     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 07/05/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                                  ; 15/02/2016
   126                                  Cluster_Buffer	 equ 70000h ; max = 64K Bytes ; buffer for file read & write
   127                                  ; 11/04/2016
   128                                  Env_Page:	 equ 93000h ; 512 bytes (4096 bytes)
   129                                  Env_Page_Size	 equ 512    ; (4096 bytes)				 	  		 	  
   130                                  
   131                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   132                                  
   133                                  [ORG 0] 
   134                                  	; 12/11/2014
   135                                  	; Save boot drive number (that is default root drive)
   136 00000000 8816[6AC9]              	mov	[boot_drv], dl ; physical drv number
   137                                  
   138                                  	; Determine installed memory
   139                                  	; 31/10/2014
   140                                  	;
   141 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   142 00000007 CD15                    	int	15h	   ; for large configurations
   143 00000009 7308                    	jnc	short chk_ms
   144 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   145 0000000D CD15                    	int	15h
   146                                  	;	   
   147                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   148                                  	;out	70h, al ; select CMOS register
   149                                  	;in	al, 71h ; read data (1 byte)
   150                                  	;mov	cl, al
   151                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   152                                  	;out	70h, al ; select CMOS register
   153                                  	;in	al, 71h ; read data (1 byte)
   154                                  	;mov	ch, al
   155                                   	;      
   156 0000000F 89C1                    	mov	cx, ax
   157 00000011 31D2                    	xor	dx, dx
   158                                  chk_ms:
   159 00000013 890E[B8CB]              	mov	[mem_1m_1k], cx
   160 00000017 8916[BACB]              	mov	[mem_16m_64k], dx
   161                                  	; 05/11/2014
   162                                  	;and	dx, dx
   163                                  	;jz	short L2
   164 0000001B 81F90004                        cmp     cx, 1024
   165 0000001F 7315                    	jnb	short L0
   166                                  		 ; insufficient memory_error	
   167                                  		 ; Minimum 2 MB memory is needed... 
   168                                  	; 05/11/2014
   169                                  	; (real mode error printing)
   170 00000021 FB                      	sti
   171 00000022 BE[83CA]                	mov	si, msg_out_of_memory
   172 00000025 BB0700                  	mov	bx, 7
   173 00000028 B40E                    	mov	ah, 0Eh	; write tty
   174                                  oom_1:
   175 0000002A AC                      	lodsb
   176 0000002B 08C0                    	or	al, al
   177 0000002D 7404                    	jz	short oom_2
   178 0000002F CD10                    	int	10h
   179 00000031 EBF7                    	jmp	short oom_1
   180                                  oom_2:
   181 00000033 F4                              hlt
   182 00000034 EBFD                    	jmp	short oom_2
   183                                  
   184                                  L0:
   185                                  %include 'diskinit.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskinit.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 04/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskinit.inc (10/07/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC
    20                              <1> ; Last Modification: 10/07/2015
    21                              <1> 
    22                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
    23                              <1> 
    24                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
    25                              <1> 
    26                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
    27                              <1> ;L0:
    28                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
    29                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
    30 00000036 BA7F00              <1> 	mov	dx, 7Fh
    31                              <1> L1:	
    32 00000039 FEC2                <1> 	inc	dl
    33 0000003B B441                <1> 	mov	ah, 41h ; Check extensions present
    34                              <1> 			; Phoenix EDD v1.1 - EDD v3
    35 0000003D BBAA55              <1> 	mov	bx, 55AAh
    36 00000040 CD13                <1> 	int 	13h
    37 00000042 721A                <1> 	jc	short L2
    38                              <1> 
    39 00000044 81FB55AA            <1> 	cmp	bx, 0AA55h
    40 00000048 7514                <1> 	jne	short L2
    41 0000004A FE06[6DC9]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    42 0000004E 8816[6CC9]          <1>         mov     [last_drv], dl  ; last hard disk number
    43 00000052 BB[F0C8]            <1> 	mov	bx, hd0_type - 80h
    44 00000055 01D3                <1> 	add	bx, dx	 
    45 00000057 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
    46                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
    47                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
    48                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
    49                              <1>                          ;            (EDD) ready (DPTE ready)
    50                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
    51                              <1>                          ;            (EDD-3)
    52                              <1> 			 ; Bit 4 to 15 - 0, Reserved
    53 00000059 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
    54 0000005C 72DB                <1> 	jb	short L1
    55                              <1> L2:
    56                              <1> 	; 23/11/2014
    57                              <1> 	; 19/11/2014
    58 0000005E 30D2                <1> 	xor	dl, dl  ; 0
    59                              <1> 	; 04/02/2016 (esi -> si)
    60 00000060 BE[6EC9]            <1> 	mov	si, fd0_type
    61                              <1> L3:
    62                              <1> 	; 14/01/2015
    63 00000063 8816[6BC9]          <1> 	mov	[drv], dl
    64                              <1> 	;
    65 00000067 B408                <1> 	mov 	ah, 08h ; Return drive parameters
    66 00000069 CD13                <1> 	int	13h	
    67 0000006B 7210                <1> 	jc	short L4
    68                              <1> 		; BL = drive type (for floppy drives)
    69                              <1> 		; DL = number of floppy drives
    70                              <1> 		;		
    71                              <1> 		; ES:DI = Address of DPT from BIOS
    72                              <1> 		;
    73 0000006D 881C                <1> 	mov	[si], bl ;  Drive type
    74                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
    75                              <1> 	; 14/01/2015
    76 0000006F E8A202              <1> 	call	set_disk_parms
    77                              <1> 	; 10/12/2014
    78 00000072 81FE[6EC9]          <1> 	cmp	si, fd0_type
    79 00000076 7705                <1> 	ja	short L4
    80 00000078 46                  <1> 	inc	si ; fd1_type
    81 00000079 B201                <1> 	mov	dl, 1
    82 0000007B EBE6                <1> 	jmp	short L3
    83                              <1> L4:
    84                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
    85 0000007D B27F                <1> 	mov	dl, 7Fh
    86                              <1> 	; 24/12/2014 (Temporary)
    87 0000007F 803E[6DC9]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
    88 00000084 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
    89                              <1> 			  ; will be performed according to
    90                              <1> 			  ; present EDD specification
    91                              <1> L6:
    92 00000088 FEC2                <1> 	inc 	dl
    93 0000008A 8816[6BC9]          <1>         mov     [drv], dl
    94 0000008E 8816[6CC9]          <1>         mov     [last_drv], dl ; 14/01/2015
    95 00000092 B408                <1> 	mov 	ah, 08h ; Return drive parameters
    96 00000094 CD13                <1> 	int	13h	; (conventional function)
    97 00000096 0F828201            <1>         jc      L13	; fixed disk drive not ready
    98 0000009A 8816[6DC9]          <1>         mov     [hdc], dl ; number of drives
    99                              <1> 	;; 14/01/2013
   100                              <1> 	;;push	cx
   101 0000009E E87302              <1> 	call	set_disk_parms
   102                              <1> 	;;pop	cx
   103                              <1> 	;
   104                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   105 000000A1 8A16[6BC9]          <1>         mov     dl, [drv]
   106 000000A5 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   107 000000A8 80FA80              <1> 	cmp	dl, 80h
   108 000000AB 7603                <1> 	jna	short L7
   109 000000AD 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   110                              <1> L7:	
   111 000000B0 31C0                <1> 	xor	ax, ax
   112 000000B2 8ED8                <1> 	mov	ds, ax
   113 000000B4 8B37                <1>         mov     si, [bx]
   114 000000B6 8B4702              <1>         mov     ax, [bx+2] 
   115 000000B9 8ED8                <1> 	mov	ds, ax
   116 000000BB 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   117 000000BE 0F855601            <1>         jne     L12 ; invalid FDPT
   118 000000C2 BF0000              <1> 	mov	di, HD0_DPT
   119 000000C5 80FA80              <1> 	cmp	dl, 80h
   120 000000C8 7603                <1> 	jna	short L8
   121 000000CA BF2000              <1> 	mov	di, HD1_DPT 
   122                              <1> L8:
   123                              <1> 	; 30/12/2014
   124 000000CD B80090              <1> 	mov	ax, DPT_SEGM
   125 000000D0 8EC0                <1> 	mov	es, ax
   126                              <1> 	; 24/12/2014
   127 000000D2 B90800              <1> 	mov	cx, 8
   128 000000D5 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   129 000000D7 8CC8                <1> 	mov	ax, cs
   130 000000D9 8ED8                <1> 	mov	ds, ax
   131                              <1> 	; 02/02/2015
   132 000000DB 8A0E[6BC9]          <1>         mov     cl, [drv]
   133 000000DF 88CB                <1> 	mov	bl, cl
   134 000000E1 B8F001              <1> 	mov	ax, 1F0h
   135 000000E4 80E301              <1> 	and	bl, 1
   136 000000E7 7406                <1> 	jz	short L9
   137 000000E9 C0E304              <1> 	shl	bl, 4
   138 000000EC 2D8000              <1> 	sub	ax, 1F0h-170h
   139                              <1> L9:
   140 000000EF AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   141 000000F0 050602              <1> 	add	ax, 206h
   142 000000F3 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   143 000000F4 88D8                <1> 	mov	al, bl
   144 000000F6 04A0                <1> 	add	al, 0A0h
   145 000000F8 AA                  <1> 	stosb	; Device/Head Register upper nibble
   146                              <1> 	;
   147 000000F9 FE06[6BC9]          <1> 	inc	byte [drv]
   148 000000FD BB[F0C8]            <1> 	mov	bx, hd0_type - 80h
   149 00000100 01CB                <1> 	add	bx, cx
   150 00000102 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   151 00000105 A0[6DC9]            <1> 	mov	al, [hdc]
   152 00000108 FEC8                <1> 	dec	al
   153 0000010A 0F840E01            <1>         jz      L13
   154 0000010E 80FA80              <1> 	cmp	dl, 80h
   155 00000111 0F8673FF            <1>         jna     L6
   156 00000115 E90401              <1>         jmp     L13
   157                              <1> L10:
   158 00000118 FEC2                <1> 	inc 	dl
   159                              <1> 	; 25/12/2014
   160 0000011A 8816[6BC9]          <1> 	mov	[drv], dl
   161 0000011E B408                <1> 	mov 	ah, 08h ; Return drive parameters
   162 00000120 CD13                <1> 	int	13h	; (conventional function)
   163 00000122 0F82F600            <1>         jc      L13
   164                              <1> 	; 14/01/2015
   165 00000126 8A16[6BC9]          <1> 	mov	dl, [drv]
   166 0000012A 52                  <1> 	push	dx
   167 0000012B 51                  <1> 	push	cx
   168 0000012C E8E501              <1> 	call	set_disk_parms
   169 0000012F 59                  <1> 	pop	cx
   170 00000130 5A                  <1> 	pop	dx
   171                              <1> 	; 04/02/2016 (esi -> si)
   172 00000131 BE[60EC]            <1> 	mov	si, _end ; 30 byte temporary buffer address 	
   173                              <1> 			 ; at the '_end' of kernel.
   174 00000134 C7041E00            <1> 	mov	word [si], 30
   175 00000138 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   176 0000013A CD13                <1> 	int	13h
   177 0000013C 0F82DC00            <1>         jc      L13
   178                              <1> 	; 04/02/2016 (ebx -> bx)
   179                              <1> 	; 14/01/2015
   180 00000140 29DB                <1> 	sub	bx, bx
   181 00000142 88D3                <1> 	mov	bl, dl
   182 00000144 80EB80              <1> 	sub	bl, 80h
   183 00000147 81C3[70C9]          <1> 	add	bx, hd0_type
   184 0000014B 8A07                <1> 	mov 	al, [bx]
   185 0000014D 0C80                <1> 	or	al, 80h
   186 0000014F 8807                <1> 	mov 	[bx], al	
   187 00000151 81EB[6EC9]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   188 00000155 81C3[BAC9]          <1> 	add	bx, drv.status
   189 00000159 8807                <1> 	mov	[bx], al
   190                              <1> 	; 04/02/2016 (eax -> ax)
   191 0000015B 8B4410              <1> 	mov	ax, [si+16]
   192 0000015E 854412              <1> 	test	ax, [si+18]
   193 00000161 7412                <1> 	jz	short L10_A0h 
   194                              <1> 			; 'CHS only' disks on EDD system 
   195                              <1> 			;  are reported with ZERO disk size
   196 00000163 81EB[BAC9]          <1> 	sub	bx, drv.status
   197 00000167 C1E302              <1> 	shl	bx, 2
   198 0000016A 81C3[9EC9]          <1> 	add	bx, drv.size ; disk size (in sectors)
   199 0000016E 8907                <1> 	mov	[bx], ax
   200 00000170 8B4412              <1> 	mov	ax, [si+18]
   201 00000173 8907                <1> 	mov	[bx], ax
   202                              <1> 
   203                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   204                              <1> 	 ; for CHS disks (28/02/2015)
   205                              <1> 	; 30/12/2014
   206 00000175 BF0000              <1> 	mov	di, HD0_DPT
   207 00000178 88D0                <1> 	mov	al, dl
   208 0000017A 83E003              <1> 	and 	ax, 3
   209 0000017D C0E005              <1> 	shl	al, 5 ; *32
   210 00000180 01C7                <1> 	add 	di, ax
   211 00000182 B80090              <1> 	mov	ax, DPT_SEGM
   212 00000185 8EC0                <1> 	mov	es, ax
   213                              <1> 	;
   214 00000187 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   215 00000189 88CC                <1> 	mov	ah, cl	
   216 0000018B C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   217 0000018E 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   218 0000018F AB                  <1> 	stosw		
   219 00000190 88F0                <1> 	mov	al, dh	; max. head number
   220 00000192 FEC0                <1> 	inc	al
   221 00000194 AA                  <1> 	stosb		; logical heads (limits 256)
   222 00000195 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   223 00000197 AA                  <1> 	stosb
   224 00000198 8A440C              <1> 	mov	al, [si+12]
   225 0000019B AA                  <1> 	stosb		 ; physical sectors per track
   226 0000019C 31C0                <1>  	xor	ax, ax
   227                              <1> 	;dec	ax	 ; 02/01/2015 
   228 0000019E AB                  <1> 	stosw		 ; precompensation (obsolete)
   229                              <1> 	;xor	al, al	 ; 02/01/2015	
   230 0000019F AA                  <1> 	stosb		 ; reserved
   231 000001A0 B008                <1> 	mov	al, 8	 ; drive control byte
   232                              <1> 		         ; (do not disable retries, 
   233                              <1> 			 ; more than 8 heads)
   234 000001A2 AA                  <1> 	stosb
   235 000001A3 8B4404              <1> 	mov	ax, [si+4]
   236 000001A6 AB                  <1> 	stosw		 ; physical number of cylinders	
   237                              <1> 	;push	ax	 ; 02/01/2015
   238 000001A7 8A4408              <1> 	mov	al, [si+8]
   239 000001AA AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   240 000001AB 29C0                <1> 	sub 	ax, ax
   241                              <1> 	;pop	ax	 ; 02/01/2015	
   242 000001AD AB                  <1> 	stosw		 ; landing zone (obsolete)
   243 000001AE 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   244 000001B0 243F                <1> 	and 	al, 3Fh	
   245 000001B2 AA                  <1> 	stosb
   246                              <1> 	;sub	al, al	 ; checksum
   247                              <1> 	;stosb
   248                              <1> 	;
   249 000001B3 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   250 000001B6 AD                  <1> 	lodsw
   251 000001B7 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   252 000001B8 AD                  <1> 	lodsw
   253 000001B9 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   254                              <1> 	;
   255                              <1> 	; checksum calculation
   256 000001BA 89FE                <1> 	mov	si, di
   257 000001BC 06                  <1> 	push	es
   258 000001BD 1F                  <1> 	pop	ds
   259                              <1> 	;mov	cx, 16
   260 000001BE B90F00              <1> 	mov 	cx, 15
   261 000001C1 29CE                <1> 	sub	si, cx
   262 000001C3 30E4                <1> 	xor	ah, ah
   263                              <1> 	;del	cl
   264                              <1> L11:		
   265 000001C5 AC                  <1> 	lodsb
   266 000001C6 00C4                <1> 	add	ah, al
   267 000001C8 E2FB                <1> 	loop	L11
   268                              <1> 	;
   269 000001CA 88E0                <1> 	mov	al, ah
   270 000001CC F6D8                <1> 	neg	al	; -x+x = 0
   271 000001CE AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   272                              <1> 	;
   273 000001CF 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   274 000001D0 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   275                              <1> 	;
   276                              <1> 	; 23/02/2015
   277 000001D1 57                  <1> 	push	di
   278                              <1> 	; ES:DI points to DPTE (FDPTE) location
   279                              <1> 	;mov	cx, 8
   280 000001D2 B108                <1> 	mov	cl, 8
   281 000001D4 F3A5                <1> 	rep	movsw	
   282                              <1> 	;
   283                              <1> 	; 23/02/2015
   284                              <1> 	; (P)ATA drive and LBA validation
   285                              <1> 	; (invalidating SATA drives and setting
   286                              <1> 	; CHS type I/O for old type fixed disks)
   287 000001D6 5B                  <1> 	pop	bx
   288 000001D7 8CC8                <1> 	mov	ax, cs
   289 000001D9 8ED8                <1> 	mov	ds, ax
   290 000001DB 268B07              <1> 	mov	ax, [es:bx]
   291 000001DE 3DF001              <1> 	cmp	ax, 1F0h
   292 000001E1 7418                <1> 	je	short L11a
   293 000001E3 3D7001              <1> 	cmp	ax, 170h
   294 000001E6 7413                <1> 	je	short L11a
   295                              <1> 	; invalidation 
   296                              <1> 	; (because base port address is not 1F0h or 170h)
   297 000001E8 30FF                <1> 	xor	bh, bh
   298 000001EA 88D3                <1> 	mov	bl, dl
   299 000001EC 80EB80              <1> 	sub	bl, 80h
   300 000001EF C687[70C9]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   301 000001F4 808F[BCC9]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   302 000001F9 EB14                <1> 	jmp	short L11b
   303                              <1> L11a:	
   304                              <1> 	; LBA validation
   305 000001FB 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   306 000001FF A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   307 00000201 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   308                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   309 00000203 28FF                <1> 	sub	bh, bh
   310 00000205 88D3                <1> 	mov	bl, dl
   311 00000207 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   312 0000020A 80A7[BCC9]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   313                              <1> 				; bit 0 = LBA ready bit
   314                              <1> 	; 'diskio' procedure will check this bit !
   315                              <1> L11b:
   316 0000020F 3A16[6CC9]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   317 00000213 7307                <1>         jnb     short L13
   318 00000215 E900FF              <1>         jmp     L10
   319                              <1> L12:
   320                              <1> 	; Restore data registers
   321 00000218 8CC8                <1> 	mov	ax, cs
   322 0000021A 8ED8                <1> 	mov	ds, ax	
   323                              <1> L13:
   324                              <1> 	; 13/12/2014
   325 0000021C 0E                  <1> 	push	cs
   326 0000021D 07                  <1> 	pop	es
   327                              <1> L14:
   328 0000021E B411                <1> 	mov 	ah, 11h
   329 00000220 CD16                <1> 	int 	16h
   330 00000222 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   331 00000224 B010                <1> 	mov	al, 10h
   332 00000226 CD16                <1> 	int 	16h
   333 00000228 EBF4                <1> 	jmp 	short L14
   334                              <1> L15:
   335                              <1> ; //////
   336                              <1> 	; 24/11/2014
   337                              <1> 	; 19/11/2014
   338                              <1> 	; 14/11/2014
   339                              <1> 	; Temporary code for disk searching code check
   340                              <1> 	;
   341                              <1> 	; This code will show existing (usable) drives and also
   342                              <1> 	; will show EDD interface support status for hard disks		
   343                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   344                              <1> 	; no need to get it again in protected mode...) 
   345                              <1> 	;	
   346                              <1> 	; 13/11/2014
   347 0000022A BB0700              <1> 	mov	bx, 7
   348 0000022D B40E                <1> 	mov	ah, 0Eh
   349 0000022F A0[6EC9]            <1> 	mov	al, [fd0_type]
   350 00000232 20C0                <1> 	and	al, al
   351 00000234 743D                <1> 	jz	short L15a
   352 00000236 88C2                <1> 	mov	dl, al
   353 00000238 B046                <1> 	mov	al, 'F'
   354 0000023A CD10                <1> 	int 	10h
   355 0000023C B044                <1> 	mov	al, 'D'
   356 0000023E CD10                <1> 	int 	10h
   357 00000240 B030                <1> 	mov	al, '0'
   358 00000242 CD10                <1> 	int 	10h
   359 00000244 B020                <1> 	mov	al, ' '
   360 00000246 CD10                <1> 	int	10h
   361 00000248 E8B200              <1> 	call	L15c
   362 0000024B B020                <1> 	mov	al, ' '
   363 0000024D CD10                <1> 	int	10h
   364                              <1> 	;
   365 0000024F A0[6FC9]            <1> 	mov	al, [fd1_type]
   366 00000252 20C0                <1> 	and	al, al
   367 00000254 741D                <1> 	jz	short L15a
   368 00000256 88C2                <1> 	mov	dl, al
   369 00000258 B046                <1> 	mov	al, 'F'
   370 0000025A CD10                <1> 	int 	10h
   371 0000025C B044                <1> 	mov	al, 'D'
   372 0000025E CD10                <1> 	int 	10h
   373 00000260 B031                <1> 	mov	al, '1'
   374 00000262 CD10                <1> 	int 	10h
   375 00000264 B020                <1> 	mov	al, ' '
   376 00000266 CD10                <1> 	int	10h
   377 00000268 E89200              <1> 	call	L15c
   378 0000026B B020                <1> 	mov	al, ' '
   379 0000026D CD10                <1> 	int	10h
   380 0000026F B020                <1> 	mov	al, ' '
   381 00000271 CD10                <1> 	int	10h
   382                              <1> L15a:
   383 00000273 A0[70C9]            <1> 	mov	al, [hd0_type]
   384 00000276 20C0                <1> 	and	al, al
   385 00000278 7479                <1> 	jz	short L15b
   386 0000027A 88C2                <1> 	mov	dl, al
   387 0000027C B048                <1> 	mov	al, 'H'
   388 0000027E CD10                <1> 	int 	10h
   389 00000280 B044                <1> 	mov	al, 'D'
   390 00000282 CD10                <1> 	int 	10h
   391 00000284 B030                <1> 	mov	al, '0'
   392 00000286 CD10                <1> 	int 	10h
   393 00000288 B020                <1> 	mov	al, ' '
   394 0000028A CD10                <1> 	int 	10h
   395 0000028C E86E00              <1> 	call	L15c
   396 0000028F B020                <1> 	mov	al, ' '
   397 00000291 CD10                <1> 	int	10h
   398                              <1> 	;
   399 00000293 A0[71C9]            <1> 	mov	al, [hd1_type]
   400 00000296 20C0                <1> 	and	al, al
   401 00000298 7459                <1> 	jz	short L15b
   402 0000029A 88C2                <1> 	mov	dl, al
   403 0000029C B048                <1> 	mov	al, 'H'
   404 0000029E CD10                <1> 	int 	10h
   405 000002A0 B044                <1> 	mov	al, 'D'
   406 000002A2 CD10                <1> 	int 	10h
   407 000002A4 B031                <1> 	mov	al, '1'
   408 000002A6 CD10                <1> 	int 	10h
   409 000002A8 B020                <1> 	mov	al, ' '
   410 000002AA CD10                <1> 	int 	10h
   411 000002AC E84E00              <1> 	call	L15c
   412 000002AF B020                <1> 	mov	al, ' '
   413 000002B1 CD10                <1> 	int	10h
   414                              <1> 	;
   415 000002B3 A0[72C9]            <1> 	mov	al, [hd2_type]
   416 000002B6 20C0                <1> 	and	al, al
   417 000002B8 7439                <1> 	jz	short L15b
   418 000002BA 88C2                <1> 	mov	dl, al
   419 000002BC B048                <1> 	mov	al, 'H'
   420 000002BE CD10                <1> 	int 	10h
   421 000002C0 B044                <1> 	mov	al, 'D'
   422 000002C2 CD10                <1> 	int 	10h
   423 000002C4 B032                <1> 	mov	al, '2'
   424 000002C6 CD10                <1> 	int 	10h
   425 000002C8 B020                <1> 	mov	al, ' '
   426 000002CA CD10                <1> 	int 	10h
   427 000002CC E82E00              <1> 	call	L15c
   428 000002CF B020                <1> 	mov	al, ' '
   429 000002D1 CD10                <1> 	int	10h
   430                              <1> 	;
   431 000002D3 A0[73C9]            <1> 	mov	al, [hd3_type]
   432 000002D6 20C0                <1> 	and	al, al
   433 000002D8 7419                <1> 	jz	short L15b
   434 000002DA 88C2                <1> 	mov	dl, al
   435 000002DC B048                <1> 	mov	al, 'H'
   436 000002DE CD10                <1> 	int 	10h
   437 000002E0 B044                <1> 	mov	al, 'D'
   438 000002E2 CD10                <1> 	int 	10h
   439 000002E4 B033                <1> 	mov	al, '3'
   440 000002E6 CD10                <1> 	int 	10h
   441 000002E8 B020                <1> 	mov	al, ' '
   442 000002EA CD10                <1> 	int 	10h
   443 000002EC E80E00              <1> 	call	L15c
   444 000002EF B020                <1> 	mov	al, ' '
   445 000002F1 CD10                <1> 	int	10h
   446                              <1> 	;
   447                              <1> L15b:
   448 000002F3 B00D                <1> 	mov	al, 0Dh
   449 000002F5 CD10                <1> 	int 	10h	
   450 000002F7 B00A                <1> 	mov	al, 0Ah
   451 000002F9 CD10                <1> 	int 	10h
   452                              <1> 	;;xor	ah, ah
   453                              <1> 	;;int 	16h	
   454                              <1> 	;
   455 000002FB EB77                <1>         jmp     L16  ; jmp short L16
   456                              <1>         ;
   457                              <1> L15c:
   458 000002FD 88D6                <1> 	mov	dh, dl
   459 000002FF C0EE04              <1> 	shr	dh, 4
   460 00000302 80C630              <1> 	add	dh, 30h
   461 00000305 80E20F              <1> 	and	dl, 15
   462 00000308 80C230              <1> 	add	dl, 30h
   463 0000030B 88F0                <1> 	mov	al, dh
   464 0000030D CD10                <1> 	int	10h
   465 0000030F 88D0                <1> 	mov	al, dl
   466 00000311 CD10                <1> 	int	10h
   467 00000313 C3                  <1> 	retn
   468                              <1> 	;
   469                              <1> 	; end of temporary code for disk searching code check
   470                              <1> 
   471                              <1> ; //////
   472                              <1> 
   473                              <1> set_disk_parms:
   474                              <1> 	; 04/02/2016 (ebx -> bx)
   475                              <1> 	; 10/07/2015
   476                              <1> 	; 14/01/2015
   477                              <1> 	;push	bx
   478 00000314 28FF                <1> 	sub	bh, bh
   479 00000316 8A1E[6BC9]          <1> 	mov	bl, [drv]
   480 0000031A 80FB80              <1> 	cmp	bl, 80h
   481 0000031D 7203                <1> 	jb	short sdp0
   482 0000031F 80EB7E              <1> 	sub	bl, 7Eh
   483                              <1> sdp0:	
   484 00000322 81C3[BAC9]          <1> 	add	bx, drv.status
   485 00000326 C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   486                              <1> 	;
   487 00000329 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   488 0000032B 88CC                <1> 	mov	ah, cl ; 
   489 0000032D C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   490 00000330 81EB[BAC9]          <1> 	sub	bx, drv.status
   491 00000334 D0E3                <1> 	shl	bl, 1
   492 00000336 81C3[74C9]          <1> 	add	bx, drv.cylinders
   493 0000033A 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   494 0000033B 8907                <1> 	mov	[bx], ax
   495 0000033D 50                  <1> 	push	ax ; ** cylinders
   496 0000033E 81EB[74C9]          <1> 	sub	bx, drv.cylinders
   497 00000342 81C3[82C9]          <1> 	add	bx, drv.heads
   498 00000346 30E4                <1> 	xor	ah, ah
   499 00000348 88F0                <1> 	mov	al, dh ; heads
   500 0000034A 40                  <1> 	inc	ax
   501 0000034B 8907                <1> 	mov	[bx], ax
   502 0000034D 81EB[82C9]          <1>         sub     bx, drv.heads
   503 00000351 81C3[90C9]          <1>         add     bx, drv.spt
   504 00000355 30ED                <1> 	xor	ch, ch
   505 00000357 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   506 0000035A 890F                <1> 	mov	[bx], cx
   507 0000035C 81EB[90C9]          <1>         sub     bx, drv.spt
   508 00000360 D1E3                <1> 	shl	bx, 1
   509 00000362 81C3[9EC9]          <1> 	add	bx, drv.size ; disk size (in sectors)
   510                              <1> 	; LBA size = cylinders * heads * secpertrack
   511 00000366 F7E1                <1> 	mul	cx 
   512 00000368 89C2                <1> 	mov	dx, ax	; heads*spt					
   513 0000036A 58                  <1> 	pop	ax ; ** cylinders
   514 0000036B 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   515 0000036C F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   516 0000036E 8907                <1> 	mov	[bx], ax
   517 00000370 895702              <1> 	mov	[bx+2], dx
   518                              <1> 	;
   519                              <1> 	;pop	bx
   520 00000373 C3                  <1> 	retn
   521                              <1> 
   522                              <1> ;align 2
   523                              <1> 
   524                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   525                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   526                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   527                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   528                              <1> 
   529                              <1> ;last_drv:
   530                              <1> ;	db  0
   531                              <1> ;drv_status:
   532                              <1> ;	db  0,0,0,0,0,0
   533                              <1> ;	db 0
   534                              <1> 
   535                              <1> 
   536                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   537                              <1> 
   538                              <1> L16:
   186                                  
   187                                  	; 10/11/2014
   188 00000374 FA                           	cli	; Disable interrupts (clear interrupt flag)
   189                                  		; Reset Interrupt MASK Registers (Master&Slave)
   190                                  	;mov	al, 0FFh	; mask off all interrupts
   191                                  	;out	21h, al		; on master PIC (8259)
   192                                  	;jmp 	$+2  ; (delay)
   193                                  	;out	0A1h, al	; on slave PIC (8259)
   194                                  	;
   195                                  	; Disable NMI 
   196 00000375 B080                    	mov   	al, 80h 
   197 00000377 E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   198                                  	;23/02/2015
   199 00000379 90                      	nop			;
   200                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   201                                  				; for preventing unknown state (!?)
   202                                  	;
   203                                   	; 20/08/2014
   204                                  	; Moving the kernel 64 KB back (to physical address 0)
   205                                  	; DS = CS = 1000h
   206                                  	; 05/11/2014
   207 0000037A 31C0                    	xor	ax, ax
   208 0000037C 8EC0                    	mov	es, ax ; ES = 0
   209                                  	;
   210 0000037E B90040                  	mov	cx, (KEND - KLOAD)/4
   211 00000381 31F6                    	xor	si, si
   212 00000383 31FF                    	xor	di, di
   213 00000385 F366A5                  	rep	movsd
   214                                  	;
   215 00000388 06                      	push	es ; 0
   216 00000389 68[8D03]                	push	L17
   217 0000038C CB                      	retf
   218                                  	;
   219                                  L17:
   220                                  	; Turn off the floppy drive motor
   221 0000038D BAF203                          mov     dx, 3F2h
   222 00000390 EE                              out     dx, al ; 0 ; 31/12/2013
   223                                  
   224                                  	; Enable access to memory above one megabyte
   225                                  L18:
   226 00000391 E464                    	in	al, 64h
   227 00000393 A802                    	test	al, 2
   228 00000395 75FA                            jnz     short L18
   229 00000397 B0D1                    	mov	al, 0D1h	; Write output port
   230 00000399 E664                    	out	64h, al
   231                                  L19:
   232 0000039B E464                    	in	al, 64h
   233 0000039D A802                    	test	al, 2
   234 0000039F 75FA                            jnz     short L19
   235 000003A1 B0DF                    	mov	al, 0DFh	; Enable A20 line
   236 000003A3 E660                    	out	60h, al
   237                                  ;L20:
   238                                  	;
   239                                  	; Load global descriptor table register
   240                                  
   241                                          ;mov     ax, cs
   242                                          ;mov     ds, ax
   243                                  
   244 000003A5 2E0F0116[40C6]                  lgdt    [cs:gdtd]
   245                                  
   246 000003AB 0F20C0                          mov     eax, cr0
   247                                  	; or 	eax, 1
   248 000003AE 40                      	inc     ax
   249 000003AF 0F22C0                  	mov     cr0, eax
   250                                  
   251                                  	; Jump to 32 bit code
   252                                  	
   253 000003B2 66                      	db 66h 			; Prefix for 32-bit
   254 000003B3 EA                      	db 0EAh 		; Opcode for far jump
   255 000003B4 [BA030000]              	dd StartPM 		; Offset to start, 32-bit
   256                                  				; (1000h:StartPM = StartPM + 10000h)
   257 000003B8 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   258                                  				; assuming that StartPM resides in code32
   259                                  
   260                                  [BITS 32] 
   261                                  
   262                                  StartPM:
   263                                  	; Kernel Base Address = 0 ; 30/12/2013
   264 000003BA 66B81000                	mov ax, KDATA           ; Save data segment identifier
   265 000003BE 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   266 000003C0 8EC0                           	mov es, ax              ; Move data segment into ES register
   267 000003C2 8EE0                           	mov fs, ax              ; Move data segment into FS register
   268 000003C4 8EE8                          	mov gs, ax              ; Move data segment into GS register
   269 000003C6 8ED0                            mov ss, ax              ; Move data segment into SS register
   270 000003C8 BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   271                                  
   272                                  clear_bss: ; Clear uninitialized data area
   273                                  	; 11/03/2015
   274 000003CD 31C0                    	xor  eax, eax ; 0
   275 000003CF B91C080000              	mov  ecx, (bss_end - bss_start)/4
   276                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   277 000003D4 BF[F0CB0000]            	mov  edi, bss_start	
   278 000003D9 F3AB                    	rep  stosd  		
   279                                  
   280                                  memory_init:
   281                                  	; Initialize memory allocation table and page tables
   282                                  	; 16/11/2014
   283                                  	; 15/11/2014
   284                                  	; 07/11/2014
   285                                  	; 06/11/2014
   286                                  	; 05/11/2014
   287                                  	; 04/11/2014
   288                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   289                                  	;
   290                                  ;	xor	eax, eax
   291                                  ;	xor 	ecx, ecx
   292 000003DB B108                    	mov	cl, 8
   293 000003DD BF00001000              	mov	edi, MEM_ALLOC_TBL	
   294 000003E2 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   295                                  				   ; for the first 1 MB memory
   296                                  	;
   297 000003E4 668B0D[B8CB0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   298                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   299 000003EB 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   300 000003EF 890D[E0CE0000]          	mov	[free_pages], ecx
   301 000003F5 668B15[BACB0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   302                                  				   ; between 16 MB and 4 GB.	
   303 000003FC 6609D2                  	or	dx, dx
   304 000003FF 7413                    	jz	short mi_0
   305                                  	;
   306 00000401 6689D0                  	mov	ax, dx
   307 00000404 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   308 00000407 0105[E0CE0000]          	add	[free_pages], eax
   309 0000040D 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   310 00000412 EB07                    	jmp	short mi_1
   311                                  mi_0:
   312 00000414 6689C8                  	mov	ax, cx
   313 00000417 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   314                                  mi_1:
   315 0000041B A3[DCCE0000]            	mov	[memory_size], eax ; Total available memory in pages
   316                                  				   ; 1 alloc. tbl. bit = 1 memory page
   317                                  				   ; 32 allocation bits = 32 mem. pages   
   318                                  	;
   319 00000420 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   320 00000425 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   321                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   322                                  				   ;  --> x M.A.T. pages, if y = 0
   323 00000428 66A3[F0CE0000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   324 0000042E C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   325                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   326 00000431 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   327                                  	; Set/Calculate Kernel's Page Directory Address
   328 00000433 81C300001000            	add	ebx, MEM_ALLOC_TBL
   329 00000439 891D[D8CE0000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   330                                  				   ; just after the last M.A.T. page
   331                                  	;
   332 0000043F 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   333 00000442 A3[E8CE0000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   334                                  	;			   ; (allocation status search must be 
   335                                  				   ; stopped after here)	
   336 00000447 31C0                    	xor	eax, eax
   337 00000449 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   338 0000044A 6651                    	push	cx
   339 0000044C C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   340                                  				   ; count of 32 allocation bits
   341 0000044F F3AB                    	rep	stosd
   342 00000451 6659                    	pop	cx
   343 00000453 40                      	inc	eax		   ; 0	
   344 00000454 80E11F                  	and	cl, 31		   ; remain bits
   345 00000457 7412                    	jz	short mi_4
   346 00000459 8907                    	mov	[edi], eax	   ; reset	
   347                                  mi_2:
   348 0000045B 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   349 0000045E FEC9                    	dec	cl
   350 00000460 7404                    	jz	short mi_3
   351 00000462 FEC0                    	inc	al
   352 00000464 EBF5                    	jmp	short mi_2
   353                                  mi_3:
   354 00000466 28C0                    	sub	al, al	   	   ; 0
   355 00000468 83C704                  	add	edi, 4		   ; 15/11/2014
   356                                  mi_4:
   357 0000046B 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   358 0000046E 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   359                                  	;	
   360 00000470 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   361                                  	;	
   362 00000475 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   363 00000477 7406                    	jz	short mi_5	  ; jump if EDI points to 
   364                                  				  ;         end of first 16 MB	
   365 00000479 D1E9                    	shr	ecx, 1		  ; convert to dword count
   366 0000047B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   367 0000047D F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   368                                  				  ; (memory hole under 16 MB)
   369                                  mi_5:
   370 0000047F 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   371 00000482 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   372 00000484 9C                      	pushf			  ; 16/11/2014		
   373 00000485 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   374 00000486 F3AB                    	rep	stosd
   375 00000488 40                      	inc	eax		  ; 0
   376 00000489 9D                      	popf			  ; 16/11/2014
   377 0000048A 7305                    	jnc	short mi_6
   378 0000048C 6648                    	dec	ax		  ; eax = 0000FFFFh
   379 0000048E AB                      	stosd
   380 0000048F 6640                    	inc	ax		  ; 0		
   381                                  mi_6:
   382 00000491 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   383 00000493 730A                    	jnb	short mi_7	  ; end of memory allocation table
   384                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   385 00000495 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   386 00000497 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   387 00000499 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   388 0000049B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   389 0000049D F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   390                                  mi_7:
   391                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   392 0000049F BA00001000              	mov	edx, MEM_ALLOC_TBL
   393                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   394                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   395 000004A4 668B0D[F0CE0000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   396 000004AB 89D7                    	mov	edi, edx
   397 000004AD C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   398                                  				  ; byte offset in M.A.T.
   399                                  				  ; (1 M.A.T. byte points to 
   400                                  				  ;	      32768 bytes)
   401                                  				  ; Note: MEM_ALLOC_TBL address 
   402                                  				  ; must be aligned on 128 KB 
   403                                  				  ; boundary!
   404 000004B0 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   405                                  	; eax = 0
   406 000004B2 290D[E0CE0000]          	sub	[free_pages], ecx ; 07/11/2014
   407                                  mi_8:
   408 000004B8 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   409                                  	;dec	bl
   410 000004BB FEC9                    	dec	cl
   411 000004BD 7404                    	jz	short mi_9
   412 000004BF FEC0                    	inc	al
   413 000004C1 EBF5                    	jmp	short mi_8
   414                                  mi_9:
   415                                  	;
   416                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   417                                  	;		(allocate pages for system page tables)
   418                                  
   419                                  	; edx = MEM_ALLOC_TBL
   420 000004C3 8B0D[DCCE0000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   421 000004C9 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   422 000004CF C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   423                                  				 ; page table count (PDE count)
   424                                  	;
   425 000004D2 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   426                                  	;
   427 000004D3 41                      	inc	ecx		 ; +1 for kernel page directory	
   428                                  	;
   429 000004D4 290D[E0CE0000]          	sub	[free_pages], ecx ; 07/11/2014
   430                                  	;
   431 000004DA 8B35[D8CE0000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   432 000004E0 C1EE0C                  	shr	esi, 12		 ; convert to page number
   433                                  mi_10:
   434 000004E3 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   435 000004E5 89C3                    	mov	ebx, eax
   436 000004E7 C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   437 000004EA 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   438                                  				 ;   to align on dword boundary
   439 000004ED 83E01F                  	and	eax, 31		 ; set allocation bit position 
   440                                  				 ;  (bit 0 to bit 31)
   441                                  	;
   442 000004F0 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   443                                  	;
   444 000004F2 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   445                                  	;
   446 000004F5 46                      	inc	esi		 ; next page table
   447 000004F6 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   448                                  				 ; (ecx = page table count + 1)		
   449                                  	;
   450 000004F8 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   451                                  	;
   452                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   453                                  	;
   454                                  	; Initialize Kernel's Page Directory
   455 000004F9 8B3D[D8CE0000]          	mov	edi, [k_page_dir]
   456 000004FF 89F8                    	mov	eax, edi
   457 00000501 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   458                                  		     	      ; supervisor + read&write + present
   459 00000503 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   460                                  mi_11:
   461 00000505 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   462                                  			        ; EAX points to next page table
   463 0000050A AB                      	stosd
   464 0000050B E2F8                    	loop	mi_11
   465 0000050D 29C0                    	sub	eax, eax	; Empty PDE
   466 0000050F 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   467 00000513 29D1                    	sub	ecx, edx
   468 00000515 7402                    	jz	short mi_12
   469 00000517 F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   470                                  	;
   471                                  	; Initialization of Kernel's Page Directory is OK, here.
   472                                  mi_12:
   473                                  	; Initialize Kernel's Page Tables
   474                                  	;
   475                                  	; (EDI points to address of page table 0)
   476                                  	; eax = 0
   477 00000519 8B0D[DCCE0000]          	mov	ecx, [memory_size] ; memory size in pages
   478 0000051F 89CA                    	mov	edx, ecx	; (***)
   479 00000521 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
   480                                  			     ; supervisor + read&write + present 	
   481                                  mi_13:
   482 00000523 AB                      	stosd
   483 00000524 0500100000              	add	eax, 4096	
   484 00000529 E2F8                    	loop	mi_13	
   485 0000052B 6681E2FF03              	and	dx, 1023	; (***)
   486 00000530 740B                    	jz	short mi_14
   487 00000532 66B90004                	mov	cx, 1024	
   488 00000536 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
   489 00000539 31C0                    	xor	eax, eax
   490 0000053B F3AB                    	rep	stosd		; clear remain (empty) PTEs 
   491                                  				; of the last page table
   492                                  mi_14:
   493                                  	;  Initialization of Kernel's Page Tables is OK, here.
   494                                  	;
   495 0000053D 89F8                    	mov	eax, edi	; end of the last page table page
   496                                  			        ; (beginging of user space pages)
   497 0000053F C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
   498 00000542 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
   499                                  				; aligning on dword boundary	
   500                                  	 
   501 00000544 A3[ECCE0000]            	mov	[first_page], eax
   502 00000549 A3[E4CE0000]            	mov	[next_page], eax ; The first free page pointer
   503                                  				 ; for user programs
   504                                  				 ; (Offset in Mem. Alloc. Tbl.)	
   505                                  	;
   506                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
   507                                  	;
   508                                  	
   509                                  	; Enable paging
   510                                  	;
   511 0000054E A1[D8CE0000]                    mov     eax, [k_page_dir]
   512 00000553 0F22D8                  	mov	cr3, eax
   513 00000556 0F20C0                  	mov	eax, cr0
   514 00000559 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
   515 0000055E 0F22C0                  	mov	cr0, eax
   516                                          ;jmp    KCODE:StartPMP
   517                                  
   518 00000561 EA                      	db 0EAh 		; Opcode for far jump
   519 00000562 [68050000]                      dd StartPMP		; 32 bit offset
   520 00000566 0800                    	dw KCODE		; kernel code segment descriptor
   521                                  
   522                                  
   523                                  StartPMP:
   524                                  	; 06/11//2014
   525                                  	; Clear video page 0
   526                                  	;
   527                                  	; Temporary Code
   528                                  	;
   529 00000568 B9E8030000              	mov	ecx, 80*25/2
   530 0000056D BF00800B00              	mov	edi, 0B8000h
   531                                  	; 30/01/2016
   532                                  	;xor	eax, eax	; black background, black fore color
   533 00000572 B800070007              	mov	eax, 07000700h  ; black background, light gray fore color
   534 00000577 F3AB                    	rep	stosd
   535                                  	
   536                                  	; 19/08/2014
   537                                  	; Kernel Base Address = 0
   538                                  	; It is mapped to (physically) 0 in the page table.
   539                                  	; So, here is exactly 'StartPMP' address.
   540                                  
   541                                   	; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
   542 00000579 BE[BCCB0000]            	mov	esi, starting_msg
   543                                  	;; 14/08/2015 (kernel version message will appear
   544                                  	;;	       when protected mode and paging is enabled)
   545 0000057E BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
   546 00000583 B40A                    	mov	ah, 0Ah ; Black background, light green forecolor
   547                                  	; 20/08/2014
   548 00000585 E87D010000              	call	printk
   549                                  
   550                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
   551                                  	; // Set IRQ offsets
   552                                  	;
   553                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
   554                                  	;
   555                                  					;; ICW1
   556 0000058A B011                    	mov	al, 11h			; Initialization sequence
   557 0000058C E620                    	out	20h, al			; 	8259A-1
   558                                  	; jmp 	$+2
   559 0000058E E6A0                    	out	0A0h, al		; 	8259A-2
   560                                  					;; ICW2
   561 00000590 B020                    	mov	al, 20h			; Start of hardware ints (20h)
   562 00000592 E621                    	out	21h, al			;	for 8259A-1
   563                                  	; jmp 	$+2
   564 00000594 B028                    	mov	al, 28h			; Start of hardware ints (28h)
   565 00000596 E6A1                    	out	0A1h, al		; 	for 8259A-2
   566                                  					;
   567 00000598 B004                    	mov	al, 04h			;; ICW3
   568 0000059A E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
   569                                  	; jmp 	$+2
   570 0000059C B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
   571 0000059E E6A1                    	out	0A1h, al		;
   572                                  					;; ICW4
   573 000005A0 B001                    	mov	al, 01h	 		;
   574 000005A2 E621                    	out	21h, al			; 	8086 mode, normal EOI	
   575                                  	; jmp 	$+2
   576 000005A4 E6A1                    	out	0A1h, al		;	for both chips.
   577                                  
   578                                  	;mov	al, 0FFh	; mask off all interrupts for now
   579                                  	;out	21h, al
   580                                  	;; jmp 	$+2
   581                                  	;out	0A1h, al
   582                                  
   583                                  	; 02/04/2015
   584                                  	; 26/03/2015 System call (INT 30h) modification
   585                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
   586                                  	;
   587                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
   588                                  	;  setup_idt:
   589                                  	;
   590                                          ;; 16/02/2015
   591                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   592                                  	; 21/08/2014 (timer_int)
   593 000005A6 BE[4CC60000]            	mov	esi, ilist
   594 000005AB 8D3D[F0CB0000]          	lea	edi, [idt]
   595                                  	; 26/03/2015
   596 000005B1 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
   597                                  	; 02/04/2015
   598 000005B6 BB00000800              	mov	ebx,  80000h
   599                                  rp_sidt1:
   600 000005BB AD                      	lodsd
   601 000005BC 89C2                    	mov	edx, eax
   602 000005BE 66BA008E                	mov	dx, 8E00h
   603 000005C2 6689C3                  	mov	bx, ax
   604 000005C5 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
   605                                         			        ; /* interrupt gate - dpl=0, present */
   606 000005C7 AB                      	stosd	; selector & offset bits 0-15 	
   607 000005C8 89D0                    	mov	eax, edx
   608 000005CA AB                      	stosd	; attributes & offset bits 16-23
   609 000005CB E2EE                    	loop	rp_sidt1
   610                                  	; 15/04/2016
   611                                  	; TRDOS 386 (TRDOS v2.0) /// 32 sofware interrupts ///
   612                                  	;mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
   613 000005CD B120                    	mov	cl, 32	      ;  16 software interrupts (INT 30h to INT 4Fh)	
   614                                  rp_sidt2:
   615 000005CF AD                      	lodsd
   616 000005D0 21C0                    	and	eax, eax
   617 000005D2 7413                    	jz	short rp_sidt3
   618 000005D4 89C2                    	mov	edx, eax
   619 000005D6 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   620 000005DA 6689C3                  	mov	bx, ax
   621 000005DD 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   622 000005DF AB                      	stosd
   623 000005E0 89D0                    	mov	eax, edx
   624 000005E2 AB                      	stosd
   625 000005E3 E2EA                    	loop	rp_sidt2
   626 000005E5 EB16                    	jmp	short sidt_OK
   627                                  rp_sidt3:
   628 000005E7 B8[310A0000]            	mov	eax, ignore_int
   629 000005EC 89C2                    	mov	edx, eax
   630 000005EE 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   631 000005F2 6689C3                  	mov	bx, ax
   632 000005F5 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   633                                  rp_sidt4:
   634 000005F7 AB                      	stosd
   635 000005F8 92                      	xchg	eax, edx
   636 000005F9 AB                      	stosd
   637 000005FA 92                      	xchg	edx, eax
   638 000005FB E2FA                    	loop	rp_sidt4
   639                                  sidt_OK: 
   640 000005FD 0F011D[46C60000]        	lidt 	[idtd]
   641                                  	;
   642                                  	; TSS descriptor setup ; 24/03/2015
   643 00000604 B8[70CE0000]            	mov	eax, task_state_segment
   644 00000609 66A3[3AC60000]          	mov	[gdt_tss0], ax
   645 0000060F C1C010                  	rol	eax, 16
   646 00000612 A2[3CC60000]            	mov	[gdt_tss1], al
   647 00000617 8825[3FC60000]          	mov	[gdt_tss2], ah
   648 0000061D 66C705[D6CE0000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
   648 00000625 00                 
   649                                  		; 
   650                                  		; IO Map Base address (When this address points
   651                                  		; to end of the TSS, CPU does not use IO port 
   652                                  		; permission bit map for RING 3 IO permissions, 
   653                                  		; access to any IO ports in ring 3 will be forbidden.)
   654                                   		;
   655                                  	;mov	[tss.esp0], esp ; TSS offset 4
   656                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
   657 00000626 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
   658                                  			 ; occurs (or a system call -software INT- is requested)
   659                                  			 ; while cpu running in ring 3 (in user mode).				
   660                                  			 ; (Kernel stack pointer and segment will be loaded
   661                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
   662 0000062A 0F00D8                  	ltr	ax  ; Load task register
   663                                  	;
   664                                  esp0_set0:
   665                                  	; 30/07/2015
   666 0000062D 8B0D[DCCE0000]          	mov 	ecx, [memory_size] ; memory size in pages
   667 00000633 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
   668 00000636 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
   669                                  			  ; (kernel mode virtual address)
   670 0000063C 7605                    	jna	short esp0_set1
   671                                  	;
   672                                  	; If available memory > CORE (end of the 1st 4 MB)
   673                                  	; set stack pointer to CORE
   674                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
   675                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
   676 0000063E B900004000              	mov	ecx, CORE
   677                                  esp0_set1:
   678 00000643 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
   679                                  esp0_set_ok:
   680                                  	; 30/07/2015 (**tss.esp0**) 
   681 00000645 8925[74CE0000]          	mov	[tss.esp0], esp
   682 0000064B 66C705[78CE0000]10-             mov     word [tss.ss0], KDATA
   682 00000653 00                 
   683                                  	; 14/08/2015
   684                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
   685                                  	;
   686                                  	;cli	; Disable interrupts (for CPU)
   687                                  	;    (CPU will not handle hardware interrupts, except NMI!)
   688                                  	;
   689 00000654 30C0                    	xor	al, al		; Enable all hardware interrupts!
   690 00000656 E621                    	out	21h, al		; (IBM PC-AT compatibility)
   691 00000658 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
   692 0000065A E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
   693                                  				; (Even if related hardware component
   694                                  				;  does not exist!)
   695                                  	; Enable NMI 
   696 0000065C B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
   697 0000065E E670                    	out  	70h, al
   698                                  	; 23/02/2015
   699 00000660 90                      	nop
   700 00000661 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
   701                                  				; for preventing unknown state (!?)
   702                                  	;
   703                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
   704                                  	;
   705                                  	; 02/09/2014
   706 00000663 6631DB                  	xor	bx, bx
   707 00000666 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
   708 0000066A E8E4110000              	call	_set_cpos	; 24/01/2016
   709                                  	;
   710                                  	; 06/11/2014
   711 0000066F E8C5120000              	call	memory_info
   712                                  	; 14/08/2015
   713                                  	;call getch ; 28/02/2015
   714                                  drv_init:
   715 00000674 FB                      	sti	; Enable Interrupts 
   716                                  	; 06/02/2015
   717 00000675 8B15[70C90000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   718 0000067B 668B1D[6EC90000]        	mov	bx, [fd0_type] ; fd0, fd1
   719                                  	; 22/02/2015
   720 00000682 6621DB                  	and	bx, bx
   721 00000685 751B                    	jnz	short di1
   722                                  	;
   723 00000687 09D2                    	or 	edx, edx
   724 00000689 7529                    	jnz	short di2
   725                                  	;
   726                                  setup_error:
   727 0000068B BE[BFCA0000]            	mov 	esi, setup_error_msg
   728                                  psem:	
   729 00000690 AC                      	lodsb
   730 00000691 08C0                    	or	al, al
   731                                  	;jz	short haltx ; 22/02/2015
   732 00000693 7426                    	jz	short di3
   733 00000695 56                      	push	esi
   734 00000696 31DB                    	xor	ebx, ebx ; 0
   735                                  			; Video page 0 (bl=0)
   736 00000698 B407                    	mov	ah, 07h ; Black background, 
   737                                  			; light gray forecolor
   738 0000069A E820110000              	call	WRITE_TTY
   739 0000069F 5E                      	pop	esi
   740 000006A0 EBEE                    	jmp	short psem
   741                                  
   742                                  di1:
   743                                  	; supress 'jmp short T6'
   744                                  	;  (activate fdc motor control code)
   745 000006A2 66C705[88070000]90-     	mov	word [T5], 9090h ; nop
   745 000006AA 90                 
   746                                  	;
   747                                  	;mov	ax, int_0Eh	; IRQ 6 handler
   748                                  	;mov	di, 0Eh*4	; IRQ 6 vector
   749                                  	;stosw
   750                                  	;mov 	ax, cs
   751                                  	;stosw
   752                                  	;; 16/02/2015
   753                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   754                                  	;
   755 000006AB E8E7210000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   756                                  	;
   757 000006B0 09D2                    	or	edx, edx
   758 000006B2 7407                            jz      short di3
   759                                  di2:
   760 000006B4 E823220000              	call   	DISK_SETUP	; Initialize Fixed Disks
   761 000006B9 72D0                            jc      short setup_error
   762                                  di3:
   763 000006BB E84D120000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   764                                  	;
   765 000006C0 E89FBE0000              	call	display_disks ; 07/03/2015  (Temporary)
   766                                  ;haltx:
   767                                  	; 14/08/2015
   768                                  	;call	getch ; 22/02/2015
   769                                  	;sti	; Enable interrupts (for CPU)
   770                                  ;	; 29/01/2016
   771                                  ;	sub	ah, ah ;  read time count
   772                                  ;	call	int1Ah
   773                                  ;	mov	edx, ecx ; 18.2 * seconds
   774                                  ;md_info_msg_wait1:
   775                                  ;	; 29/01/2016
   776                                  ;	mov	ah, 1
   777                                  ;	call	int16h
   778                                  ;	jz	short md_info_msg_wait2
   779                                  ;	xor	ah, ah ; 0
   780                                  ;       call    int16h
   781                                  ;	jmp 	short md_info_msg_ok
   782                                  ;md_info_msg_wait2:
   783                                  ;	sub	ah, ah  ; read time count
   784                                  ;	call	int1Ah
   785                                  ;	cmp	edx, ecx ; ; 18.2 * seconds
   786                                  ;	jna	short md_info_msg_wait3
   787                                  ;	xchg 	edx, ecx	
   788                                  ;md_info_msg_wait3:
   789                                  ;	sub	ecx, edx
   790                                  ;	cmp	ecx, 127 ; 7 seconds (18.2 * 7)
   791                                  ;	jb	short md_info_msg_wait1		
   792                                  ;md_info_msg_ok:
   793                                  	; 30/06/2015
   794 000006C5 E84E370000              	call	sys_init
   795                                  	;
   796                                  	;jmp 	cpu_reset ; 22/02/2015
   797                                  hang:  
   798                                  	; 23/02/2015
   799                                  	;sti			; Enable interrupts
   800 000006CA F4                      	hlt
   801                                  	;
   802                                  	;nop
   803                                  	;; 03/12/2014
   804                                  	;; 28/08/2014
   805                                  	;mov	ah, 11h
   806                                  	;call	getc
   807                                  	;jz      _c8
   808                                  	;
   809                                  	; 23/02/2015
   810                                  	; 06/02/2015
   811                                  	; 07/09/2014
   812 000006CB 31DB                    	xor	ebx, ebx
   813 000006CD 8A1D[08CF0000]          	mov	bl, [ptty]	; active_page
   814 000006D3 89DE                    	mov	esi, ebx
   815 000006D5 66D1E6                  	shl 	si, 1
   816 000006D8 81C6[0ACF0000]          	add	esi, ttychr
   817 000006DE 668B06                  	mov	ax, [esi]
   818 000006E1 6621C0                  	and	ax, ax
   819                                  	;jz	short _c8
   820 000006E4 74E4                    	jz	short hang
   821 000006E6 66C7060000              	mov	word [esi], 0
   822 000006EB 80FB03                  	cmp	bl, 3		; Video page 3
   823                                  	;jb	short _c8
   824 000006EE 72DA                    	jb	short hang
   825                                  	;	
   826                                  	; 02/09/2014
   827 000006F0 B40E                    	mov	ah, 0Eh		; Yellow character 
   828                                  				; on black background
   829                                  	; 07/09/2014
   830                                  nxtl:
   831 000006F2 6653                    	push	bx
   832                                  	;
   833                                  	;xor	bx, bx		; bl = 0 (video page 0)
   834                                  				; bh = 0 (video mode)
   835                                  				; Retro UNIX 386 v1 - Video Mode 0
   836                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
   837 000006F4 6650                    	push	ax
   838 000006F6 E8C4100000              	call 	WRITE_TTY
   839 000006FB 6658                    	pop	ax
   840 000006FD 665B                    	pop	bx ; 07/09/2014
   841 000006FF 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
   842                                  	;jne	short _c8
   843 00000701 75C7                    	jne	short hang
   844 00000703 B00A                    	mov	al, 0Ah		; next line
   845 00000705 EBEB                    	jmp	short nxtl
   846                                  	
   847                                  ;_c8:
   848                                  ;	; 25/08/2014
   849                                  ;	cli				; Disable interrupts
   850                                  ;	mov	al, [scounter + 1]
   851                                  ;	and	al, al
   852                                  ;	jnz	hang
   853                                  ;	call	rtc_p
   854                                  ;	jmp     hang
   855                                  
   856                                  
   857                                  	; 27/08/2014
   858                                  	; 20/08/2014
   859                                  printk:
   860                                          ;mov    edi, [scr_row]
   861                                  pkl:
   862 00000707 AC                      	lodsb
   863 00000708 08C0                    	or 	al, al
   864 0000070A 7404                    	jz	short pkr
   865 0000070C 66AB                    	stosw
   866 0000070E EBF7                    	jmp	short pkl
   867                                  pkr:
   868 00000710 C3                      	retn
   869                                  
   870                                  ; 25/07/2015
   871                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
   872                                  ; 17/02/2015
   873                                  ; 06/02/2015 (unix386.s)
   874                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
   875                                  ;
   876                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
   877                                  ;
   878                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
   879                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
   880                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
   881                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
   882                                  ;									       :
   883                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
   884                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
   885                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
   886                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
   887                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
   888                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
   889                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
   890                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
   891                                  ;-------------------------------------------------------------------------------
   892                                  ;
   893                                  
   894                                  timer_int:	; IRQ 0
   895                                  ;int_08h:	; Timer
   896                                  	; 14/10/2015
   897                                  	; Here, we are simulating system call entry (for task switch)
   898                                  	; (If multitasking is enabled, 
   899                                  	; 'clock' procedure may jump to 'sysrelease')
   900 00000711 1E                      	push	ds
   901 00000712 06                      	push	es
   902 00000713 0FA0                    	push	fs
   903 00000715 0FA8                    	push	gs
   904 00000717 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
   905 00000718 66B91000                	mov     cx, KDATA
   906 0000071C 8ED9                            mov     ds, cx
   907 0000071E 8EC1                            mov     es, cx
   908 00000720 8EE1                            mov     fs, cx
   909 00000722 8EE9                            mov     gs, cx
   910                                  	;
   911 00000724 0F20D9                  	mov	ecx, cr3
   912 00000727 890D[C6070000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   913                                  	;
   914 0000072D 3B0D[D8CE0000]          	cmp 	ecx, [k_page_dir]
   915 00000733 741F                    	je	short T3
   916                                  	;
   917                                  	; timer interrupt has been occurred while OS is in user mode
   918 00000735 A3[80DF0000]            	mov 	[u.r0], eax
   919 0000073A 89E1                    	mov	ecx, esp
   920 0000073C 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   921 0000073F 890D[78DF0000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   922 00000745 8925[7CDF0000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   923                                  	;
   924 0000074B 8B0D[D8CE0000]          	mov	ecx, [k_page_dir]
   925 00000751 0F22D9                  	mov	cr3, ecx
   926                                  T3:
   927 00000754 FB                      	sti				; INTERRUPTS BACK ON
   928 00000755 66FF05[5CCF0000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   929 0000075C 7507                    	JNZ	short T4		; GO TO TEST_DAY
   930 0000075E 66FF05[5ECF0000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   931                                  T4:					; TEST_DAY
   932 00000765 66833D[5ECF0000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
   933 0000076D 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
   934 0000076F 66813D[5CCF0000]B0-     	CMP	word [TIMER_LOW],0B0H
   934 00000777 00                 
   935 00000778 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
   936                                  
   937                                  ;-----	TIMER HAS GONE 24 HOURS
   938                                  	;;SUB	AX,AX
   939                                  	;MOV	[TIMER_HIGH],AX
   940                                  	;MOV	[TIMER_LOW],AX
   941 0000077A 29C0                    	sub	eax, eax
   942 0000077C A3[5CCF0000]            	mov	[TIMER_LH], eax
   943                                  	;	
   944 00000781 C605[60CF0000]01        	MOV	byte [TIMER_OFL],1
   945                                  
   946                                  ;-----	TEST FOR DISKETTE TIME OUT
   947                                  
   948                                  T5:
   949                                  	; 23/12/2014
   950 00000788 EB1D                    	jmp	short T6		; will be replaced with nop, nop
   951                                  					; (9090h) if a floppy disk
   952                                  					; is detected.
   953                                  	;mov	al,[CS:MOTOR_COUNT]
   954 0000078A A0[63CF0000]            	mov	al, [MOTOR_COUNT]
   955 0000078F FEC8                    	dec	al
   956                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
   957 00000791 A2[63CF0000]            	mov	[MOTOR_COUNT], al
   958                                  	;mov	[ORG_MOTOR_COUNT], al
   959 00000796 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
   960 00000798 B0F0                    	mov 	al,0F0h
   961                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
   962 0000079A 2005[62CF0000]          	and	[MOTOR_STATUS], al
   963                                  	;and	[ORG_MOTOR_STATUS], al
   964 000007A0 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
   965                                  					; bit 2 = enable controller
   966                                  					;	1 = normal operation
   967                                  					;	0 = reset	
   968                                  					; bit 0, 1 = drive select
   969                                  					; bit 4-7 = motor running bits 
   970 000007A2 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
   971 000007A6 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
   972                                  T6:	
   973                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
   974                                  					; TIMER TICK INTERRUPT
   975                                  	;;inc	word [wait_count] ;;27/02/2015
   976                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
   977                                  	;;;;cli
   978                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
   979 000007A7 FF15[C2070000]          	call	[x_timer] ; 14/05/2015
   980                                  T7:
   981                                  	; 14/10/2015
   982 000007AD B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
   983 000007AF FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
   984 000007B0 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
   985                                  	;
   986 000007B2 A1[C6070000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
   987 000007B7 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
   988                                  	;
   989 000007BA 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   990                                  	;
   991 000007BB 0FA9                    	pop	gs
   992 000007BD 0FA1                    	pop	fs
   993 000007BF 07                      	pop	es
   994 000007C0 1F                      	pop	ds
   995 000007C1 CF                      	iretd	; return from interrupt
   996                                  
   997                                  
   998                                  ; ////////////////
   999                                  
  1000                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
  1001                                  x_timer:
  1002 000007C2 [CA070000]              	dd 	u_timer			; 14/05/2015
  1003                                  	;dd	clock
  1004                                  
  1005                                  ; 14/10/2015
  1006 000007C6 00000000                cr3reg: dd 0
  1007                                  
  1008                                  	; 06/02/2015
  1009                                  	; 07/09/2014
  1010                                  	; 21/08/2014
  1011                                  u_timer:
  1012                                  ;timer_int:	; IRQ 0
  1013                                  	; 06/02/2015
  1014                                  	;push	eax
  1015                                  	;push	edx
  1016                                  	;push	ecx
  1017                                  	;push	ebx
  1018                                  	;push	ds
  1019                                  	;push	es
  1020                                  	;mov	eax, KDATA
  1021                                  	;mov	ds, ax
  1022                                  	;mov	es, ax
  1023 000007CA FF05[1ECF0000]          	inc	dword [tcount]
  1024 000007D0 BB[0DCA0000]            	mov	ebx, tcountstr + 4
  1025 000007D5 66A1[1ECF0000]          	mov	ax, [tcount]
  1026 000007DB B90A000000              	mov	ecx, 10
  1027                                  rp_divtcnt:
  1028 000007E0 31D2                    	xor	edx, edx
  1029 000007E2 F7F1                    	div	ecx
  1030 000007E4 80C230                  	add	dl, 30h
  1031 000007E7 8813                    	mov	[ebx], dl
  1032 000007E9 6609C0                  	or	ax, ax
  1033 000007EC 7403                    	jz	short print_lzero
  1034 000007EE 4B                      	dec	ebx
  1035 000007EF EBEF                    	jmp	short rp_divtcnt
  1036                                  print_lzero:
  1037 000007F1 81FB[09CA0000]          	cmp	ebx, tcountstr
  1038 000007F7 7606                    	jna	short print_tcount
  1039 000007F9 4B                      	dec	ebx
  1040 000007FA C60330                   	mov	byte [ebx], 30h
  1041 000007FD EBF2                    	jmp	short print_lzero
  1042                                  print_tcount:
  1043 000007FF 56                      	push	esi
  1044 00000800 57                      	push	edi
  1045 00000801 BE[E5C90000]            	mov	esi, timer_msg ; Timer interrupt message
  1046                                  	; 07/09/2014
  1047 00000806 66BB0100                	mov	bx, 1		; Video page 1
  1048                                  ptmsg:
  1049 0000080A AC                      	lodsb
  1050 0000080B 08C0                    	or	al, al
  1051 0000080D 740F                    	jz	short ptmsg_ok
  1052 0000080F 56                      	push	esi
  1053 00000810 6653                    	push	bx
  1054 00000812 B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1055 00000814 E8A60F0000              	call 	WRITE_TTY
  1056 00000819 665B                    	pop	bx
  1057 0000081B 5E                      	pop	esi
  1058 0000081C EBEC                    	jmp	short ptmsg
  1059                                  	;; 27/08/2014
  1060                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1061                                  	;call	printk
  1062                                  	;
  1063                                  ptmsg_ok:
  1064                                  	; 07/09/2014
  1065 0000081E 6631D2                  	xor	dx, dx		; column 0, row 0
  1066 00000821 E82D100000              	call	_set_cpos	; set cursor position to 0,0 
  1067                                  	; 23/02/2015
  1068                                  	; 25/08/2014
  1069                                  	;mov	ebx, scounter		; (seconds counter)
  1070                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1071                                  ;	dec	byte [scounter+1]
  1072                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1073                                  ;	jns	short u_timer_retn
  1074                                  	; 26/02/2015
  1075                                  ;	call	rtc_p
  1076                                  ;	mov	ebx, scounter		; (seconds counter)
  1077                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1078                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1079                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1080                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1081                                  ;	mov	byte [ebx], 5
  1082                                  ;	inc	byte [ebx+1] ; 19
  1083                                  ;;timer_eoi:
  1084                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1085                                  ;;	out	20h, al	; 8259 PORT
  1086                                  	;
  1087                                  ;u_timer_retn:  ; 06/02/2015
  1088 00000826 5F                      	pop	edi
  1089 00000827 5E                      	pop	esi
  1090                                  	;pop	es
  1091                                  	;pop	ds
  1092                                  	;pop	ebx
  1093                                  	;pop	ecx
  1094                                  	;pop	edx
  1095                                  	;pop	eax
  1096                                  	;iret
  1097 00000828 C3                      	retn	; 06/02/2015
  1098                                  
  1099                                  	; 28/08/2014
  1100                                  irq0:
  1101 00000829 6A00                            push 	dword 0
  1102 0000082B EB48                    	jmp	short which_irq
  1103                                  irq1:
  1104 0000082D 6A01                            push 	dword 1
  1105 0000082F EB44                    	jmp	short which_irq
  1106                                  irq2:
  1107 00000831 6A02                            push 	dword 2
  1108 00000833 EB40                    	jmp	short which_irq
  1109                                  irq3:
  1110                                  	; 20/11/2015
  1111                                  	; 24/10/2015
  1112 00000835 2EFF15[BFBD0000]        	call	dword [cs:com2_irq3]
  1113 0000083C 6A03                    	push 	dword 3
  1114 0000083E EB35                    	jmp	short which_irq
  1115                                  irq4:
  1116                                  	; 20/11/2015
  1117                                  	; 24/10/2015
  1118 00000840 2EFF15[BBBD0000]        	call	dword [cs:com1_irq4]
  1119 00000847 6A04                            push 	dword 4
  1120 00000849 EB2A                    	jmp	short which_irq
  1121                                  irq5:
  1122 0000084B 6A05                            push 	dword 5
  1123 0000084D EB26                    	jmp	short which_irq
  1124                                  irq6:
  1125 0000084F 6A06                            push 	dword 6
  1126 00000851 EB22                    	jmp	short which_irq
  1127                                  irq7:
  1128 00000853 6A07                            push 	dword 7
  1129 00000855 EB1E                    	jmp	short which_irq
  1130                                  irq8:
  1131 00000857 6A08                            push 	dword 8
  1132 00000859 EB1A                    	jmp	short which_irq
  1133                                  irq9:
  1134 0000085B 6A09                            push 	dword 9
  1135 0000085D EB16                    	jmp	short which_irq
  1136                                  irq10:
  1137 0000085F 6A0A                            push 	dword 10
  1138 00000861 EB12                    	jmp	short which_irq
  1139                                  irq11:
  1140 00000863 6A0B                            push 	dword 11
  1141 00000865 EB0E                    	jmp	short which_irq
  1142                                  irq12:
  1143 00000867 6A0C                            push 	dword 12
  1144 00000869 EB0A                    	jmp	short which_irq
  1145                                  irq13:
  1146 0000086B 6A0D                            push 	dword 13
  1147 0000086D EB06                    	jmp	short which_irq
  1148                                  irq14:
  1149 0000086F 6A0E                            push 	dword 14
  1150 00000871 EB02                    	jmp	short which_irq
  1151                                  irq15:
  1152 00000873 6A0F                            push 	dword 15
  1153                                  	;jmp	short which_irq
  1154                                  
  1155                                  	; 19/10/2015
  1156                                  	; 29/08/2014
  1157                                  	; 21/08/2014
  1158                                  which_irq:
  1159 00000875 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1160 00000878 53                      	push	ebx
  1161 00000879 56                      	push	esi
  1162 0000087A 57                      	push	edi
  1163 0000087B 1E                      	push 	ds
  1164 0000087C 06                      	push 	es
  1165                                  	;
  1166 0000087D 88C3                    	mov	bl, al
  1167                                  	;
  1168 0000087F B810000000              	mov	eax, KDATA
  1169 00000884 8ED8                    	mov	ds, ax
  1170 00000886 8EC0                    	mov	es, ax
  1171                                  	; 19/10/2015
  1172 00000888 FC                      	cld
  1173                                          ; 27/08/2014
  1174 00000889 8105[C8C90000]A000-             add     dword [scr_row], 0A0h
  1174 00000891 0000               
  1175                                  	;
  1176 00000893 B417                    	mov	ah, 17h	; blue (1) background, 
  1177                                  			; light gray (7) forecolor
  1178 00000895 8B3D[C8C90000]                  mov     edi, [scr_row]
  1179 0000089B B049                    	mov	al, 'I'
  1180 0000089D 66AB                    	stosw
  1181 0000089F B052                    	mov	al, 'R'
  1182 000008A1 66AB                    	stosw
  1183 000008A3 B051                    	mov	al, 'Q'
  1184 000008A5 66AB                    	stosw
  1185 000008A7 B020                    	mov	al, ' '
  1186 000008A9 66AB                    	stosw
  1187 000008AB 88D8                    	mov	al, bl
  1188 000008AD 3C0A                    	cmp	al, 10
  1189 000008AF 7208                    	jb	short iix
  1190 000008B1 B031                    	mov	al, '1'
  1191 000008B3 66AB                    	stosw
  1192 000008B5 88D8                    	mov	al, bl
  1193 000008B7 2C0A                    	sub	al, 10
  1194                                  iix:
  1195 000008B9 0430                    	add	al, '0'
  1196 000008BB 66AB                    	stosw
  1197 000008BD B020                    	mov	al, ' '
  1198 000008BF 66AB                    	stosw
  1199 000008C1 B021                    	mov	al, '!'
  1200 000008C3 66AB                    	stosw
  1201 000008C5 B020                    	mov	al, ' '
  1202 000008C7 66AB                    	stosw
  1203                                  	; 23/02/2015
  1204 000008C9 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1205 000008CC 0F8695010000            	jna	iiret
  1206 000008D2 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1207 000008D4 E6A0                    	out	0A0h, al ; the 2nd 8259
  1208 000008D6 E98C010000              	jmp     iiret
  1209                                  	;
  1210                                  	; 22/08/2014
  1211                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1212                                  	;out	20h, al	; 8259 PORT
  1213                                  	;
  1214                                  	;pop	es
  1215                                  	;pop	ds
  1216                                  	;pop	edi
  1217                                  	;pop	esi
  1218                                  	;pop	ebx
  1219                                  	;pop 	eax
  1220                                  	;iret
  1221                                  
  1222                                  	; 02/04/2015
  1223                                  	; 25/08/2014
  1224                                  exc0:
  1225 000008DB 6A00                            push 	dword 0
  1226 000008DD E990000000                      jmp     cpu_except
  1227                                  exc1:
  1228 000008E2 6A01                            push 	dword 1
  1229 000008E4 E989000000                      jmp     cpu_except
  1230                                  exc2:
  1231 000008E9 6A02                            push 	dword 2
  1232 000008EB E982000000                      jmp     cpu_except
  1233                                  exc3:
  1234 000008F0 6A03                            push 	dword 3
  1235 000008F2 EB7E                            jmp     cpu_except
  1236                                  exc4:
  1237 000008F4 6A04                            push 	dword 4
  1238 000008F6 EB7A                            jmp     cpu_except
  1239                                  exc5:
  1240 000008F8 6A05                            push 	dword 5
  1241 000008FA EB76                            jmp     cpu_except
  1242                                  exc6:
  1243 000008FC 6A06                            push 	dword 6
  1244 000008FE EB72                            jmp     cpu_except
  1245                                  exc7:
  1246 00000900 6A07                            push 	dword 7
  1247 00000902 EB6E                            jmp     cpu_except
  1248                                  exc8:
  1249                                  	; [esp] = Error code
  1250 00000904 6A08                            push 	dword 8
  1251 00000906 EB5C                            jmp     cpu_except_en
  1252                                  exc9:
  1253 00000908 6A09                            push 	dword 9
  1254 0000090A EB66                            jmp     cpu_except
  1255                                  exc10:
  1256                                  	; [esp] = Error code
  1257 0000090C 6A0A                            push 	dword 10
  1258 0000090E EB54                            jmp     cpu_except_en
  1259                                  exc11:
  1260                                  	; [esp] = Error code
  1261 00000910 6A0B                            push 	dword 11
  1262 00000912 EB50                            jmp     cpu_except_en
  1263                                  exc12:
  1264                                  	; [esp] = Error code
  1265 00000914 6A0C                            push 	dword 12
  1266 00000916 EB4C                            jmp     cpu_except_en
  1267                                  exc13:
  1268                                  	; [esp] = Error code
  1269 00000918 6A0D                            push 	dword 13
  1270 0000091A EB48                            jmp     cpu_except_en
  1271                                  exc14:
  1272                                  	; [esp] = Error code
  1273 0000091C 6A0E                            push 	dword 14
  1274 0000091E EB44                    	jmp	short cpu_except_en
  1275                                  exc15:
  1276 00000920 6A0F                            push 	dword 15
  1277 00000922 EB4E                            jmp     cpu_except
  1278                                  exc16:
  1279 00000924 6A10                            push 	dword 16
  1280 00000926 EB4A                            jmp     cpu_except
  1281                                  exc17:
  1282                                  	; [esp] = Error code
  1283 00000928 6A11                            push 	dword 17
  1284 0000092A EB38                    	jmp	short cpu_except_en
  1285                                  exc18:
  1286 0000092C 6A12                            push 	dword 18
  1287 0000092E EB42                    	jmp	short cpu_except
  1288                                  exc19:
  1289 00000930 6A13                            push 	dword 19
  1290 00000932 EB3E                    	jmp	short cpu_except
  1291                                  exc20:
  1292 00000934 6A14                            push 	dword 20
  1293 00000936 EB3A                    	jmp	short cpu_except
  1294                                  exc21:
  1295 00000938 6A15                            push 	dword 21
  1296 0000093A EB36                    	jmp	short cpu_except
  1297                                  exc22:
  1298 0000093C 6A16                            push 	dword 22
  1299 0000093E EB32                    	jmp	short cpu_except
  1300                                  exc23:
  1301 00000940 6A17                            push 	dword 23
  1302 00000942 EB2E                    	jmp	short cpu_except
  1303                                  exc24:
  1304 00000944 6A18                            push 	dword 24
  1305 00000946 EB2A                    	jmp	short cpu_except
  1306                                  exc25:
  1307 00000948 6A19                            push 	dword 25
  1308 0000094A EB26                    	jmp	short cpu_except
  1309                                  exc26:
  1310 0000094C 6A1A                            push 	dword 26
  1311 0000094E EB22                    	jmp	short cpu_except
  1312                                  exc27:
  1313 00000950 6A1B                            push 	dword 27
  1314 00000952 EB1E                    	jmp	short cpu_except
  1315                                  exc28:
  1316 00000954 6A1C                            push 	dword 28
  1317 00000956 EB1A                    	jmp	short cpu_except
  1318                                  exc29:
  1319 00000958 6A1D                            push 	dword 29
  1320 0000095A EB16                    	jmp	short cpu_except
  1321                                  exc30:
  1322 0000095C 6A1E                            push 	dword 30
  1323 0000095E EB04                    	jmp	short cpu_except_en
  1324                                  exc31:
  1325 00000960 6A1F                            push 	dword 31
  1326 00000962 EB0E                            jmp     short cpu_except
  1327                                  
  1328                                  	; 19/10/2015
  1329                                  	; 19/09/2015
  1330                                  	; 01/09/2015
  1331                                  	; 28/08/2015
  1332                                  	; 28/08/2014
  1333                                  cpu_except_en:
  1334 00000964 87442404                	xchg	eax, [esp+4] ; Error code
  1335 00000968 36A3[54EC0000]          	mov	[ss:error_code], eax
  1336 0000096E 58                      	pop	eax  ; Exception number
  1337 0000096F 870424                  	xchg	eax, [esp]
  1338                                  		; eax = eax before exception
  1339                                  		; [esp] -> exception number
  1340                                  		; [esp+4] -> EIP to return
  1341                                  	; 19/10/2015
  1342                                  	; 19/09/2015
  1343                                  	; 01/09/2015
  1344                                  	; 28/08/2015
  1345                                  	; 29/08/2014
  1346                                  	; 28/08/2014
  1347                                  	; 25/08/2014
  1348                                  	; 21/08/2014
  1349                                  cpu_except:	; CPU Exceptions
  1350 00000972 FC                      	cld
  1351 00000973 870424                  	xchg	eax, [esp] 
  1352                                  		; eax = Exception number
  1353                                  		; [esp] = eax (before exception)	
  1354 00000976 53                      	push	ebx
  1355 00000977 56                      	push	esi
  1356 00000978 57                      	push	edi
  1357 00000979 1E                      	push 	ds
  1358 0000097A 06                      	push 	es
  1359                                  	; 28/08/2015
  1360 0000097B 66BB1000                	mov	bx, KDATA
  1361 0000097F 8EDB                    	mov	ds, bx
  1362 00000981 8EC3                    	mov	es, bx
  1363 00000983 0F20DB                  	mov	ebx, cr3
  1364 00000986 53                      	push	ebx ; (*) page directory
  1365                                  	; 19/10/2015
  1366 00000987 FC                      	cld
  1367                                  	; 25/03/2015
  1368 00000988 8B1D[D8CE0000]          	mov	ebx, [k_page_dir]
  1369 0000098E 0F22DB                  	mov	cr3, ebx
  1370                                  	; 28/08/2015
  1371 00000991 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1372 00000994 7512                    	jne	short cpu_except_nfp
  1373 00000996 E8462A0000              	call	page_fault_handler
  1374 0000099B 21C0                    	and 	eax, eax
  1375 0000099D 0F84C0000000                    jz	iiretp ; 01/09/2015
  1376 000009A3 B80E000000              	mov	eax, 0Eh ; 14
  1377                                  cpu_except_nfp:
  1378                                  	; 02/04/2015
  1379 000009A8 BB[CA060000]            	mov	ebx, hang
  1380 000009AD 875C241C                	xchg	ebx, [esp+28]
  1381                                  		; EIP (points to instruction which faults)
  1382                                  	  	; New EIP (hang)
  1383 000009B1 891D[58EC0000]          	mov	[FaultOffset], ebx
  1384 000009B7 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1385 000009BF 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1386                                  	;
  1387 000009C7 88C4                    	mov	ah, al
  1388 000009C9 240F                    	and	al, 0Fh
  1389 000009CB 3C09                    	cmp	al, 9
  1390 000009CD 7602                    	jna	short h1ok
  1391 000009CF 0407                    	add	al, 'A'-':'
  1392                                  h1ok:
  1393 000009D1 D0EC                    	shr	ah, 1
  1394 000009D3 D0EC                    	shr	ah, 1
  1395 000009D5 D0EC                    	shr	ah, 1
  1396 000009D7 D0EC                    	shr	ah, 1
  1397 000009D9 80FC09                  	cmp	ah, 9
  1398 000009DC 7603                    	jna	short h2ok
  1399 000009DE 80C407                  	add	ah, 'A'-':'
  1400                                  h2ok:	
  1401 000009E1 86E0                    	xchg 	ah, al	
  1402 000009E3 66053030                	add	ax, '00'
  1403 000009E7 66A3[20CA0000]          	mov	[excnstr], ax
  1404                                  	;
  1405                                  	; 29/08/2014
  1406 000009ED A1[58EC0000]            	mov	eax, [FaultOffset]
  1407 000009F2 51                      	push	ecx
  1408 000009F3 52                      	push	edx
  1409 000009F4 89E3                    	mov	ebx, esp
  1410                                  	; 28/08/2015
  1411 000009F6 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1412                                  			  ; to hexadecimal string
  1413                                  	;mov	ecx, 10	    ; divisor to convert	
  1414                                  			    ; binary number to decimal string
  1415                                  b2d1:
  1416 000009FB 31D2                    	xor	edx, edx
  1417 000009FD F7F1                    	div	ecx
  1418 000009FF 6652                    	push	dx
  1419 00000A01 39C8                    	cmp	eax, ecx
  1420 00000A03 73F6                    	jnb	short b2d1
  1421 00000A05 BF[2BCA0000]            	mov	edi, EIPstr ; EIP value
  1422                                  			    ; points to instruction which faults	
  1423                                  	; 28/08/2015
  1424 00000A0A 89C2                    	mov	edx, eax
  1425                                  b2d2:
  1426                                  	;add	al, '0'
  1427 00000A0C 8A82[011A0000]          	mov	al, [edx+hexchrs]
  1428 00000A12 AA                      	stosb		    ; write hexadecimal digit to its place	
  1429 00000A13 39E3                    	cmp	ebx, esp
  1430 00000A15 7606                    	jna	short b2d3
  1431 00000A17 6658                    	pop	ax
  1432 00000A19 88C2                    	mov	dl, al
  1433 00000A1B EBEF                    	jmp	short b2d2
  1434                                  b2d3:
  1435 00000A1D B068                    	mov 	al, 'h' ; 28/08/2015
  1436 00000A1F AA                      	stosb
  1437 00000A20 B020                    	mov	al, 20h	    ; space
  1438 00000A22 AA                      	stosb
  1439 00000A23 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1440 00000A25 AA                      	stosb
  1441                                  	;
  1442 00000A26 5A                      	pop	edx
  1443 00000A27 59                      	pop	ecx
  1444                                  	;
  1445 00000A28 B44F                    	mov	ah, 4Fh	; red (4) background, 
  1446                                  			; white (F) forecolor
  1447 00000A2A BE[10CA0000]            	mov	esi, exc_msg ; message offset
  1448                                  	;
  1449 00000A2F EB19                    	jmp	short piemsg
  1450                                  	;
  1451                                          ;add    dword [scr_row], 0A0h
  1452                                          ;mov    edi, [scr_row]
  1453                                          ;
  1454                                  	;call 	printk
  1455                                  	;
  1456                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1457                                  	;out	20h, al	; 8259 PORT
  1458                                  	;
  1459                                  	;pop	es
  1460                                  	;pop	ds
  1461                                  	;pop	edi
  1462                                  	;pop	esi
  1463                                  	;pop 	eax
  1464                                  	;iret
  1465                                  	
  1466                                  	; 18/04/2016
  1467                                  	; 28/08/2015
  1468                                  	; 23/02/2015
  1469                                  	; 20/08/2014
  1470                                  ignore_int:
  1471 00000A31 50                      	push	eax
  1472 00000A32 53                      	push	ebx ; 23/02/2015
  1473 00000A33 56                      	push	esi
  1474 00000A34 57                      	push	edi
  1475 00000A35 1E                      	push 	ds
  1476 00000A36 06                      	push 	es
  1477                                  	; 18/04/2016
  1478 00000A37 66B81000                	mov	ax, KDATA
  1479 00000A3B 8ED8                    	mov	ds, ax
  1480 00000A3D 8EC0                    	mov	es, ax
  1481                                  	; 28/08/2015
  1482 00000A3F 0F20D8                  	mov	eax, cr3
  1483 00000A42 50                      	push	eax ; (*) page directory
  1484                                  	;
  1485 00000A43 B467                    	mov	ah, 67h	; brown (6) background, 
  1486                                  			; light gray (7) forecolor
  1487 00000A45 BE[D0C90000]            	mov	esi, int_msg ; message offset
  1488                                  piemsg:
  1489                                          ; 27/08/2014
  1490 00000A4A 8105[C8C90000]A000-             add     dword [scr_row], 0A0h
  1490 00000A52 0000               
  1491 00000A54 8B3D[C8C90000]                  mov     edi, [scr_row]
  1492                                          ;
  1493 00000A5A E8A8FCFFFF              	call 	printk
  1494                                  	;
  1495                                  	; 23/02/2015
  1496 00000A5F B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1497 00000A61 E6A0                    	out	0A0h, al ; the 2nd 8259
  1498                                  iiretp: ; 01/09/2015
  1499                                  	; 28/08/2015
  1500 00000A63 58                      	pop	eax ; (*) page directory
  1501 00000A64 0F22D8                  	mov	cr3, eax
  1502                                  	;
  1503                                  iiret:
  1504                                  	; 22/08/2014
  1505 00000A67 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1506 00000A69 E620                    	out	20h, al	; 8259 PORT
  1507                                  	;
  1508 00000A6B 07                      	pop	es
  1509 00000A6C 1F                      	pop	ds
  1510 00000A6D 5F                      	pop	edi
  1511 00000A6E 5E                      	pop	esi
  1512 00000A6F 5B                      	pop	ebx ; 29/08/2014
  1513 00000A70 58                      	pop 	eax
  1514 00000A71 CF                      	iretd
  1515                                  
  1516                                  	; 26/02/2015
  1517                                  	; 07/09/2014
  1518                                  	; 25/08/2014
  1519                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1520                                  	; 22/08/2014
  1521 00000A72 50                      	push	eax
  1522 00000A73 53                      	push	ebx ; 29/08/2014
  1523 00000A74 56                      	push	esi
  1524 00000A75 57                      	push	edi
  1525 00000A76 1E                      	push 	ds
  1526 00000A77 06                      	push 	es
  1527                                  	;
  1528 00000A78 B810000000              	mov	eax, KDATA
  1529 00000A7D 8ED8                    	mov	ds, ax
  1530 00000A7F 8EC0                    	mov	es, ax
  1531                                  	;
  1532                                  	; 25/08/2014
  1533 00000A81 E884000000              	call	rtc_p
  1534                                  	;
  1535                                  	; 22/02/2015 - dsectpm.s
  1536                                  	; [ source: http://wiki.osdev.org/RTC ]
  1537                                  	; read status register C to complete procedure
  1538                                  	;(it is needed to get a next IRQ 8) 
  1539 00000A86 B00C                    	mov	al, 0Ch ; 
  1540 00000A88 E670                    	out	70h, al ; select register C
  1541 00000A8A 90                      	nop
  1542 00000A8B E471                    	in	al, 71h ; just throw away contents
  1543                                  	; 22/02/2015
  1544 00000A8D B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1545 00000A8F E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1546                                  	;
  1547 00000A91 EBD4                    	jmp	short iiret	
  1548                                  
  1549                                  	; 22/08/2014
  1550                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  1551                                  	; (INT 1Ah)
  1552                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  1553                                  time_of_day:
  1554 00000A93 E831330000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  1555 00000A98 726F                            jc      short rtc_retn 
  1556 00000A9A B000                    	mov	al, CMOS_SECONDS
  1557 00000A9C E843330000              	call	CMOS_READ
  1558 00000AA1 A2[4ECF0000]            	mov	[time_seconds], al 
  1559 00000AA6 B002                    	mov	al, CMOS_MINUTES
  1560 00000AA8 E837330000              	call	CMOS_READ
  1561 00000AAD A2[4FCF0000]            	mov	[time_minutes], al 
  1562 00000AB2 B004                    	mov	al, CMOS_HOURS
  1563 00000AB4 E82B330000              	call	CMOS_READ
  1564 00000AB9 A2[50CF0000]                    mov     [time_hours], al
  1565 00000ABE B006                    	mov	al, CMOS_DAY_WEEK 
  1566 00000AC0 E81F330000              	call	CMOS_READ
  1567 00000AC5 A2[51CF0000]            	mov	[date_wday], al
  1568 00000ACA B007                     	mov	al, CMOS_DAY_MONTH
  1569 00000ACC E813330000              	call	CMOS_READ
  1570 00000AD1 A2[52CF0000]            	mov	[date_day], al
  1571 00000AD6 B008                    	mov	al, CMOS_MONTH
  1572 00000AD8 E807330000              	call	CMOS_READ
  1573 00000ADD A2[53CF0000]            	mov	[date_month], al
  1574 00000AE2 B009                    	mov	al, CMOS_YEAR
  1575 00000AE4 E8FB320000              	call	CMOS_READ
  1576 00000AE9 A2[54CF0000]            	mov	[date_year], al
  1577 00000AEE B032                    	mov	al, CMOS_CENTURY
  1578 00000AF0 E8EF320000              	call	CMOS_READ
  1579 00000AF5 A2[55CF0000]            	mov	[date_century], al
  1580                                  	;
  1581 00000AFA B000                    	mov	al, CMOS_SECONDS
  1582 00000AFC E8E3320000              	call 	CMOS_READ
  1583 00000B01 3A05[4ECF0000]          	cmp	al, [time_seconds]
  1584 00000B07 758A                    	jne	short time_of_day
  1585                                  
  1586                                  rtc_retn:
  1587 00000B09 C3                      	retn
  1588                                  
  1589                                  rtc_p:	
  1590                                  	; 07/09/2014
  1591                                  	; 29/08/2014
  1592                                  	; 27/08/2014
  1593                                  	; 25/08/2014
  1594                                   	; Print Real Time Clock content
  1595                                  	;
  1596                                  	;
  1597 00000B0A E884FFFFFF              	call	time_of_day
  1598 00000B0F 72F8                    	jc	short rtc_retn
  1599                                  	;
  1600 00000B11 3A05[82CA0000]          	cmp	al, [ptime_seconds]
  1601 00000B17 74F0                            je      short rtc_retn ; 29/08/2014
  1602                                  	;
  1603 00000B19 A2[82CA0000]            	mov	[ptime_seconds], al
  1604                                  	;
  1605 00000B1E A0[55CF0000]            	mov	al, [date_century]
  1606 00000B23 E8BE000000              	call	bcd_to_ascii
  1607 00000B28 66A3[4FCA0000]          	mov	[datestr+6], ax
  1608 00000B2E A0[54CF0000]            	mov	al, [date_year]
  1609 00000B33 E8AE000000              	call	bcd_to_ascii
  1610 00000B38 66A3[51CA0000]          	mov	[datestr+8], ax
  1611 00000B3E A0[53CF0000]            	mov	al, [date_month]
  1612 00000B43 E89E000000              	call	bcd_to_ascii
  1613 00000B48 66A3[4CCA0000]          	mov	[datestr+3], ax
  1614 00000B4E A0[52CF0000]            	mov	al, [date_day]
  1615 00000B53 E88E000000              	call	bcd_to_ascii
  1616 00000B58 66A3[49CA0000]          	mov	[datestr], ax
  1617                                  	;
  1618 00000B5E 0FB61D[51CF0000]        	movzx	ebx, byte [date_wday]
  1619 00000B65 C0E302                  	shl 	bl, 2
  1620 00000B68 81C3[62CA0000]          	add	ebx, daytmp
  1621 00000B6E 8B03                    	mov	eax, [ebx]
  1622 00000B70 A3[54CA0000]            	mov	[daystr], eax
  1623                                  	;
  1624 00000B75 A0[50CF0000]            	mov	al, [time_hours]
  1625 00000B7A E867000000              	call	bcd_to_ascii
  1626 00000B7F 66A3[58CA0000]          	mov	[timestr], ax
  1627 00000B85 A0[4FCF0000]            	mov	al, [time_minutes]
  1628 00000B8A E857000000              	call	bcd_to_ascii
  1629 00000B8F 66A3[5BCA0000]          	mov	[timestr+3], ax
  1630 00000B95 A0[4ECF0000]            	mov	al, [time_seconds]
  1631 00000B9A E847000000              	call	bcd_to_ascii
  1632 00000B9F 66A3[5ECA0000]          	mov	[timestr+6], ax
  1633                                  	;		
  1634 00000BA5 BE[37CA0000]            	mov	esi, rtc_msg ; message offset
  1635                                  	; 23/02/2015
  1636 00000BAA 52                      	push	edx
  1637 00000BAB 51                      	push	ecx
  1638                                  	; 07/09/2014
  1639 00000BAC 66BB0200                	mov	bx, 2		; Video page 2
  1640                                  prtmsg:
  1641 00000BB0 AC                      	lodsb
  1642 00000BB1 08C0                    	or	al, al
  1643 00000BB3 740F                    	jz	short prtmsg_ok
  1644 00000BB5 56                      	push	esi
  1645 00000BB6 6653                    	push	bx
  1646 00000BB8 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  1647                                  			; white (F) forecolor
  1648 00000BBA E8000C0000              	call 	WRITE_TTY
  1649 00000BBF 665B                    	pop	bx
  1650 00000BC1 5E                      	pop	esi
  1651 00000BC2 EBEC                    	jmp	short prtmsg
  1652                                  	;
  1653                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  1654                                  	;call	printk
  1655                                  prtmsg_ok:
  1656                                  	; 07/09/2014
  1657 00000BC4 6631D2                  	xor	dx, dx		; column 0, row 0
  1658 00000BC7 E8870C0000              	call	_set_cpos	; set curspor position to 0,0 
  1659                                  	; 23/02/2015
  1660 00000BCC 59                      	pop	ecx
  1661 00000BCD 5A                      	pop	edx
  1662 00000BCE C3                      	retn
  1663                                  
  1664                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  1665                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  1666                                  default_irq7:
  1667 00000BCF 6650                    	push	ax
  1668 00000BD1 B00B                    	mov	al, 0Bh  ; In-Service register
  1669 00000BD3 E620                    	out	20h, al
  1670 00000BD5 EB00                            jmp short $+2
  1671 00000BD7 EB00                    	jmp short $+2
  1672 00000BD9 E420                    	in	al, 20h
  1673 00000BDB 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  1674 00000BDD 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  1675 00000BDF B020                            mov     al, 20h ; EOI
  1676 00000BE1 E620                    	out	20h, al 
  1677                                  irq7_iret:
  1678 00000BE3 6658                    	pop	ax
  1679 00000BE5 CF                      	iretd
  1680                                  	
  1681                                  bcd_to_ascii:
  1682                                  	; 25/08/2014
  1683                                  	; INPUT ->
  1684                                  	;	al = Packed BCD number
  1685                                  	; OUTPUT ->
  1686                                  	;	ax  = ASCII word/number
  1687                                  	;
  1688                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  1689                                  	;
  1690 00000BE6 D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  1691                                  					; AH = AL / 10h
  1692                                  					; AL = AL MOD 10h
  1693 00000BE8 660D3030                	or ax,'00'                      ; Make it ASCII based
  1694                                  
  1695 00000BEC 86E0                            xchg ah, al 
  1696                                  	
  1697 00000BEE C3                      	retn	
  1698                                  	
  1699                                  
  1700                                  %include 'keyboard.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - keyboard.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 17/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; keyboard.inc (17/10/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - KEYBOARD.INC
    20                              <1> ; Last Modification: 17/10/2015
    21                              <1> ;		    (Keyboard Data is in 'KYBDATA.INC')	
    22                              <1> ;
    23                              <1> ; ///////// KEYBOARD FUNCTIONS (PROCEDURES) ///////////////
    24                              <1> 
    25                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
    26                              <1> 
    27                              <1> ; 03/12/2014
    28                              <1> ; 26/08/2014
    29                              <1> ; KEYBOARD I/O
    30                              <1> ; (INT_16h - Retro UNIX 8086 v1 - U9.ASM, 30/06/2014)
    31                              <1> 
    32                              <1> ;NOTE: 'k0' to 'k7' are name of OPMASK registers.
    33                              <1> ;	(The reason of using '_k' labels!!!) (27/08/2014)    
    34                              <1> ;NOTE: 'NOT' keyword is '~' unary operator in NASM.
    35                              <1> ;	('NOT LC_HC' --> '~LC_HC') (bit reversing operator)
    36                              <1> 
    37                              <1> int16h:	; 30/06/2015
    38                              <1> ;getc:
    39 00000BEF 9C                  <1> 	pushfd	; 28/08/2014
    40 00000BF0 0E                  <1> 	push 	cs
    41 00000BF1 E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
    42 00000BF6 C3                  <1> 	retn	
    43                              <1> 
    44                              <1> getc_int:
    45                              <1> 	; 28/02/2015
    46                              <1> 	; 03/12/2014 (derivation from pc-xt-286 bios source code -1986-, 
    47                              <1> 	;	      instead of pc-at bios - 1985-)
    48                              <1> 	; 28/08/2014 (_k1d)
    49                              <1> 	; 30/06/2014
    50                              <1> 	; 03/03/2014
    51                              <1> 	; 28/02/2014
    52                              <1> 	; Derived from "KEYBOARD_IO_1" procedure of IBM "pc-xt-286" 
    53                              <1> 	; rombios source code (21/04/1986)
    54                              <1> 	;	 'keybd.asm', INT 16H, KEYBOARD_IO
    55                              <1> 	;
    56                              <1> 	; KYBD --- 03/06/86  KEYBOARD BIOS
    57                              <1> 	;
    58                              <1> 	;--- INT 16 H -----------------------------------------------------------------
    59                              <1> 	; KEYBOARD I/O								      :
    60                              <1> 	;	THESE ROUTINES PROVIDE READ KEYBOARD SUPPORT			      :
    61                              <1> 	; INPUT									      :
    62                              <1> 	;	(AH)= 00H  READ THE NEXT ASCII CHARACTER ENTERED FROM THE KEYBOARD,   :
    63                              <1> 	;		   RETURN THE RESULT IN (AL), SCAN CODE IN (AH).              :
    64                              <1> 	;		   THIS IS THE COMPATIBLE READ INTERFACE, EQUIVALENT TO THE   :
    65                              <1> 	;                  STANDARD PC OR PCAT KEYBOARD				      :	
    66                              <1> 	;-----------------------------------------------------------------------------:
    67                              <1> 	;	(AH)= 01H  SET THE ZERO FLAG TO INDICATE IF AN ASCII CHARACTER IS     :
    68                              <1> 	;		   AVAILABLE TO BE READ FROM THE KEYBOARD BUFFER.	      :
    69                              <1> 	;		   (ZF)= 1 -- NO CODE AVAILABLE			              :
    70                              <1> 	;		   (ZF)= 0 -- CODE IS AVAILABLE  (AX)= CHARACTER              :
    71                              <1> 	;		   IF (ZF)= 0, THE NEXT CHARACTER IN THE BUFFER TO BE READ IS :
    72                              <1> 	;		   IN (AX), AND THE ENTRY REMAINS IN THE BUFFER.              :
    73                              <1> 	;		   THIS WILL RETURN ONLY PC/PCAT KEYBOARD COMPATIBLE CODES    :
    74                              <1> 	;-----------------------------------------------------------------------------:	
    75                              <1> 	;	(AH)= 02H  RETURN THE CURRENT SHIFT STATUS IN AL REGISTER             :
    76                              <1> 	;		   THE BIT SETTINGS FOR THIS CODE ARE INDICATED IN THE        :
    77                              <1> 	;		   EQUATES FOR @KB_FLAG		                              :
    78                              <1> 	;-----------------------------------------------------------------------------:	
    79                              <1> 	;	(AH)= 03H  SET TYPAMATIC RATE AND DELAY                               :
    80                              <1> 	;	      (AL) = 05H                                                      :
    81                              <1> 	;	      (BL) = TYPAMATIC RATE (BITS 5 - 7 MUST BE RESET TO 0)           :
    82                              <1> 	;		       							      :
    83                              <1> 	;                     REGISTER     RATE      REGISTER     RATE                :
    84                              <1> 	;                      VALUE     SELECTED     VALUE     SELECTED              :
    85                              <1> 	;                     --------------------------------------------            :
    86                              <1> 	;			00H        30.0        10H        7.5                 :
    87                              <1> 	;			01H        26.7        11H        6.7                 :
    88                              <1> 	;			02H        24.0        12H        6.0                 :
    89                              <1> 	;			03H        21.8        13H        5.5                 :
    90                              <1> 	;			04H        20.0        14H        5.0                 :
    91                              <1> 	;			05H        18.5        15H        4.6                 :
    92                              <1> 	;			06H        17.1        16H        4.3                 :
    93                              <1> 	;			07H        16.0        17H        4.0                 :
    94                              <1> 	;			08H        15.0        18H        3.7                 :
    95                              <1> 	;			09H        13.3        19H        3.3                 :
    96                              <1> 	;			0AH        12.0        1AH        3.0                 :
    97                              <1> 	;			0BH        10.9        1BH        2.7                 :
    98                              <1>         ;			0CH        10.0        1CH        2.5                 :
    99                              <1> 	;			0DH         9.2        1DH        2.3                 :
   100                              <1> 	;			0EH         8.6        1EH        2.1                 :
   101                              <1> 	;			0FH         8.0        1FH        2.0                 :
   102                              <1> 	;									      :
   103                              <1> 	;	      (BH) = TYPAMATIC DELAY  (BITS 2 - 7 MUST BE RESET TO 0)         :
   104                              <1> 	;		       							      :
   105                              <1> 	;                     REGISTER     DELAY                                      :
   106                              <1> 	;                      VALUE       VALUE                                      :
   107                              <1> 	;                     ------------------                                      :
   108                              <1> 	;			00H        250 ms                                     :
   109                              <1> 	;			01H        500 ms                                     :
   110                              <1> 	;			02H        750 ms                                     :
   111                              <1> 	;			03H       1000 ms                                     :
   112                              <1> 	;-----------------------------------------------------------------------------:
   113                              <1> 	;	(AH)= 05H  PLACE ASCII CHARACTER/SCAN CODE COMBINATION IN KEYBOARD    :
   114                              <1> 	;		   BUFFER AS IF STRUCK FROM KEYBOARD                          :
   115                              <1> 	;		   ENTRY:  (CL) = ASCII CHARACTER		              :
   116                              <1> 	;		           (CH) = SCAN CODE                                   :
   117                              <1> 	;		   EXIT:   (AH) = 00H = SUCCESSFUL OPERATION                  :
   118                              <1> 	;		           (AL) = 01H = UNSUCCESSFUL - BUFFER FULL            :
   119                              <1> 	;		   FLAGS:  CARRY IF ERROR                                     :
   120                              <1> 	;-----------------------------------------------------------------------------:		
   121                              <1> 	;	(AH)= 10H  EXTENDED READ INTERFACE FOR THE ENHANCED KEYBOARD,         :
   122                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=0                            :
   123                              <1> 	;-----------------------------------------------------------------------------:
   124                              <1> 	;	(AH)= 11H  EXTENDED ASCII STATUS FOR THE ENHANCED KEYBOARD,           :
   125                              <1> 	;		   OTHERWISE SAME AS FUNCTION AH=1                            :
   126                              <1> 	;-----------------------------------------------------------------------------:	
   127                              <1> 	;	(AH)= 12H  RETURN THE EXTENDED SHIFT STATUS IN AX REGISTER            :
   128                              <1> 	;		   AL = BITS FROM KB_FLAG, AH = BITS FOR LEFT AND RIGHT       :
   129                              <1> 	;		   CTL AND ALT KEYS FROM KB_FLAG_1 AND KB_FLAG_3              :
   130                              <1> 	; OUTPUT					                              :
   131                              <1> 	;	AS NOTED ABOVE, ONLY (AX) AND FLAGS CHANGED	                      :
   132                              <1> 	;	ALL REGISTERS RETAINED		                                      :
   133                              <1> 	;------------------------------------------------------------------------------
   134                              <1> 
   135                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   136                              <1> int32h:  ; Keyboard BIOS
   137                              <1> 
   138                              <1> KEYBOARD_IO_1:	
   139 00000BF7 FB                  <1> 	sti				; INTERRUPTS BACK ON
   140 00000BF8 1E                  <1> 	push	ds			; SAVE CURRENT DS
   141 00000BF9 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
   142                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
   143 00000BFA 66BB1000            <1>         mov     bx, KDATA 
   144 00000BFE 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
   145 00000C00 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
   146 00000C02 7439                <1> 	jz	short _K1		; ASCII_READ
   147 00000C04 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
   148 00000C06 7452                <1>         jz      short _K2               ; ASCII_STATUS
   149 00000C08 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
   150 00000C0A 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
   151 00000C10 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
   152 00000C12 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
   153 00000C18 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
   154 00000C1B 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
   155                              <1> _KIO1:	
   156 00000C21 80EC0B              <1> 	sub	ah, 11			; AH =  10H
   157 00000C24 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
   158 00000C26 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
   159 00000C28 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
   160 00000C2A FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
   161 00000C2C 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
   162                              <1> _KIO_EXIT:
   163                              <1> 	;pop	ecx			; RECOVER REGISTER
   164 00000C2E 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   165 00000C2F 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   166 00000C30 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
   167                              <1> 
   168                              <1> 	;-----	ASCII CHARACTER
   169                              <1> _K1E:	
   170 00000C31 E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
   171 00000C36 E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   172 00000C3B EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
   173                              <1> _K1:	
   174 00000C3D E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
   175 00000C42 E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   176 00000C47 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
   177                              <1> _K1A:
   178 00000C49 EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
   179                              <1> 
   180                              <1> 	;-----	ASCII STATUS
   181                              <1> _K2E:	
   182 00000C4B E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
   183 00000C50 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   184 00000C52 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   185 00000C53 E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   186 00000C58 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
   187                              <1> _K2:	
   188 00000C5A E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
   189 00000C5F 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   190 00000C61 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   191 00000C62 E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   192 00000C67 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
   193 00000C69 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
   194 00000C6A E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
   195 00000C6F EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
   196                              <1> _K2A:
   197 00000C71 9D                  <1> 	popf				; RESTORE ZF FROM TEST
   198                              <1> _K2B:
   199                              <1> 	;pop	ecx			; RECOVER REGISTER
   200 00000C72 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   201 00000C73 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   202 00000C74 CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
   203                              <1> 
   204                              <1> 	;-----	SHIFT STATUS
   205                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
   206 00000C77 8A25[92C80000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
   207 00000C7D 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
   208                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
   209                              <1> 	;shl	ah, cl			; BIT 7 POSITION
   210 00000C80 C0E405              <1>         shl	ah, 5
   211 00000C83 A0[92C80000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
   212 00000C88 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
   213 00000C8A 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
   214 00000C8C A0[94C80000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
   215 00000C91 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
   216 00000C93 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
   217                              <1> _K3:
   218 00000C95 A0[91C80000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
   219 00000C9A EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
   220                              <1> 
   221                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
   222                              <1> _K300:
   223 00000C9C 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
   224 00000C9E 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
   225 00000CA0 F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
   226 00000CA3 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
   227 00000CA5 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
   228 00000CA8 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
   229 00000CAA B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
   230 00000CAC E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   231                              <1> 	;mov	cx, 5			; SHIFT COUNT
   232                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
   233 00000CB1 C0E705              <1> 	shl	bh, 5
   234 00000CB4 88D8                <1> 	mov	al, bl			; PUT IN RATE
   235 00000CB6 08F8                <1> 	or	al, bh			; AND DELAY
   236 00000CB8 E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   237 00000CBD E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
   238                              <1> 
   239                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
   240                              <1> _K500:
   241 00000CC2 56                  <1> 	push	esi			; SAVE SI (esi)
   242 00000CC3 FA                  <1> 	cli				; 
   243 00000CC4 8B1D[A2C80000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
   244 00000CCA 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
   245 00000CCC E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
   246 00000CD1 3B1D[9EC80000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
   247 00000CD7 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
   248 00000CD9 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
   249 00000CDC 891D[A2C80000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
   250 00000CE2 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
   251 00000CE4 EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
   252                              <1> _K502:
   253 00000CE6 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
   254                              <1> _K504:
   255 00000CE8 FB                  <1> 	sti				
   256 00000CE9 5E                  <1> 	pop	esi			; RECOVER SI (esi)
   257 00000CEA E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
   258                              <1> 
   259                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
   260                              <1> _K1S:
   261 00000CEF FA                  <1> 	cli	; 03/12/2014
   262 00000CF0 8B1D[9EC80000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   263 00000CF6 3B1D[A2C80000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   264                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
   265 00000CFC 750F                <1> 	jne	short _k1x ; 03/12/2014
   266                              <1> 	;
   267                              <1> 	; 03/12/2014
   268                              <1> 	; 28/08/2014
   269                              <1> 	; PERFORM OTHER FUNCTION ?? here !
   270                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
   271                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
   272                              <1> _K1T:                                   ; ASCII READ
   273 00000CFE FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
   274 00000CFF 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
   275                              <1> _K1U:	
   276 00000D00 FA                  <1> 	cli				; INTERRUPTS BACK OFF
   277 00000D01 8B1D[9EC80000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   278 00000D07 3B1D[A2C80000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   279                              <1> _k1x:
   280 00000D0D 53                  <1> 	push	ebx			; SAVE ADDRESS		
   281 00000D0E 9C                  <1> 	pushf				; SAVE FLAGS
   282 00000D0F E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   283 00000D14 8A1D[93C80000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   284 00000D1A 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   285 00000D1C 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
   286 00000D1F 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
   287 00000D21 E8C9060000          <1> 	call	SND_LED1
   288 00000D26 FA                  <1> 	cli				; DISABLE INTERRUPTS
   289                              <1> _K1V:
   290 00000D27 9D                  <1> 	popf				; RESTORE FLAGS
   291 00000D28 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
   292 00000D29 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
   293                              <1> 	;
   294 00000D2B 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
   295 00000D2E E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
   296 00000D33 891D[9EC80000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
   297 00000D39 C3                  <1> 	retn				; RETURN
   298                              <1> 
   299                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
   300                              <1> _K2S:
   301 00000D3A FA                  <1> 	cli				; INTERRUPTS OFF
   302 00000D3B 8B1D[9EC80000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   303 00000D41 3B1D[A2C80000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
   304 00000D47 668B03              <1> 	mov	ax, [ebx]
   305 00000D4A 9C                  <1> 	pushf				; SAVE FLAGS
   306 00000D4B 6650                <1> 	push	ax			; SAVE CODE
   307 00000D4D E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   308 00000D52 8A1D[93C80000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   309 00000D58 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   310 00000D5A 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
   311 00000D5D 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
   312 00000D5F E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   313                              <1> _K2T:
   314 00000D64 6658                <1> 	pop	ax			; RESTORE CODE
   315 00000D66 9D                  <1> 	popf				; RESTORE FLAGS
   316 00000D67 FB                  <1> 	sti				; INTERRUPTS BACK ON
   317 00000D68 C3                  <1> 	retn				; RETURN
   318                              <1> 
   319                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
   320                              <1> _KIO_E_XLAT:
   321 00000D69 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   322 00000D6B 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
   323 00000D6D 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
   324 00000D6F 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
   325 00000D71 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
   326                              <1> _KIO_E_RET:				
   327 00000D73 C3                  <1> 	retn				; GO BACK
   328                              <1> 
   329                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
   330                              <1> _KIO_S_XLAT:
   331 00000D74 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
   332 00000D77 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
   333 00000D79 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
   334 00000D7B 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
   335 00000D7D 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
   336 00000D7F 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
   337 00000D81 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
   338                              <1> _kio_ret: ; 03/12/2014
   339 00000D83 F8                  <1> 	clc
   340 00000D84 C3                  <1> 	retn
   341                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   342                              <1> _KIO_S1:				
   343 00000D85 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
   344                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   345 00000D87 C3                  <1> 	retn
   346                              <1> _KIO_S2:		
   347 00000D88 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
   348 00000D8B 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
   349 00000D8D 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   350 00000D8F 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
   351 00000D91 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   352 00000D93 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
   353 00000D95 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
   354                              <1> _KIO_S3:
   355 00000D97 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
   356                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
   357 00000D99 75E8                <1> 	jne	short _kio_ret
   358 00000D9B 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   359 00000D9D 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
   360 00000D9F 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
   361                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
   362                              <1> _KIO_USE:
   363                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
   364 00000DA1 C3                  <1> 	retn				; RETURN	
   365                              <1> _KIO_DIS:
   366 00000DA2 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
   367 00000DA3 C3                  <1> 	retn				; RETURN
   368                              <1> 
   369                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
   370                              <1> _K4:    
   371 00000DA4 43                  <1> 	inc     ebx
   372 00000DA5 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
   373 00000DA6 3B1D[9AC80000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
   374                              <1>         ;jne    short _K5               ; NO, CONTINUE
   375 00000DAC 7206                <1> 	jb	short _K5
   376 00000DAE 8B1D[96C80000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
   377                              <1> _K5:
   378 00000DB4 C3                  <1> 	retn
   379                              <1> 
   380                              <1> ; 20/02/2015
   381                              <1> ; 05/12/2014
   382                              <1> ; 26/08/2014
   383                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
   384                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
   385                              <1> ;
   386                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
   387                              <1> ; rombios source code (06/10/1985)
   388                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
   389                              <1> 
   390                              <1> ; EQUATES (IBM PC-XT-286 BIOS, 1986, 'POSQEQU.INC')
   391                              <1> 
   392                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
   393                              <1> ENA_KBD		equ	0AEh		; ENABLE KEYBOARD COMMAND
   394                              <1> DIS_KBD		equ	0ADh		; DISABLE KEYBOARD COMMAND
   395                              <1> SHUT_CMD	equ	0FEh		; CAUSE A SHUTDOWN COMMAND
   396                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   397                              <1> STATUS_PORT	equ	064h		; 8042 STATUS PORT
   398                              <1> INPT_BUF_FULL	equ	00000010b 	; 1 = +INPUT BUFFER FULL
   399                              <1> PORT_A		equ	060h		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   400                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
   401                              <1> KB_ACK		equ	0FAh		; ACKNOWLEDGE PROM TRANSMISSION
   402                              <1> KB_RESEND	equ	0FEh		; RESEND REQUEST
   403                              <1> KB_OVER_RUN	equ	0FFh		; OVER RUN SCAN CODE
   404                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
   405                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
   406                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
   407                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
   408                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
   409                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
   410                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
   411                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
   412                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
   413                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
   414                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
   415                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
   416                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
   417                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
   418                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
   419                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
   420                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
   421                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
   422                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
   423                              <1> F11_M		equ	87		; F11 KEY MAKE
   424                              <1> F12_M		equ	88		; F12 KEY MAKE
   425                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
   426                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
   427                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
   428                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
   429                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
   430                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
   431                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
   432                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
   433                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
   434                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
   435                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
   436                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
   437                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
   438                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
   439                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
   440                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
   441                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
   442                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
   443                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
   444                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
   445                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
   446                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
   447                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
   448                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
   449                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
   450                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
   451                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
   452                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
   453                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
   454                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
   455                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
   456                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
   457                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
   458                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
   459                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
   460                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
   461                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
   462                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
   463                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
   464                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
   465                              <1> ;
   466                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
   467                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
   468                              <1> INTA00		equ	020h		; 8259 PORT
   469                              <1> 
   470                              <1> 
   471                              <1> kb_int:
   472                              <1> 
   473                              <1> ; 17/10/2015 ('ctrlbrk') 
   474                              <1> ; 05/12/2014
   475                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-)
   476                              <1> ; 26/08/2014
   477                              <1> ;
   478                              <1> ; 03/06/86  KEYBOARD BIOS
   479                              <1> ;
   480                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
   481                              <1> ;										;
   482                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
   483                              <1> ;										;
   484                              <1> ;--------------------------------------------------------------------------------
   485                              <1> 
   486                              <1> KB_INT_1:
   487 00000DB5 FB                  <1> 	sti				; ENABLE INTERRUPTS
   488                              <1> 	;push	ebp
   489 00000DB6 50                  <1> 	push	eax
   490 00000DB7 53                  <1> 	push	ebx
   491 00000DB8 51                  <1> 	push	ecx
   492 00000DB9 52                  <1> 	push	edx
   493 00000DBA 56                  <1> 	push	esi
   494 00000DBB 57                  <1> 	push	edi
   495 00000DBC 1E                  <1> 	push	ds
   496 00000DBD 06                  <1> 	push	es
   497 00000DBE FC                  <1> 	cld				; FORWARD DIRECTION
   498 00000DBF 66B81000            <1> 	mov	ax, KDATA
   499 00000DC3 8ED8                <1> 	mov	ds, ax
   500 00000DC5 8EC0                <1> 	mov	es, ax
   501                              <1> 	;
   502                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
   503 00000DC7 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
   504 00000DC9 E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
   505 00000DCE FA                  <1> 	cli				; DISABLE INTERRUPTS
   506 00000DCF B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
   507                              <1> KB_INT_01:
   508 00000DD4 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
   509 00000DD6 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
   510 00000DD8 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
   511                              <1> 	;
   512                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
   513 00000DDA E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
   514                              <1> 	;
   515                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
   516                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
   517                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
   518                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
   519                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
   520                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
   521                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
   522                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
   523                              <1> 	;
   524                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
   525                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
   526 00000DDC FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
   527 00000DDD 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
   528 00000DDF 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
   529                              <1> 	;
   530                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
   531 00000DE1 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
   532 00000DE3 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
   533                              <1> 	;
   534                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
   535 00000DE5 FA                  <1> 	cli				; DISABLE INTERRUPTS
   536 00000DE6 800D[93C80000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
   537 00000DED E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
   538                              <1> 	;
   539                              <1> 	;-----	RESEND THE LAST BYTE
   540                              <1> KB_INT_4:
   541 00000DF2 FA                  <1> 	cli				; DISABLE INTERRUPTS
   542 00000DF3 800D[93C80000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
   543 00000DFA E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
   544                              <1> 	;
   545                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
   546                              <1> KB_INT_2:
   547 00000DFF 6650                <1> 	push 	ax			; SAVE DATA IN
   548 00000E01 E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   549 00000E06 8A1D[93C80000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   550 00000E0C 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   551 00000E0E 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
   552 00000E11 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
   553 00000E13 E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   554                              <1> UP0:
   555 00000E18 6658                <1> 	pop	ax			; RESTORE DATA IN
   556                              <1> ;------------------------------------------------------------------------
   557                              <1> ;	START OF KEY PROCESSING						;
   558                              <1> ;------------------------------------------------------------------------
   559 00000E1A 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
   560                              <1> 	;
   561                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
   562 00000E1C 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
   563 00000E1E 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
   564                              <1> 	;
   565                              <1> K16:	
   566 00000E24 8A3D[94C80000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
   567                              <1> 	;
   568                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
   569 00000E2A F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
   570 00000E2D 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
   571 00000E2F 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
   572 00000E31 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
   573 00000E33 7507                <1> 	jne	short RST_RD_ID
   574 00000E35 800D[94C80000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   575                              <1> RST_RD_ID:
   576 00000E3C 8025[94C80000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
   577                              <1>         ;jmp    short ID_EX		; AND EXIT
   578 00000E43 E924020000          <1> 	jmp	K26
   579                              <1> 	;
   580                              <1> TST_ID_2:
   581 00000E48 8025[94C80000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
   582 00000E4F 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
   583 00000E51 7419                <1>         je	short KX_BIT		; JUMP IF SO
   584 00000E53 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
   585                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
   586 00000E55 0F8511020000        <1> 	jne	K26
   587                              <1> 	;
   588                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
   589 00000E5B F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
   590 00000E5E 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
   591 00000E60 800D[91C80000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
   592 00000E67 E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
   593                              <1> KX_BIT:
   594 00000E6C 800D[94C80000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
   595 00000E73 E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
   596                              <1> 	;
   597                              <1> NOT_ID:
   598 00000E78 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
   599 00000E7A 750C                <1> 	jne	short TEST_E1
   600 00000E7C 800D[94C80000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
   601                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
   602 00000E83 E9EB010000          <1> 	jmp	K26A	
   603                              <1> TEST_E1:	
   604 00000E88 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
   605 00000E8A 750C                <1> 	jne	short NOT_HC
   606 00000E8C 800D[94C80000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
   607 00000E93 E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
   608                              <1> 	;
   609                              <1> NOT_HC:
   610 00000E98 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
   611 00000E9A F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
   612 00000E9D 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
   613                              <1> 	;
   614 00000E9F BF[7EC70000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
   615 00000EA4 AE                  <1> 	scasb
   616 00000EA5 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
   617 00000EAB AE                  <1> 	scasb
   618 00000EAC 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
   619                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
   620 00000EAE E9B9010000          <1> 	jmp	K26
   621                              <1> 	;
   622                              <1> NOT_LC_E0:
   623 00000EB3 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
   624 00000EB6 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
   625 00000EB8 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
   626 00000EBD BF[7CC70000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
   627 00000EC2 F2AE                <1> 	repne	scasb			; CHECK IT
   628                              <1> 	;je	short EXIT		; THROW AWAY IF SO
   629 00000EC4 0F84A9010000        <1> 	je	K26A			
   630                              <1> 	;
   631 00000ECA 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
   632                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
   633 00000ECC 0F859A010000        <1> 	jne	K26
   634 00000ED2 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
   635                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
   636 00000ED5 0F8591010000        <1> 	jnz	K26
   637                              <1>         ; 20/02/2015 
   638 00000EDB F605[92C80000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
   639                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
   640 00000EE2 0F8584010000        <1> 	jnz	K26
   641 00000EE8 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
   642                              <1> 	;
   643                              <1> 	;-----	TEST FOR SYSTEM KEY
   644                              <1> T_SYS_KEY:
   645 00000EED 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
   646 00000EEF 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
   647                              <1> 	;
   648 00000EF1 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
   649 00000EF4 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
   650                              <1> 	;
   651 00000EF6 F605[92C80000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
   652                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
   653 00000EFD 0F8569010000        <1> 	jnz     K26			
   654                              <1> 	;
   655 00000F03 800D[92C80000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
   656 00000F0A B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   657 00000F0C E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   658                              <1> 					; INTERRUPT-RETURN-NO-EOI
   659 00000F0E B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   660 00000F10 E862040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   661                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
   662                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
   663                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   664                              <1> 	;INT	15H			; USER INTERRUPT	
   665 00000F15 E965010000          <1>         jmp     K27A                    ; END PROCESSING
   666                              <1> 	;
   667                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
   668                              <1> 	;
   669                              <1> K16C:
   670 00000F1A 8025[92C80000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
   671 00000F21 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   672 00000F23 E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
   673                              <1> 					; INTERRUPT-RETURN-NO-EOI
   674                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   675                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
   676                              <1> 	;
   677                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
   678                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   679                              <1> 	;INT	15H			; USER INTERRUPT
   680                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
   681                              <1> 	;
   682 00000F25 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
   683                              <1> 	;
   684                              <1> 	;-----	TEST FOR SHIFT KEYS
   685                              <1> K16A:
   686 00000F2A 8A1D[91C80000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   687 00000F30 BF[78C70000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
   688 00000F35 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
   689 00000F3A F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
   690 00000F3C 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
   691 00000F3E 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
   692                              <1> 	;
   693                              <1> 	;------	SHIFT KEY FOUND
   694                              <1> K17:
   695 00000F44 81EF[79C70000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   696 00000F4A 8AA7[80C70000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
   697 00000F50 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
   698 00000F52 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
   699 00000F54 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
   700                              <1> 	;
   701                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
   702                              <1> K17C:
   703 00000F5A 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
   704 00000F5D 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
   705                              <1> 	;
   706                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
   707 00000F5F 0825[91C80000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
   708 00000F65 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
   709                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
   710 00000F67 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
   711                              <1> K17D:
   712 00000F6D F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
   713 00000F70 740B                <1> 	jz 	short K17E		; NO, JUMP
   714 00000F72 0825[94C80000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
   715 00000F78 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
   716                              <1> K17E:
   717 00000F7D D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
   718 00000F7F 0825[92C80000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
   719 00000F85 E9E2000000          <1> 	jmp	K26
   720                              <1> 	;
   721                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
   722                              <1> K18:					; SHIFT-TOGGLE
   723 00000F8A F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
   724                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
   725 00000F8D 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
   726                              <1> K18A:
   727 00000F93 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
   728 00000F95 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
   729 00000F97 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
   730                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
   731 00000F9A 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
   732                              <1> K18B:
   733 00000FA0 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
   734 00000FA3 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
   735                              <1> K19:	
   736 00000FA5 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
   737 00000FA8 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
   738 00000FAA F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
   739 00000FAD 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
   740                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
   741 00000FAF 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
   742 00000FB1 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
   743                              <1> K21:					; MIGHT BE NUMERIC
   744 00000FB6 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
   745 00000FB9 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
   746                              <1> 	;
   747                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
   748 00000FBB 8425[92C80000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
   749 00000FC1 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
   750                              <1> K22A:
   751 00000FC7 0825[92C80000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   752 00000FCD 3025[91C80000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
   753                              <1> 	;
   754                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
   755 00000FD3 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
   756 00000FD6 7409                <1> 	jz	short K22B		; GO IF NOT
   757                              <1> 	;
   758 00000FD8 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
   759 00000FDA E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
   760 00000FDF 6658                <1> 	pop	ax			; RESTORE SCAN CODE
   761                              <1> K22B:
   762 00000FE1 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
   763 00000FE3 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
   764 00000FE9 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
   765 00000FEB E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
   766                              <1> 	;
   767                              <1> 	;-----	BREAK SHIFT FOUND
   768                              <1> K23:					; BREAK-SHIFT-FOUND
   769 00000FF0 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
   770 00000FF3 F6D4                <1> 	not	ah			; INVERT MASK
   771 00000FF5 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
   772 00000FF7 2025[91C80000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
   773 00000FFD 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
   774 00001000 7730                <1> 	ja	short K23D		; NO, ALL DONE
   775                              <1> 	;
   776 00001002 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
   777 00001005 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
   778 00001007 2025[94C80000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
   779 0000100D EB08                <1> 	jmp	short K23B		; CONTINUE
   780                              <1> K23A:
   781 0000100F D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
   782 00001011 2025[92C80000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
   783                              <1> K23B:
   784 00001017 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
   785 00001019 A0[94C80000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
   786 0000101E D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
   787 00001020 0A05[92C80000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
   788 00001026 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
   789 00001028 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
   790 0000102A 0805[91C80000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
   791 00001030 88E0                <1> 	mov	al, ah
   792                              <1> K23D:
   793 00001032 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
   794 00001034 7536                <1> 	jne	short K26		; INTERRUPT RETURN
   795                              <1> 	;	
   796                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
   797 00001036 A0[95C80000]        <1> 	mov	al, [ALT_INPUT]
   798 0000103B B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   799 0000103D 8825[95C80000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
   800 00001043 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
   801 00001045 7425                <1> 	je	short K26		; INTERRUPT_RETURN
   802                              <1>         ; 29/01/2016
   803                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
   804 00001047 E9D0020000          <1> 	jmp	_K60
   805                              <1> 	;
   806                              <1> K24:					; BREAK-TOGGLE
   807 0000104C 2025[92C80000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
   808 00001052 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
   809                              <1> 	;
   810                              <1> 	;-----	TEST FOR HOLD STATE
   811                              <1> 					; AL, AH = SCAN CODE
   812                              <1> K25:					; NO-SHIFT-FOUND
   813 00001054 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
   814 00001056 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
   815 00001058 F605[92C80000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
   816 0000105F 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
   817 00001061 3C45                <1> 	cmp	al, NUM_KEY
   818 00001063 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
   819 00001065 8025[92C80000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   820                              <1> 	;
   821                              <1> K26:
   822 0000106C 8025[94C80000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
   823                              <1> K26A:					; INTERRUPT-RETURN
   824 00001073 FA                  <1> 	cli				; TURN OFF INTERRUPTS
   825 00001074 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   826 00001076 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   827                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
   828 00001078 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   829 0000107A E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   830                              <1> K27A:
   831 0000107F FA                  <1> 	cli				; DISABLE INTERRUPTS
   832 00001080 07                  <1> 	pop	es			; RESTORE REGISTERS
   833 00001081 1F                  <1> 	pop	ds
   834 00001082 5F                  <1> 	pop	edi
   835 00001083 5E                  <1> 	pop	esi
   836 00001084 5A                  <1> 	pop	edx
   837 00001085 59                  <1> 	pop	ecx
   838 00001086 5B                  <1> 	pop	ebx
   839 00001087 58                  <1> 	pop	eax
   840                              <1> 	;pop	ebp
   841 00001088 CF                  <1> 	iret				; RETURN
   842                              <1> 
   843                              <1> 	;-----	NOT IN	HOLD STATE
   844                              <1> K28:					; NO-HOLD-STATE
   845 00001089 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
   846 0000108B 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
   847                              <1> 	;
   848 0000108D F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
   849                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
   850 00001090 0F84F1000000        <1>         jz      K38
   851                              <1> 	;
   852 00001096 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
   853 00001099 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
   854                              <1> 	 ;28/02/2015
   855 0000109B F605[92C80000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
   856                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
   857 000010A2 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
   858                              <1>         ;				; DUE TO PRESSING SYSREQ	
   859                              <1> ;K28A:	jmp	short K38
   860                              <1> 	;
   861                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
   862                              <1> K29:					; TEST-RESET
   863 000010A8 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
   864 000010AB 740B                <1> 	jz	short K31		; NO_RESET
   865 000010AD 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
   866 000010AF 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
   867                              <1> 	;
   868                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
   869                              <1>  	; 26/08/2014
   870                              <1> cpu_reset:
   871                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
   872                              <1> 	; Send FEh (system reset command) to the keyboard controller.
   873 000010B1 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
   874 000010B3 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
   875                              <1> khere:
   876 000010B5 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
   877 000010B6 EBFD                <1> 	jmp 	short khere		; INSURE HALT
   878                              <1> 
   879                              <1> 	;
   880                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
   881                              <1> K31:					; NO-RESET
   882 000010B8 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
   883 000010BA 7507                <1> 	jne	short K311		; NOT THERE
   884 000010BC B020                <1> 	mov	al, ' '			; SET SPACE CHAR
   885 000010BE E948020000          <1>         jmp     K57                     ; BUFFER_FILL
   886                              <1> K311:
   887 000010C3 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
   888 000010C5 7509                <1> 	jne	short K312		; NOT THERE
   889 000010C7 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
   890 000010CB E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
   891                              <1> K312:
   892 000010D0 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
   893 000010D2 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
   894 000010D8 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
   895 000010DA 0F849A000000        <1>         je      K37B                    ; GO PROCESS
   896                              <1> 	;
   897                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
   898                              <1> K32:					; ALT-KEY-PAD
   899 000010E0 BF[54C70000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
   900 000010E5 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
   901 000010EA F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
   902 000010EC 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
   903 000010EE F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
   904 000010F1 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
   905 000010F7 81EF[55C70000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   906 000010FD A0[95C80000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
   907 00001102 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
   908 00001104 F6E4                <1> 	mul	ah
   909 00001106 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
   910 00001109 A2[95C80000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
   911                              <1> ;K32A:
   912 0000110E E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
   913                              <1> 	;
   914                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
   915                              <1> K33:					; NO-ALT-KEYPAD
   916 00001113 C605[95C80000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
   917 0000111A B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
   918 0000111F F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
   919 00001121 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
   920                              <1> 	;
   921                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
   922                              <1> K34:					; ALT-TOP-ROW
   923 00001123 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
   924 00001125 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
   925 00001127 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
   926 00001129 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
   927 0000112B 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
   928 0000112E EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   929                              <1> 	;
   930                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
   931                              <1> K35:					; ALT-FUNCTION
   932 00001130 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
   933 00001132 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
   934 00001134 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
   935 00001136 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
   936 00001138 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
   937 0000113B EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   938                              <1> K35A:
   939 0000113D F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
   940 00001140 7422                <1> 	jz	short K37		; NO, JUMP
   941 00001142 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
   942 00001144 7509                <1>         jne     short K35B              ; NOT THERE
   943 00001146 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
   944 0000114A E9BC010000          <1> 	jmp	K57			; BUFFER FILL
   945                              <1> K35B:
   946 0000114F 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
   947 00001151 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
   948 00001153 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
   949                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
   950 00001155 0F8511FFFFFF        <1>         jne     K26
   951 0000115B 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
   952 0000115F E9A7010000          <1> 	jmp	K57			; BUFFER FILL
   953                              <1> K37:
   954 00001164 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
   955 00001166 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
   956 00001168 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
   957                              <1>         ;ja	short K32A		; IF SO, IGNORE
   958 0000116A 0F87FCFEFFFF        <1>         ja      K26
   959 00001170 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
   960                              <1> K37A:
   961 00001173 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
   962 00001175 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
   963                              <1> K37B:
   964 0000117A B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
   965 0000117C E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
   966                              <1> K37C:
   967 00001181 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
   968 00001183 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
   969 00001185 EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
   970                              <1> 	;
   971                              <1> 	;-----	NOT IN ALTERNATE SHIFT
   972                              <1> K38:					; NOT-ALT-SHIFT
   973                              <1> 					; BL STILL HAS SHIFT FLAGS
   974 00001187 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
   975                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
   976 0000118A 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
   977                              <1> 	;
   978                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
   979                              <1> 	;-----	TEST FOR BREAK
   980                              <1> K38A:
   981 00001190 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
   982 00001192 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
   983 00001194 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
   984 00001197 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
   985 00001199 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
   986 0000119C 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
   987                              <1> K38B:
   988 0000119E 8B1D[9EC80000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
   989 000011A4 891D[A2C80000]      <1> 	mov	[BUFFER_TAIL], ebx
   990 000011AA C605[90C80000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
   991                              <1> 	;
   992                              <1> 	;-----	ENABLE KEYBOARD
   993 000011B1 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
   994 000011B3 E8BF010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   995                              <1> 	;
   996                              <1> 	; CTRL+BREAK code here !!!
   997                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
   998                              <1> 	; 17/10/2015	
   999 000011B8 E8DA2D0000          <1> 	call	ctrlbrk ; control+break subroutine
  1000                              <1> 	;
  1001 000011BD 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  1002 000011C0 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  1003                              <1> 	;
  1004                              <1> 	;-----	TEST FOR PAUSE
  1005                              <1> K39:					; NO_BREAK
  1006 000011C5 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1007 000011C8 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  1008 000011CA 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  1009 000011CC 7533                <1> 	jne	short K41		; NO-PAUSE
  1010                              <1> K39P:
  1011 000011CE 800D[92C80000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  1012                              <1> 	;
  1013                              <1> 	;-----	ENABLE KEYBOARD
  1014 000011D5 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1015 000011D7 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1016                              <1> K39A:
  1017 000011DC B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  1018 000011DE E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  1019                              <1> 	;
  1020                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  1021 000011E0 803D[C6C80000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  1022 000011E7 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  1023 000011E9 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  1024 000011ED A0[C7C80000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  1025 000011F2 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  1026                              <1> 	;
  1027                              <1> K40:					; PAUSE-LOOP
  1028 000011F3 F605[92C80000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  1029 000011FA 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  1030                              <1> 	;
  1031 000011FC E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  1032                              <1>         ;
  1033                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  1034                              <1> K41:					; NO-PAUSE
  1035 00001201 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  1036 00001203 7513                <1> 	jne	short K42		; NOT-KEY-55
  1037 00001205 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1038 00001208 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  1039 0000120A F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1040 0000120D 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  1041                              <1> K41A:	
  1042 0000120F 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  1043 00001213 E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  1044                              <1> 	;
  1045                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  1046                              <1> K42:					; NOT-KEY-55
  1047 00001218 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  1048 0000121A 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  1049 0000121C 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  1050 0000121E 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  1051 00001220 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  1052 00001223 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  1053 00001225 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  1054 00001229 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  1055                              <1> K42A: 
  1056                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1057 0000122E 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  1058                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  1059                              <1> 	;;jb	K56 ; 20/02/2015
  1060                              <1> 	;;jmp	K64 ; 20/02/2015
  1061                              <1> K42B:
  1062 00001230 BB[88C70000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1063 00001235 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  1064 0000123B E9B9000000          <1> 	jmp	K64	
  1065                              <1>         ;
  1066                              <1> 	;-----	NOT IN CONTROL SHIFT
  1067                              <1> K44:					; NOT-CTL-SHIFT
  1068 00001240 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  1069 00001242 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  1070 00001244 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  1071 00001247 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  1072 00001249 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  1073 0000124C 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  1074 0000124E EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1075                              <1> K44A:
  1076 00001250 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  1077 00001253 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1078                              <1> 	;
  1079                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  1080                              <1> K44B:
  1081 00001255 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1082 00001257 E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1083 0000125C B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  1084 0000125E E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  1085                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  1086                              <1> 	;PUSH 	BP			; SAVE POINTER
  1087                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  1088                              <1> 	;POP	BP			; RESTORE POINTER
  1089 00001260 8025[94C80000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  1090 00001267 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  1091                              <1> 	;
  1092                              <1> 	;-----	HANDLE IN-CORE KEYS
  1093                              <1> K45:					; NOT-PRINT-SCREEN
  1094 0000126C 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  1095 0000126E 7734                <1> 	ja	short K46		; JUMP IF NOT
  1096 00001270 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  1097 00001272 7505                <1> 	jne	short K45A		; NO, JUMP
  1098 00001274 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  1099 00001277 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  1100                              <1> K45A:
  1101 00001279 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  1102 0000127E BF[5EC70000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  1103 00001283 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  1104                              <1> 		; 20/02/2015
  1105 00001285 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  1106                              <1> 	;
  1107 00001287 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  1108 0000128A 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  1109                              <1> K45B:
  1110 0000128C F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1111 0000128F 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  1112                              <1> 					; NO, LOWERCASE
  1113                              <1> K45C:
  1114 00001291 BB[E0C70000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  1115 00001296 EB51                <1> 	jmp	short K56	
  1116                              <1> K45D:					; ALMOST-CAPS-STATE
  1117 00001298 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  1118 0000129B 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  1119                              <1> K45E:
  1120 0000129D BB[38C80000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  1121 000012A2 EB45                <1> K45F:	jmp	short K56
  1122                              <1> 	;
  1123                              <1> 	;-----	TEST FOR KEYS F1 - F10
  1124                              <1> K46:					; NOT IN-CORE AREA
  1125 000012A4 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  1126                              <1> 	;ja	short K47		; JUMP IF NOT
  1127                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  1128 000012A6 7635                <1> 	jna	short K53		
  1129                              <1> 	;
  1130                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  1131                              <1> K47:					; NOT F1 - F10
  1132 000012A8 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  1133 000012AA 772D                <1> 	ja	short K52		; JUMP IF NOT
  1134                              <1> 	;
  1135                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  1136                              <1> K48:
  1137 000012AC 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  1138 000012AE 74ED                <1> 	je	short K45E		; GO TRANSLATE
  1139 000012B0 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  1140 000012B2 74E9                <1> 	je	short K45E		; GO TRANSLATE
  1141 000012B4 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  1142 000012B7 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  1143                              <1> 	;		
  1144 000012B9 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  1145 000012BC 7514                <1> 	jnz	short K50		; TEST FOR SURE
  1146 000012BE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1147                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  1148 000012C1 75DA                <1> 	jnz	short K45E
  1149                              <1> 	;
  1150                              <1> 	;-----	BASE CASE FOR KEYPAD
  1151                              <1> K49:					
  1152 000012C3 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  1153 000012C5 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  1154 000012C7 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  1155 000012C9 EB40                <1> 	jmp	short K57		; BUFFER FILL
  1156                              <1> K49A:
  1157 000012CB BB[E0C70000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  1158 000012D0 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  1159                              <1> 	;
  1160                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  1161                              <1> K50:					; ALMOST-NUM-STATE
  1162 000012D2 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  1163 000012D5 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  1164 000012D7 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  1165                              <1> 	;
  1166                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  1167                              <1> K52:					; NOT A NUMPAD KEY
  1168 000012D9 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  1169                              <1> 	;jne	short K53		; JUMP IF NOT
  1170                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  1171 000012DB 74AF                <1> 	je	short K45B		
  1172                              <1> 	;
  1173                              <1> 	;-----	MUST BE F11 OR F12 
  1174                              <1> K53:					; F1 - F10 COME HERE, TOO
  1175 000012DD F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  1176 000012E0 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  1177                              <1> 		; 20/02/2015 
  1178 000012E2 BB[38C80000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  1179 000012E7 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  1180                              <1> 	;
  1181                              <1> 	;-----	TRANSLATE THE CHARACTER
  1182                              <1> K56:					; TRANSLATE-CHAR
  1183 000012E9 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1184 000012EB D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  1185 000012EC F605[94C80000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1186 000012F3 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1187 000012F5 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  1188 000012F7 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  1189                              <1> 	;
  1190                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  1191                              <1> K64:					; TRANSLATE-SCAN-ORGD
  1192 000012F9 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1193 000012FB D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  1194 000012FC 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  1195 000012FE B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  1196 00001300 F605[94C80000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1197 00001307 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1198 00001309 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  1199                              <1> 	;
  1200                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  1201                              <1> K57:					; BUFFER_FILL
  1202 0000130B 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  1203                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  1204 0000130D 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  1205 00001313 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  1206                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  1207 00001316 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  1208                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  1209                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  1210                              <1> 
  1211                              <1> _K60: ; 29/01/2016
  1212 0000131C 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  1213 0000131F 721F                <1> 	jb	short K61
  1214 00001321 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  1215 00001324 771A                <1> 	ja	short K61
  1216                              <1> 	;
  1217 00001326 8A1D[08CF0000]      <1> 	mov	bl, [ACTIVE_PAGE]
  1218 0000132C 80C368              <1> 	add	bl, 68h
  1219 0000132F 38E3                <1> 	cmp	bl, ah
  1220 00001331 740D                <1> 	je	short K61
  1221 00001333 6650                <1> 	push	ax
  1222 00001335 88E0                <1> 	mov	al, ah
  1223 00001337 2C68                <1> 	sub	al, 68h
  1224 00001339 E85E020000          <1> 	call	set_active_page
  1225 0000133E 6658                <1> 	pop	ax
  1226                              <1> K61:					; NOT-CAPS-STATE
  1227 00001340 8B1D[A2C80000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  1228 00001346 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  1229 00001348 E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  1230 0000134D 3B1D[9EC80000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  1231 00001353 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  1232 00001355 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  1233 00001358 891D[A2C80000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  1234 0000135E E909FDFFFF          <1> 	jmp	K26
  1235                              <1> 	;;cli				; TURN OFF INTERRUPTS
  1236                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  1237                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  1238                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1239                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  1240                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  1241                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  1242                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  1243                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  1244                              <1> 	;;jmp   K27                    
  1245                              <1> 	;
  1246                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  1247                              <1> K62:
  1248 00001363 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  1249 00001365 E620                <1> 	out	INTA00, al
  1250 00001367 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  1251 0000136B B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  1252 0000136D E83A050000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  1253 00001372 E901FDFFFF          <1> 	jmp     K27			; EXIT   
  1254                              <1> 
  1255                              <1> SHIP_IT:
  1256                              <1> 	;---------------------------------------------------------------------------------
  1257                              <1> 	; SHIP_IT
  1258                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1259                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  1260                              <1> 	;---------------------------------------------------------------------------------
  1261                              <1> 	;
  1262 00001377 6650                <1> 	push	ax			; SAVE DATA TO SEND
  1263                              <1> 
  1264                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  1265 00001379 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  1266                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  1267 0000137A B900000100          <1> 	mov	ecx, 10000h			
  1268                              <1> S10:
  1269 0000137F E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  1270 00001381 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  1271 00001383 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  1272                              <1> 
  1273 00001385 6658                <1> 	pop	ax			; GET DATA TO SEND
  1274 00001387 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  1275 00001389 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  1276 0000138A C3                  <1> 	retn				; RETURN TO CALLER
  1277                              <1> 
  1278                              <1> SND_DATA:
  1279                              <1> 	; ---------------------------------------------------------------------------------
  1280                              <1> 	; SND_DATA
  1281                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1282                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  1283                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  1284                              <1> 	; ---------------------------------------------------------------------------------
  1285                              <1> 	;
  1286 0000138B 6650                <1> 	push	ax			; SAVE REGISTERS
  1287 0000138D 6653                <1> 	push	bx
  1288 0000138F 51                  <1> 	push	ecx
  1289 00001390 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  1290 00001392 B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  1291                              <1> SD0:
  1292 00001394 FA                  <1> 	cli				; DISABLE INTERRUPTS
  1293 00001395 8025[93C80000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  1294                              <1> 	;
  1295                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  1296 0000139C B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  1297                              <1> SD5:
  1298 000013A1 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  1299 000013A3 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  1300 000013A5 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  1301                              <1> 	;
  1302 000013A7 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  1303 000013A9 E660                <1> 	out	PORT_A, al		; SEND BYTE
  1304 000013AB FB                  <1> 	sti				; ENABLE INTERRUPTS
  1305                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  1306 000013AC B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  1307                              <1> SD1:
  1308 000013B1 F605[93C80000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  1309 000013B8 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  1310 000013BA E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  1311                              <1> SD2:
  1312 000013BC FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  1313 000013BE 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  1314 000013C0 800D[93C80000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  1315 000013C7 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  1316                              <1> SD3:
  1317 000013C9 F605[93C80000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  1318 000013D0 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  1319                              <1> SD4:	
  1320 000013D2 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  1321 000013D3 665B                <1> 	pop	bx
  1322 000013D5 6658                <1> 	pop	ax
  1323 000013D7 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  1324                              <1> 
  1325                              <1> SND_LED:
  1326                              <1> 	; ---------------------------------------------------------------------------------
  1327                              <1> 	; SND_LED
  1328                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  1329                              <1> 	;
  1330                              <1> 	;----------------------------------------------------------------------------------
  1331                              <1> 	;
  1332 000013D8 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1333 000013D9 F605[93C80000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1334 000013E0 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1335                              <1> 	;
  1336 000013E2 800D[93C80000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1337 000013E9 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  1338 000013EB E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  1339 000013ED EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  1340                              <1> SND_LED1:
  1341 000013EF FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1342 000013F0 F605[93C80000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1343 000013F7 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1344                              <1> 	;
  1345 000013F9 800D[93C80000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1346                              <1> SL0:
  1347 00001400 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  1348 00001402 E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1349 00001407 FA                  <1> 	cli
  1350 00001408 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  1351 0000140D 8025[93C80000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1352 00001414 0805[93C80000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1353 0000141A F605[93C80000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1354 00001421 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  1355                              <1> 	;
  1356 00001423 E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1357 00001428 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1358 00001429 F605[93C80000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1359 00001430 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  1360                              <1> SL2:
  1361 00001432 B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  1362 00001434 E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1363 00001439 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1364                              <1> SL3:
  1365 0000143A 8025[93C80000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  1366                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  1367 00001441 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1368 00001442 C3                  <1> 	retn				; RETURN TO CALLER
  1369                              <1> 
  1370                              <1> MAKE_LED:
  1371                              <1> 	;---------------------------------------------------------------------------------
  1372                              <1> 	; MAKE_LED
  1373                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  1374                              <1> 	;	THE MODE INDICATORS.
  1375                              <1> 	;---------------------------------------------------------------------------------
  1376                              <1> 	;
  1377                              <1> 	;push 	cx			; SAVE CX
  1378 00001443 A0[91C80000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  1379 00001448 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  1380                              <1> 	;mov	cl, 4			; SHIFT COUNT
  1381                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  1382 0000144A C0C004              <1> 	rol	al, 4 ; 20/02/2015
  1383 0000144D 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  1384                              <1> 	;pop	cx
  1385 0000144F C3                  <1> 	retn				; RETURN TO CALLER
  1386                              <1> 
  1387                              <1> ; % include 'kybdata.s'   ; KEYBOARD DATA
  1388                              <1> 
  1389                              <1> 
  1390                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  1701                                  
  1702                                  %include 'video.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - video.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; video.inc (13/08/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
    20                              <1> ; Last Modification: 13/08/2015
    21                              <1> ;		  (Video Data is in 'VIDATA.INC')
    22                              <1> ;
    23                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
    24                              <1> 
    25                              <1> ; 16/01/2016 (32 bit modifications, TRDOS386 - TRDOS v2.0, video.s)
    26                              <1> ; INT 32H (TRDOS 386) = INT 10H (IBM PC/AT REAL MODE)
    27                              <1> 
    28                              <1> ; IBM PC-AT BIOS Source Code
    29                              <1> ; TITLE VIDEO1 --- 06/10/85  VIDEO DISPLAY BIOS
    30                              <1> 
    31                              <1> int10h:
    32                              <1> 	; 23/03/2016
    33                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
    34 00001450 9C                  <1> 	pushfd
    35 00001451 0E                  <1> 	push 	cs
    36 00001452 E851000000          <1> 	call 	VIDEO_IO_1
    37 00001457 C3                  <1> 	retn
    38                              <1> 
    39                              <1> ;--- INT 10 H -------------------------------------------------------------------
    40                              <1> ; VIDEO_IO									:	
    41                              <1> ;	THESE ROUTINES PROVIDE THE CRT DISPLAY INTERFACE			:
    42                              <1> ;	THE FOLLOWING FUNCTIONS ARE PROVIDED:					:
    43                              <1> ;										:
    44                              <1> ;    (AH)= 00H	SET MODE (AL) CONTAINS MODE VALUE				:
    45                              <1> ;		(AL) = 00H  40X25 BW MODE (POWER ON DEFAULT)			:
    46                              <1> ;		(AL) = 01H  40X25 COLOR						:
    47                              <1> ;		(AL) = 02H  80X25 BW						:
    48                              <1> ;		(AL) = 03H  80X25 COLOR						:
    49                              <1> ;		              GRAPHICS MODES					:
    50                              <1> ;		(AL) = 04H  320X200 COLOR					:
    51                              <1> ;		(AL) = 05H  320X200 BW MODE					:
    52                              <1> ;		(AL) = 06H  640X200 BW MODE					:
    53                              <1> ;		(AL) = 07H   80X25 MONOCHROME (USED INTERNAL TO VIDEO ONLY)	:
    54                              <1> ;		*** NOTES -BW MODES OPERATE SAME AS COLOR MODES, BUT COLOR	:
    55                              <1> ;		           BURST IS NOT ENABLED					:
    56                              <1> ;		          -CURSOR IS NOT DISPLAYED IN GRAPHICS MODE		:
    57                              <1> ;    (AH)= 01H	SET CURSOR TYPE							:
    58                              <1> ;		(CH) = BITS 4-0 = START LINE FOR CURSOR				:
    59                              <1> ;		       ** HARDWARE WILL ALWAYS CAUSE BLINK			:
    60                              <1> ;		       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING	:
    61                              <1> ;		          OR NO CURSOR AT ALL					:
    62                              <1> ;		(CL) = BITS 4-0 = END LINE FOR CURSOR				:
    63                              <1> ;    (AH)= 02H	SET CURSOR POSITION						:
    64                              <1> ;		(DH,DL) = ROW,COLUMN  (00H,00H) IS UPPER LEFT			:
    65                              <1> ;		(BH) = A PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
    66                              <1> ;    (AH)= 03H	READ CURSOR POSITION						:
    67                              <1> ;		(BH) = PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
    68                              <1> ;		ON EXIT (DH,DL) = ROW,COLUMN OF CURRENT CURSOR			:
    69                              <1> ;		        (CH,CL) = CURSOR MODE CURRENTLY SET			:
    70                              <1> ;    (AH)= 04H	READ LIGHT PEN POSITION						:
    71                              <1> ;		ON EXIT:							:
    72                              <1> ;		(AH) = 00H -- LIGHT PEN SWITCH NOT DOWN/NOT TRIGGERED		:
    73                              <1> ;		(AH) = 01H -- VALID LIGHT PEN VALUE IN REGISTERS		:
    74                              <1> ;		        (DH,DL) = ROW,COLUMN OF CHARACTER LP POSITION		:
    75                              <1> ;		        (CH) = RASTER LINE (0-199)				:
    76                              <1> ;		        (BX) = PIXEL COLUMN (0-319,639)				:
    77                              <1> ;    (AH)= 05H	SELECT ACTIVE DISPLAY PAGE (VALID ONLY FOR ALPHA MODES)		:
    78                              <1> ;		(AL) = NEW PAGE VALUE (0-7 FOR MODES 0&1, 0-3 FOR MODES 2&3)	:
    79                              <1> ;    (AH)= 06H	SCROLL ACTIVE PAGE UP						:
    80                              <1> ;		(AL) = NUMBER OF LINES. ( LINES BLANKED AT BOTTOM OF WINDOW )	:
    81                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
    82                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
    83                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
    84                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
    85                              <1> ;    (AH)= 07H	SCROLL ACTIVE PAGE DOWN						:
    86                              <1> ;		(AL) = NUMBER OF LINES, INPUT LINES BLANKED AT TOP OF WINDOW	:
    87                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
    88                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
    89                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
    90                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
    91                              <1> ;										:
    92                              <1> ;   CHARACTER HANDLING ROUTINES							:
    93                              <1> ;										:
    94                              <1> ;    (AH)= 08H	READ ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
    95                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
    96                              <1> ;		ON EXIT:							:
    97                              <1> ;		(AL) = CHAR READ						:
    98                              <1> ;		(AH) = ATTRIBUTE OF CHARACTER READ (ALPHA MODES ONLY)		:
    99                              <1> ;    (AH)= 09H	WRITE ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
   100                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
   101                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
   102                              <1> ;		(AL) = CHAR TO WRITE						:
   103                              <1> ;		(BL) = ATTRIBUTE OF CHARACTER (ALPHA)/COLOR OF CHAR (GRAPHICS)	:
   104                              <1> ;		         SEE NOTE ON WRITE DOT FOR BIT 7 OF BL = 1.		:
   105                              <1> ;    (AH) = 0AH	WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION			:
   106                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
   107                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
   108                              <1> ;		(AL) = CHAR TO WRITE						:
   109                              <1> ;		       NOTE: USE FUNCTION (AH)= 09H IN GRAPHICS MODES		:
   110                              <1> ;	FOR READ/WRITE CHARACTER INTERFACE WHILE IN GRAPHICS MODE, THE		:
   111                              <1> ;		CHARACTERS ARE FORMED FROM A CHARACTER GENERATOR IMAGE		:
   112                              <1> ;		MAINTAINED IN THE SYSTEM ROM. ONLY THE 1ST 128 CHARS		:
   113                              <1> ;		ARE CONTAINED THERE. TO READ/WRITE THE SECOND 128 CHARS,	:
   114                              <1> ;		THE USER MUST INITIALIZE THE POINTER AT INTERRUPT 1FH		:
   115                              <1> ;		(LOCATION 0007CH) TO POINT TO THE 1K BYTE TABLE CONTAINING	:
   116                              <1> ;		THE CODE POINTS FOR THE SECOND 128 CHARS (128-255).		:
   117                              <1> ;	FOR WRITE CHARACTER INTERFACE IN GRAPHICS MODE, THE REPLICATION FACTOR	:
   118                              <1> ;		CONTAINED IN (CX) ON ENTRY WILL PRODUCE VALID RESULTS ONLY	:
   119                              <1> ;		FOR CHARACTERS CONTAINED ON THE SAME ROW. CONTINUATION TO	:
   120                              <1> ;		SUCCEEDING LINES WILL NOT PRODUCE CORRECTLY.			:
   121                              <1> ;										:
   122                              <1> ;    GRAPHICS INTERFACE								:
   123                              <1> ;    (AH)= 0BH	SET COLOR PALETTE						:
   124                              <1> ;		(BH) = PALETTE COLOR ID BEING SET (0-127)			:
   125                              <1> ;		(BL) = COLOR VALUE TO BE USED WITH THAT COLOR ID		:
   126                              <1> ;		       NOTE: FOR THE CURRENT COLOR CARD, THIS ENTRY POINT HAS	:
   127                              <1> ;		               MEANING ONLY FOR 320X200 GRAPHICS.		:
   128                              <1> ;		       COLOR ID = 0 SELECTS THE BACKGROUND COLOR (0-15)		:
   129                              <1> ;		       COLOR ID = 1 SELECTS THE PALETTE TO BE USED:		:
   130                              <1> ;		               0 = GREEN(1)/RED(2)/YELLOW(3)			:
   131                              <1> ;		               1 = CYAN(1)/MAGENTA(2)/WHITE(3)			:
   132                              <1> ;		       IN 40X25 OR 80X25 ALPHA MODES, THE VALUE SET FOR 	:
   133                              <1> ;		               PALETTE COLOR 0 INDICATES THE BORDER COLOR	:
   134                              <1> ;		               TO BE USED (VALUES 0-31, WHERE 16-31 SELECT	:
   135                              <1> ;		               THE HIGH INTENSITY BACKGROUND SET.		:
   136                              <1> ;    (AH)= 0CH	WRITE DOT							:
   137                              <1> ;		(DX) = ROW NUMBER						:
   138                              <1> ;		(CX) = COLUMN NUMBER						:
   139                              <1> ;		(AL) = COLOR VALUE						:
   140                              <1> ;		        IF BIT 7 OF AL = 1, THEN THE COLOR VALUE IS EXCLUSIVE	:
   141                              <1> ;		        ORed WITH THE CURRENT CONTENTS OF THE DOT		:
   142                              <1> ;    (AH)= ODH	READ DOT							:
   143                              <1> ;		(DX) = ROW NUMBER						:
   144                              <1> ;		(CX) = COLUMN NUMBER						:
   145                              <1> ;		(AL) = RETURNS THE DOT READ					:
   146                              <1> ;										:
   147                              <1> ;    ASCII TELETYPE ROUTINE FOR OUTPUT						:
   148                              <1> ;										:
   149                              <1> ;    (AH)= 0EH	WRITE TELETYPE TO ACTIVE PAGE					:
   150                              <1> ;		(AL) = CHAR TO WRITE						:
   151                              <1> ;		(BL) = FOREGROUND COLOR IN GRAPHICS MODE			:
   152                              <1> ;		NOTE -- SCREEN WIDTH IS CONTROLLED BY PREVIOUS MODE SET		:
   153                              <1> ;    (AH)= 0FH	CURRENT VIDEO STATE						:
   154                              <1> ;		RETURNS THE CURRENT VIDEO STATE					:
   155                              <1> ;		(AL) = MODE CURRENTLY SET ( SEE (AH)=00H FOR EXPLANATION)	:
   156                              <1> ;		(AH) = NUMBER OR CHARACTER COLUMNS ON SCREEN			:
   157                              <1> ;		(BH) = CURRENT ACTIVE DISPLAY PAGE				:
   158                              <1> ;    (AH)= 10H	RESERVED							:
   159                              <1> ;    (AH)= 11H	RESERVED							:
   160                              <1> ;    (AH)= 12H	RESERVED							:
   161                              <1> ;    (AH)= 13H	WRITE STRING							:
   162                              <1> ;			ES:BP  -  POINTER T0 STRING TO BE WRITTEN		:
   163                              <1> ;			CX     -  LENGTH OF CHARACTER STRING TO WRITTEN		:
   164                              <1> ;			DX     -  CURSOR POSITION FOR STRING TO BE WRITTEN	:
   165                              <1> ;			BH     -  PAGE NUMBER					:
   166                              <1> ;		(AL)= 00H	WRITE CHARACTER STRING				:
   167                              <1> ;			BL     -  ATTRIBUTE					:
   168                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
   169                              <1> ;			CURSOR NOT MOVED					:
   170                              <1> ;		(AL)= 01H	WRITE CHARACTER STRING AND MOVE CURSOR		:
   171                              <1> ;			BL     -  ATTRIBUTE					:
   172                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
   173                              <1> ;			CURSOR MOVED						:
   174                              <1> ;		(AL)= 02H	WRITE CHARACTER AND ATTRIBUTE STRING		:
   175                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
   176                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
   177                              <1> ;			CURSOR IS NOT MOVED					:
   178                              <1> ;		(AL)= 03H WRITE CHARACTER AND ATTRIBUTE STRING AND MOVE CURSOR	:
   179                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
   180                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
   181                              <1> ;			CURSOR IS MOVED						:
   182                              <1> ;		 NOTE:  CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE	:
   183                              <1> ;		        TREATED AS COMMANDS RATHER THAN PRINTABLE CHARACTERS.	:
   184                              <1> ;										:
   185                              <1> ;	BX,CX,DX,SI,DI,BP,SP,DS,ES,SS PRESERVED DURING CALLS EXCEPT FOR		:
   186                              <1> ;	BX,CX,DX RETURN VALUES ON FUNCTIONS 03H,04H,0DH AND 0FH. ON ALL CALLS	:
   187                              <1> ;	AX IS MODIFIED.								:
   188                              <1> ;--------------------------------------------------------------------------------
   189                              <1> 
   190 00001458 [F4140000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   191 0000145C [54150000]          <1> 	dd	SET_CTYPE
   192 00001460 [69150000]          <1> 	dd	SET_CPOS
   193 00001464 [70150000]          <1> 	dd	READ_CURSOR
   194 00001468 [F9140000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
   195 0000146C [92150000]          <1> 	dd	ACT_DISP_PAGE
   196 00001470 [0B160000]          <1> 	dd	SCROLL_UP
   197 00001474 [EF160000]          <1> 	dd	SCROLL_DOWN
   198 00001478 [3A170000]          <1> 	dd	READ_AC_CURRENT
   199 0000147C [68170000]          <1> 	dd	WRITE_AC_CURRENT
   200 00001480 [7B170000]          <1> 	dd	WRITE_C_CURRENT
   201 00001484 [F9140000]          <1> 	dd	VIDEO_RETURN	; SET_COLOR
   202 00001488 [F9140000]          <1> 	dd	VIDEO_RETURN	; WRITE_DOT
   203 0000148C [F9140000]          <1> 	dd	VIDEO_RETURN	; READ_DOT
   204 00001490 [BF170000]          <1> 	dd	WRITE_TTY
   205 00001494 [E1140000]          <1> 	dd	VIDEO_STATE
   206 00001498 [F9140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   207 0000149C [F9140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   208 000014A0 [F9140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   209 000014A4 [F9140000]          <1> 	dd	VIDEO_RETURN	; WRITE_STRING
   210                              <1> M1L	EQU	$ - M1
   211                              <1> 
   212                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   213                              <1> int31h:  ; Video BIOS
   214                              <1> 
   215                              <1> VIDEO_IO_1:
   216 000014A8 FB                  <1> 	sti				; INTERRUPTS BACK ON
   217 000014A9 FC                  <1> 	cld				; SET DIRECTION FORWARD
   218 000014AA 80FC14              <1> 	cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
   219 000014AD 7321                <1> 	jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
   220                              <1> 
   221 000014AF 06                  <1> 	push	es
   222 000014B0 1E                  <1> 	push	ds			; SAVE WORK AND PARAMETER REGISTERS
   223 000014B1 52                  <1> 	push	edx
   224 000014B2 51                  <1> 	push	ecx
   225 000014B3 53                  <1> 	push	ebx
   226 000014B4 56                  <1> 	push	esi
   227 000014B5 57                  <1> 	push	edi
   228 000014B6 55                  <1> 	push	ebp
   229 000014B7 66BE1000            <1> 	mov	si, KDATA 		; POINT DS: TO DATA SEGMENT
   230 000014BB 8EDE                <1> 	mov	ds, si
   231 000014BD 8EC6                <1> 	mov	es, si
   232 000014BF BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
   233                              <1> 	; 23/03/2016
   234 000014C4 C0E402              <1> 	shl	ah, 2  ; dword		; TIMES 2 FOR WORD TABLE LOOKUP
   235 000014C7 0FB6F4              <1> 	movzx	esi, ah			; MOVE OFFSET INTO LOOK UP REGISTER (SI)
   236                              <1> 	;mov	ah, [CRT_MODE]		; MOVE CURRENT MODE INTO (AH) REGISTER
   237                              <1> 
   238 000014CA FFA6[58140000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
   239                              <1> 
   240                              <1> M4:					;	COMMAND NOT VALID
   241 000014D0 CF                  <1> 	iret				; DO NOTHING IF NOT IN VALID RANGE
   242                              <1> 
   243                              <1> 
   244                              <1> ; 02/09/2014 (Retro UNIX 386 v1)
   245                              <1> ;
   246                              <1> ; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   247                              <1> 
   248                              <1> set_mode_3:  	; will be called from 'write_tty' 
   249 000014D1 53                  <1> 	push	ebx
   250 000014D2 52                  <1> 	push	edx
   251 000014D3 50                  <1> 	push	eax
   252 000014D4 57                  <1> 	push	edi
   253 000014D5 51                  <1> 	push	ecx
   254 000014D6 E827000000          <1> 	call	set_txt_mode
   255 000014DB 59                  <1> 	pop	ecx
   256 000014DC 5F                  <1> 	pop	edi
   257 000014DD 58                  <1> 	pop	eax
   258 000014DE 5A                  <1> 	pop	edx
   259 000014DF 5B                  <1> 	pop	ebx
   260 000014E0 C3                  <1> 	retn
   261                              <1> 
   262                              <1> VIDEO_STATE:
   263                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   264                              <1> 
   265                              <1> ;---------------------------------------------------
   266                              <1> ; VIDEO STATE
   267                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
   268                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
   269                              <1> ;  AL = CURRENT VIDEO MODE
   270                              <1> ;  BH = CURRENT ACTIVE PAGE
   271                              <1> ;---------------------------------------------------
   272                              <1> 
   273                              <1> 	;mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
   274 000014E1 B480                <1> 	mov	ah, 80h
   275 000014E3 A0[C6C80000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
   276                              <1> 	;movzx	esi, al
   277                              <1> 	;mov	ah, [esi+M6] 
   278                              <1> 	; BL = active page (not BH!)
   279 000014E8 8A1D[08CF0000]      <1> 	mov	bl, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
   280 000014EE 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
   281 000014EF 5F                  <1> 	pop	edi
   282 000014F0 5E                  <1> 	pop	esi
   283 000014F1 59                  <1> 	pop	ecx	; DISCARD SAVED BX
   284 000014F2 EB09                <1> 	jmp	short M15	; RETURN TO CALLER
   285                              <1> 
   286                              <1> SET_MODE:
   287                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
   288                              <1> 	;	valid video mode: 03h only!
   289                              <1> 	;	(VGA modes will be selected with another routine)
   290                              <1> 	;
   291                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
   292                              <1> 
   293                              <1> ;------------------------------------------------------
   294                              <1> ; SET MODE					      :
   295                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
   296                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
   297                              <1> ; INPUT						      :
   298                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
   299                              <1> ; OUTPUT					      :
   300                              <1> ;	NONE					      :
   301                              <1> ;------------------------------------------------------
   302                              <1> 
   303 000014F4 E809000000          <1> 	call	set_txt_mode
   304                              <1> 
   305                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   306                              <1> 
   307                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   308                              <1> 
   309                              <1> VIDEO_RETURN:
   310 000014F9 5D                  <1> 	pop	ebp
   311 000014FA 5F                  <1> 	pop	edi
   312 000014FB 5E                  <1> 	pop	esi
   313 000014FC 5B                  <1> 	pop	ebx
   314                              <1> M15:			; VIDEO_RETURN_C
   315 000014FD 59                  <1> 	pop	ecx
   316 000014FE 5A                  <1> 	pop	edx
   317 000014FF 1F                  <1> 	pop	ds
   318 00001500 07                  <1> 	pop	es	; RECOVER SEGMENTS
   319 00001501 CF                  <1> 	iret		; ALL DONE
   320                              <1> 
   321                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   322                              <1> set_txt_mode:
   323                              <1> 	;mov	dx, 03D4h 	; address of color card
   324 00001502 B003                <1> 	mov	al, 3
   325                              <1> ;M8:
   326 00001504 A2[C6C80000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
   327 00001509 B029                <1> 	mov	al, 29h
   328                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
   329 0000150B 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
   330                              <1> 	;push	dx  		; save port value
   331                              <1> 	;add	dx, 4		; point to control register
   332 0000150D 66BAD803            <1> 	mov	dx, 3D8h
   333 00001511 EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
   334                              <1> 	;pop	dx
   335                              <1> ;M9:
   336 00001512 BB[C8C80000]        <1> 	mov	ebx, video_params ; initialization table
   337 00001517 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
   338 0000151B 86E0                <1> 	xchg 	ah, al
   339 0000151D 66A3[F6CE0000]      <1> 	mov	[CURSOR_MODE], ax ; save cursor mode
   340 00001523 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
   341                              <1> 	
   342                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
   343 00001525 B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
   344                              <1> M10:			;  initialization loop
   345 0000152A 88E0                <1> 	mov	al, ah 	; get 6845 register number
   346 0000152C EE                  <1> 	out	dx, al
   347 0000152D 6642                <1> 	inc	dx      ; point to data port
   348 0000152F FEC4                <1> 	inc	ah	; next register value
   349 00001531 8A03                <1> 	mov	al, [ebx] ; get table value
   350 00001533 EE                  <1> 	out	dx, al	; out to chip
   351 00001534 43                  <1> 	inc	ebx	; next in table
   352 00001535 664A                <1> 	dec	dx	; back to pointer register
   353 00001537 E2F1                <1> 	loop	M10	; do the whole table
   354                              <1> 
   355                              <1> ;-----	FILL REGEN AREA WITH BLANK
   356                              <1> 	;xor	ax, ax  
   357                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
   358                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
   359                              <1> 	;mov	ecx, 8192 ; number of words in color card
   360                              <1> 	; black background, light gray characeter color, space character
   361                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
   362                              <1> ;M13:			  ; clear buffer
   363                              <1> 	;add	edi, 0B8000h ; [crt_base]
   364                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   365                              <1> 
   366                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
   367                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
   368                              <1> 			 ; prepare to output to video enable port
   369                              <1> 	;add	dx,4	 ; point to the mode control gerister
   370 00001539 66BAD803            <1> 	mov	dx, 3D8h
   371                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
   372 0000153D B029                <1> 	mov	al, 29h
   373 0000153F EE                  <1> 	out	dx, al	 ; set video enable port
   374                              <1> 
   375                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
   376                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
   377                              <1> 	;
   378                              <1> 	;mov	byte [CRT_COLS], 80h ; initialize number of columns count
   379                              <1> 	;
   380                              <1> ;-----	SET CURSOR POSITIONS
   381                              <1> 	;mov	word [CRT_LEN], 80*25*2
   382 00001540 BF[F8CE0000]        <1> 	mov	edi, CURSOR_POSN
   383 00001545 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
   384 0000154A 31C0                <1> 	xor	eax, eax
   385 0000154C F3AB                <1> 	rep 	stosd	; fill with zeroes
   386                              <1> 
   387                              <1> ;-----	SET UP OVERSCAN REGISTER
   388 0000154E 6642                <1> 	inc	dx	; set overscan port to a default
   389 00001550 B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
   390                              <1> ;M14:
   391 00001552 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
   392                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
   393                              <1> 
   394                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   395 00001553 C3                  <1> 	retn
   396                              <1> 
   397                              <1> SET_CTYPE:
   398                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   399 00001554 E802000000          <1> 	call	_set_ctype
   400 00001559 EB9E                <1> 	jmp	short VIDEO_RETURN
   401                              <1> 
   402                              <1> _set_ctype:
   403                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
   404                              <1> 	;
   405                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   406                              <1> 
   407                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
   408                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
   409                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
   410                              <1> 	;     OR NO CURSOR AT ALL
   411                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
   412                              <1> 
   413                              <1> ;------------------------------------------------
   414                              <1> ; SET_CTYPE
   415                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
   416                              <1> ; INPUT
   417                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
   418                              <1> ; OUTPUT	
   419                              <1> ;	NONE
   420                              <1> ;------------------------------------------------
   421                              <1> 
   422 0000155B B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
   423 0000155D 66890D[F6CE0000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
   424                              <1> 	;call	m16	; output cx register
   425                              <1> 	;retn
   426 00001564 E915030000          <1>         jmp     m16
   427                              <1> 
   428                              <1> SET_CPOS:
   429                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   430 00001569 E8E5020000          <1> 	call	_set_cpos
   431 0000156E EB89                <1> 	jmp	short VIDEO_RETURN
   432                              <1> 
   433                              <1> READ_CURSOR:
   434                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   435                              <1> 	;
   436                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   437                              <1> 
   438                              <1> ;------------------------------------------------------
   439                              <1> ; READ_CURSOR
   440                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
   441                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
   442                              <1> ; INPUT
   443                              <1> ;	BH - PAGE OF CURSOR
   444                              <1> ; OUTPUT
   445                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
   446                              <1> ;	CX - CURRENT CURSOR MODE
   447                              <1> ;------------------------------------------------------
   448                              <1> 
   449                              <1> 	; BL = Video page number (0 to 7)
   450                              <1> 	
   451                              <1> 
   452 00001570 E810000000          <1> 	call	get_cpos
   453 00001575 0FB70D[F6CE0000]    <1> 	movzx	ecx, word [CURSOR_MODE]
   454                              <1> 
   455 0000157C 5D                  <1> 	pop	ebp
   456 0000157D 5F                  <1> 	pop	edi
   457 0000157E 5E                  <1> 	pop	esi
   458 0000157F 5B                  <1> 	pop	ebx
   459 00001580 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
   460 00001581 58                  <1> 	pop	eax
   461 00001582 1F                  <1> 	pop	ds
   462 00001583 07                  <1> 	pop	es
   463 00001584 CF                  <1> 	iret
   464                              <1> 
   465                              <1> get_cpos:
   466                              <1> 	; 16/01/2016
   467                              <1> 	; BL = Video page number (0 to 7)
   468                              <1> 	;
   469 00001585 D0E3                <1> 	shl	bl, 1 ; WORD OFFSET
   470 00001587 0FB6F3              <1> 	movzx	esi, bl 
   471 0000158A 0FB796[F8CE0000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
   472 00001591 C3                  <1> 	retn
   473                              <1> 
   474                              <1> ACT_DISP_PAGE:
   475                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   476                              <1> 	;
   477                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   478                              <1> 	;
   479                              <1> ;-----------------------------------------------------
   480                              <1> ; ACT_DISP_PAGE
   481                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
   482                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
   483                              <1> ; INPUT
   484                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
   485                              <1> ; OUTPUT
   486                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
   487                              <1> ;-----------------------------------------------------
   488                              <1> 
   489 00001592 E805000000          <1> 	call	set_active_page
   490 00001597 E95DFFFFFF          <1>         jmp     VIDEO_RETURN
   491                              <1> 
   492                              <1> set_active_page:   ; tty_sw
   493                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   494                              <1> 	; 30/06/2015
   495                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
   496                              <1> 	; 10/12/2013
   497                              <1> 	; 04/12/2013
   498                              <1> 	;
   499 0000159C A2[08CF0000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
   500                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
   501 000015A1 66B9A00F            <1> 	mov	cx, 25*80*2
   502                              <1> 	; 27/06/2015
   503 000015A5 0FB6D8              <1> 	movzx	ebx, al
   504                              <1> 	;
   505 000015A8 6698                <1> 	cbw	; 07/09/2014 (ah=0)
   506 000015AA 66F7E1              <1> 	mul 	cx	; display page times regen length
   507                              <1> 	; 10/12/2013
   508 000015AD 66A3[F4CE0000]      <1> 	mov	[CRT_START], ax ; save start address for later
   509 000015B3 6689C1              <1> 	mov	cx, ax ; start address to cx
   510                              <1> 	;sar	cx, 1
   511 000015B6 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
   512 000015B9 B40C                <1> 	mov	ah, 12	; 6845 register for start address
   513 000015BB E8BE020000          <1> 	call	m16
   514                              <1> 	;sal	bx, 1
   515                              <1> 	; 01/09/2014
   516 000015C0 D0E3                <1> 	shl	bl, 1	; *2 for word offset
   517 000015C2 81C3[F8CE0000]      <1> 	add	ebx, CURSOR_POSN
   518 000015C8 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
   519                              <1> 	; 16/01/2016
   520                              <1> 	;call	m18
   521                              <1> 	;retn
   522 000015CB E99A020000          <1> 	jmp	m18
   523                              <1> 
   524                              <1> position:
   525                              <1> 	; 27/06/2015
   526                              <1> 	; 02/09/2014
   527                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   528                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
   529                              <1> 	;
   530                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   531                              <1> 	;
   532                              <1> ;-----------------------------------------
   533                              <1> ; POSITION
   534                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
   535                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
   536                              <1> ; INPUT
   537                              <1> ;	AX = ROW, COLUMN POSITION
   538                              <1> ; OUTPUT
   539                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
   540                              <1> ;-----------------------------------------
   541                              <1> 
   542                              <1> 		; DX = ROW, COLUMN POSITION
   543                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
   544 000015D0 31C0                <1> 	xor	eax, eax ; 02/09/2014
   545 000015D2 B050                <1> 	mov	al, 80   ; determine bytes to row	
   546 000015D4 F6E6                <1> 	mul	dh	 ; row value
   547 000015D6 30F6                <1> 	xor	dh, dh   ; 0	
   548 000015D8 6601D0              <1> 	add	ax, dx	 ; add column value to the result
   549 000015DB 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
   550                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
   551 000015DE C3                  <1> 	retn
   552                              <1> 
   553                              <1> find_position:
   554                              <1> 	; 27/06/2015
   555                              <1> 	; 07/09/2014
   556                              <1> 	; 02/09/2014
   557                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   558                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   559 000015DF 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
   560 000015E2 89CE                <1> 	mov	esi, ecx
   561 000015E4 66D1E6              <1> 	shl	si, 1
   562 000015E7 668B96[F8CE0000]    <1> 	mov	dx, [esi + CURSOR_POSN]
   563 000015EE 740A                <1> 	jz	short p21
   564 000015F0 6631F6              <1> 	xor	si, si
   565                              <1> p20:
   566                              <1> 	;add	si, [CRT_LEN]
   567 000015F3 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
   568 000015F8 E2F9                <1> 	loop	p20
   569                              <1> p21:
   570 000015FA 6621D2              <1> 	and	dx, dx
   571 000015FD 7407                <1> 	jz	short p22
   572 000015FF E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
   573 00001604 01C6                <1> 	add	esi, eax ; add location to start of regen page
   574                              <1> p22:	
   575                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
   576                              <1> 	;mov	dx, 03D4h ; I/O address of color card
   577                              <1> 	;add	dx, 6	; point at status port
   578 00001606 66BADA03            <1> 	mov	dx, 03DAh ; status port
   579                              <1> 	; cx = 0
   580 0000160A C3                  <1> 	retn
   581                              <1> 
   582                              <1> SCROLL_UP:
   583                              <1> 	; 30/01/2016
   584                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   585                              <1> 	; 07/09/2014
   586                              <1> 	; 02/09/2014
   587                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
   588                              <1> 	; 04/04/2014
   589                              <1> 	; 04/12/2013
   590                              <1> 	;
   591                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   592                              <1> 	;
   593                              <1> ;----------------------------------------------
   594                              <1> ; SCROLL UP
   595                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
   596                              <1> ;	ON THE SCREEN
   597                              <1> ; INPUT
   598                              <1> ;	(AH) = CURRENT CRT MODE
   599                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
   600                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
   601                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
   602                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
   603                              <1> ;	(DS) = DATA SEGMENT
   604                              <1> ;	(ES) = REGEN BUFFER SEGMENT
   605                              <1> ; OUTPUT
   606                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
   607                              <1> ;--------------------------------------------
   608                              <1> 
   609 0000160B E805000000          <1> 	call	_scroll_up
   610 00001610 E9E4FEFFFF          <1>         jmp     VIDEO_RETURN
   611                              <1> 
   612                              <1> _scroll_up:  ; from 'write_tty'
   613                              <1> 	;
   614                              <1> 	; ((ah = 3))
   615                              <1> 	; cl = left upper column
   616                              <1> 	; ch = left upper row
   617                              <1> 	; dl = right lower column
   618                              <1> 	; dh = right lower row
   619                              <1> 	;
   620                              <1> 	; al = line count 
   621                              <1> 	; ah = attribute to be used on blanked line	
   622                              <1> 	; bl = video page number (0 to 7)
   623                              <1> 	; 
   624                              <1> 
   625 00001615 E86C000000          <1> 	call	test_line_count ; 16/01/2016
   626                              <1> 
   627                              <1> 	;mov	bh, [CRT_MODE] ; current video mode	
   628                              <1> 	;cmp	bh, 4
   629                              <1>  	;jb	short n1
   630                              <1> 
   631                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
   632                              <1> 	;jne	GRAPHICS_UP
   633                              <1> n1:
   634 0000161A 30FF                <1> 	xor	bh, bh	; 0
   635 0000161C 6650                <1> 	push	ax ; *
   636                              <1> 	;mov 	esi, [CRT_BASE]
   637 0000161E BE00800B00          <1>         mov     esi, 0B8000h  
   638 00001623 3A1D[08CF0000]      <1>         cmp     bl, [ACTIVE_PAGE]
   639 00001629 750B                <1> 	jne	short n2
   640                              <1> 	;
   641 0000162B 66A1[F4CE0000]      <1>         mov     ax, [CRT_START]
   642 00001631 6601C6              <1>         add     si, ax
   643 00001634 EB0F                <1>         jmp     short n4
   644                              <1> n2:
   645 00001636 20DB                <1>         and     bl, bl
   646 00001638 740B                <1> 	jz	short n4
   647 0000163A 88D8                <1> 	mov	al, bl
   648                              <1> n3:
   649                              <1>         ;add    si, [CRT_LEN]
   650                              <1>         ;add    esi, 80*25*2 
   651 0000163C 6681C6A00F          <1>         add     si, 80*25*2
   652 00001641 FEC8                <1>         dec	al
   653 00001643 75F7                <1> 	jnz	short n3
   654                              <1> n4:	
   655 00001645 E84D000000          <1> 	call	scroll_position ; 16/01/2016
   656 0000164A 7419                <1>         jz      short n6 
   657                              <1> 
   658 0000164C 01CE                <1>         add     esi, ecx ; from address for scroll
   659 0000164E 88F7                <1> 	mov	bh, dh  ; #rows in block
   660 00001650 28C7                <1> 	sub	bh, al	; #rows to be moved
   661                              <1> n5:
   662 00001652 E880000000          <1> 	call	n10 ; 16/01/2016
   663                              <1> 	
   664                              <1>         ;mov    cl, [CRT_COLS] 
   665                              <1> 	;add	cl, cl
   666                              <1>         ;mov    ecx, 80*2
   667 00001657 66B9A000            <1>         mov     cx, 80*2
   668 0000165B 01CE                <1>         add     esi, ecx  ; next line
   669 0000165D 01CF                <1>         add     edi, ecx
   670 0000165F FECF                <1> 	dec	bh	 ; count of lines to move
   671 00001661 75EF                <1> 	jnz	short n5 ; row loop
   672                              <1> 	; bh = 0
   673 00001663 88C6                <1> 	mov	dh, al	 ; #rows	
   674                              <1> n6:
   675                              <1> 	; attribute in ah
   676 00001665 B020                <1> 	mov	al, ' '	 ; fill with blanks
   677                              <1> n7:
   678 00001667 E878000000          <1> 	call	n11 ; 16/01/2016
   679                              <1> 
   680                              <1> 	;mov	cl, [CRT_COLS]
   681                              <1> 	;add	cl, cl
   682                              <1>         ;mov    ecx, 80*2
   683 0000166C 66B9A000            <1>         mov	cx, 80*2
   684 00001670 01CF                <1>         add     edi, ecx
   685 00001672 FECE                <1> 	dec	dh
   686 00001674 75F1                <1> 	jnz	short n7
   687                              <1> 	;
   688 00001676 3A1D[08CF0000]      <1> 	cmp	bl, [ACTIVE_PAGE]
   689 0000167C 7507                <1> 	jne	short n8
   690                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   691 0000167E B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   692 00001680 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   693 00001684 EE                  <1> 	out	dx, al
   694                              <1> n8:
   695 00001685 C3                  <1> 	retn
   696                              <1> 
   697                              <1> 
   698                              <1> test_line_count:
   699                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   700                              <1> 	; 07/09/2014 (scroll_up)
   701 00001686 08C0                <1> 	or	al, al
   702 00001688 740C                <1> 	jz	short al_set
   703 0000168A 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
   704 0000168C 28EF                <1> 	sub	bh, ch
   705 0000168E FEC7                <1> 	inc	bh	; adjust difference by 1
   706 00001690 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
   707 00001692 7502                <1> 	jne	short al_set ; if not the we're all set
   708 00001694 30C0                <1> 	xor	al, al	; otherwise set al to zero
   709                              <1> al_set:
   710 00001696 C3                  <1> 	retn
   711                              <1> 
   712                              <1> scroll_position:
   713                              <1> 	; 30/01/2016
   714                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   715                              <1> 	; 07/09/2014 (scroll_up)
   716                              <1> 
   717 00001697 6652                <1> 	push	dx
   718 00001699 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
   719 0000169C E82FFFFFFF          <1> 	call	position
   720 000016A1 01C6                <1> 	add	esi, eax
   721 000016A3 89F7                <1> 	mov	edi, esi
   722 000016A5 665A                <1> 	pop	dx	; lower right position in DX
   723 000016A7 6629CA              <1> 	sub	dx, cx
   724 000016AA FEC6                <1> 	inc	dh	; dh = #rows 
   725 000016AC FEC2                <1> 	inc	dl	; dl = #cols in block
   726 000016AE 59                  <1> 	pop	ecx 	; return address
   727 000016AF 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
   728 000016B1 51                  <1> 	push	ecx	; return address
   729 000016B2 0FB7C8              <1> 	movzx	ecx, ax
   730                              <1> 	;mov	ah, [CRT_COLS]
   731 000016B5 B450                <1> 	mov	ah, 80
   732 000016B7 F6E4                <1> 	mul	ah	; determine offset to from address
   733 000016B9 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
   734                              <1> 	;
   735 000016BC 6650                <1> 	push	ax	; offset 
   736 000016BE 6652                <1> 	push	dx
   737                              <1> 	;
   738                              <1> 	; 04/04/2014
   739 000016C0 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
   740                              <1> n9:                      ; wait_display_enable
   741 000016C4 EC                  <1>         in      al, dx   ; get port
   742 000016C5 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
   743 000016C7 74FB                <1> 	jz	short n9 ; wait_display_enable
   744 000016C9 B025                <1> 	mov	al, 25h
   745 000016CB B2D8                <1> 	mov	dl, 0D8h ; address control port
   746 000016CD EE                  <1> 	out	dx, al	; turn off video during vertical retrace
   747 000016CE 665A                <1> 	pop	dx	; #rows, #cols
   748 000016D0 6658                <1>        	pop	ax	; offset
   749 000016D2 6691                <1> 	xchg	ax, cx	; 
   750                              <1> 	; ecx = offset, al = line count, ah = attribute
   751                              <1> 	;
   752 000016D4 08C0                <1> 	or	al, al
   753 000016D6 C3                  <1> 	retn
   754                              <1> 
   755                              <1> n10:
   756                              <1> 	; Move rows
   757 000016D7 88D1                <1> 	mov	cl, dl	; get # of cols to move
   758 000016D9 56                  <1> 	push	esi
   759 000016DA 57                  <1> 	push	edi	; save start address
   760                              <1> n10r:
   761 000016DB 66A5                <1> 	movsw		; move that line on screen
   762 000016DD FEC9                <1> 	dec	cl
   763 000016DF 75FA                <1>         jnz     short n10r
   764 000016E1 5F                  <1> 	pop	edi
   765 000016E2 5E                  <1> 	pop	esi	; recover addresses
   766 000016E3 C3                  <1> 	retn
   767                              <1> n11:
   768                              <1> 	; Clear rows
   769                              <1>                 ; dh =  #rows
   770 000016E4 88D1                <1>         mov	cl, dl	; get # of cols to clear
   771 000016E6 57                  <1>         push    edi     ; save address
   772                              <1> n11r:
   773 000016E7 66AB                <1>         stosw           ; store fill character
   774 000016E9 FEC9                <1> 	dec	cl
   775 000016EB 75FA                <1>         jnz     short n11r
   776 000016ED 5F                  <1>         pop     edi     ; recover address
   777 000016EE C3                  <1> 	retn
   778                              <1> 
   779                              <1> SCROLL_DOWN:
   780                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   781                              <1> 	;
   782                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   783                              <1> 
   784                              <1> ;------------------------------------------
   785                              <1> ; SCROLL DOWN
   786                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
   787                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
   788                              <1> ;	WITH A DEFINED CHARACTER
   789                              <1> ; INPUT
   790                              <1> ;	(AH) = CURRENT CRT MODE
   791                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
   792                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
   793                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
   794                              <1> ;	(BH) = FILL CHARACTER
   795                              <1> ;	(DS) = DATA SEGMENT
   796                              <1> ;	(ES) = REGEN SEGMENT
   797                              <1> ; OUTPUT
   798                              <1> ;	NONE -- SCREEN IS SCROLLED
   799                              <1> ;------------------------------------------
   800                              <1> 
   801                              <1> 	; ((ah = 3))
   802                              <1> 	; cl = left upper column
   803                              <1> 	; ch = left upper row
   804                              <1> 	; dl = right lower column
   805                              <1> 	; dh = right lower row
   806                              <1> 	;
   807                              <1> 	; al = line count 
   808                              <1> 	; ah = attribute to be used on blanked line	
   809                              <1> 	; bl = video page number (0 to 7)
   810                              <1> 	; 
   811                              <1> 
   812                              <1> 	; !!!!
   813 000016EF FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
   814                              <1> 	; !!!!
   815 000016F0 E891FFFFFF          <1> 	call	test_line_count ; 16/01/2016
   816                              <1> 	
   817                              <1> 	;mov	bh, [CRT_MODE] ; current video mode
   818                              <1> 	;cmp	bh, 4
   819                              <1>  	;jb	short n12
   820                              <1> 
   821                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
   822                              <1> 	;jne	GRAPHICS_DOWN
   823                              <1> 
   824                              <1> n12:			; CONTINUE_DOWN
   825 000016F5 6650                <1> 	push	ax	; * ; save attribute in ah
   826 000016F7 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
   827 000016FA E898FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
   828 000016FF 7419                <1> 	jz	short n14
   829 00001701 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
   830 00001703 88F7                <1> 	mov	bh, dh  ; #rows in block
   831 00001705 28C7                <1> 	sub	bh, al	; #rows to be moved
   832                              <1> n13:
   833 00001707 E8CBFFFFFF          <1> 	call	n10	; MOVE ONE ROW
   834                              <1> 
   835                              <1> 	;mov    cl, [CRT_COLS] 
   836                              <1> 	;add	cl, cl
   837                              <1>         ;mov    ecx, 80*2
   838 0000170C 66B9A000            <1>         mov     cx, 80*2
   839 00001710 29CE                <1>         sub     esi, ecx  ; next line
   840 00001712 29CF                <1>         sub     edi, ecx
   841 00001714 FECF                <1> 	dec	bh	 ; count of lines to move
   842 00001716 75EF                <1> 	jnz	short n13 ; row loop
   843                              <1> 	; bh = 0
   844 00001718 88C6                <1> 	mov	dh, al	 ; #rows
   845                              <1> n14:
   846                              <1> 	; attribute in ah
   847 0000171A B020                <1> 	mov	al, ' '	 ; fill with blanks
   848                              <1> n15:
   849 0000171C E8C3FFFFFF          <1> 	call	n11 ; 16/01/2016
   850                              <1> 
   851                              <1> 	;mov	cl, [CRT_COLS]
   852                              <1> 	;add	cl, cl
   853                              <1>         ;mov    ecx, 80*2
   854 00001721 B1A0                <1>         mov	cl, 80*2
   855 00001723 29CF                <1>         sub     edi, ecx
   856 00001725 FECE                <1> 	dec	dh
   857 00001727 75F3                <1> 	jnz	short n15
   858                              <1> 	;
   859 00001729 3A1D[08CF0000]      <1> 	cmp	bl, [ACTIVE_PAGE]
   860 0000172F 7507                <1> 	jne	short n16
   861                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   862 00001731 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   863 00001733 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   864 00001737 EE                  <1> 	out	dx, al
   865                              <1> n16:
   866                              <1> 	; !!!!
   867 00001738 FC                  <1> 	cld		; Clear direction flag !
   868                              <1> 	; !!!!
   869 00001739 C3                  <1> 	retn
   870                              <1> 
   871                              <1> READ_AC_CURRENT:
   872                              <1> 	; 18/01/2016
   873                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   874                              <1> 	;
   875                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   876                              <1> 	;
   877                              <1> 
   878 0000173A E805000000          <1> 	call	_read_ac_current
   879 0000173F E9B5FDFFFF          <1>         jmp     VIDEO_RETURN
   880                              <1> 
   881                              <1> ;------------------------------------------------------------------------
   882                              <1> ; READ_AC_CURRENT							:
   883                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
   884                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
   885                              <1> ; INPUT									:
   886                              <1> ;	(AH) = CURRENT CRT MODE						:
   887                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
   888                              <1> ;	(DS) = DATA SEGMENT						:
   889                              <1> ;	(ES) = REGEN SEGMENT						:
   890                              <1> ; OUTPUT								:
   891                              <1> ;	(AL) = CHARACTER READ						:
   892                              <1> ;	(AH) = ATTRIBUTE READ						:
   893                              <1> ;------------------------------------------------------------------------
   894                              <1> 
   895                              <1> _read_ac_current: ; 18/01/2016
   896                              <1> 
   897                              <1> p10:
   898 00001744 E896FEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
   899                              <1> 	;
   900                              <1> 	; esi = regen location
   901                              <1> 	; dx = status port
   902                              <1> 	;
   903                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
   904                              <1> 	;
   905                              <1> p11:			; wait for horizontal retrace is low or vertical
   906 00001749 FB                  <1> 	sti		; enable interrupts first
   907 0000174A 3A1D[08CF0000]      <1>         cmp     bl, [ACTIVE_PAGE]
   908 00001750 750C                <1> 	jne	short p14 
   909 00001752 FA                  <1> 	cli 		; block interrupts for single loop
   910 00001753 EC                  <1> 	in	al, dx	; get status from the adapter
   911 00001754 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
   912 00001756 75F1                <1> 	jnz	short p11 ; wait until it is
   913                              <1> p12:			;  wait for either retrace high
   914 00001758 EC                  <1> 	in	al, dx ; get status again
   915 00001759 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
   916 0000175B 74FB                <1> 	jz	short p12 ; wait until either retrace active
   917 0000175D FB                  <1> 	sti
   918                              <1> p14:
   919 0000175E 81C600800B00        <1> 	add	esi, 0B8000h 
   920 00001764 668B06              <1> 	mov	ax, [esi]
   921                              <1> 
   922 00001767 C3                  <1> 	retn	; 18/01/2016
   923                              <1> 
   924                              <1> 
   925                              <1> WRITE_AC_CURRENT:
   926                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   927                              <1> 	;
   928                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   929                              <1> 	;
   930                              <1> ;----------------------------------------------------------------
   931                              <1> ; WRITE_AC_CURRENT						:
   932                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
   933                              <1> ;	AT THE CURRENT CURSOR POSITION				:
   934                              <1> ; INPUT								:
   935                              <1> ;	(AH) = CURRENT CRT MODE					:
   936                              <1> ;	(BH) = DISPLAY PAGE					:
   937                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   938                              <1> ;	(AL) = CHAR TO WRITE					:
   939                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
   940                              <1> ;	(DS) = DATA SEGMENT					:
   941                              <1> ;	(ES) = REGEN SEGMENT					:
   942                              <1> ; OUTPUT							:
   943                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   944                              <1> ;----------------------------------------------------------------
   945                              <1> 
   946 00001768 E821000000          <1> 	call	_write_c_current
   947                              <1> 
   948 0000176D 0FB6F3              <1> 	movzx	esi, bl ; video page number (0 to 7)	
   949 00001770 88A6[D8C80000]      <1> 	mov	[esi+chr_attrib], ah ; color/attribute
   950                              <1> 
   951 00001776 E97EFDFFFF          <1>         jmp     VIDEO_RETURN
   952                              <1> 
   953                              <1> WRITE_C_CURRENT:
   954                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   955                              <1> 	;
   956                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   957                              <1> 	;
   958                              <1> 
   959                              <1> 	;and	bl, 7 ; video page number (<= 7)
   960 0000177B 0FB6F3              <1> 	movzx	esi, bl	
   961 0000177E 8AA6[D8C80000]      <1> 	mov	ah, [esi+chr_attrib]
   962                              <1> 
   963 00001784 E805000000          <1> 	call	_write_c_current
   964 00001789 E96BFDFFFF          <1>         jmp     VIDEO_RETURN
   965                              <1> 
   966                              <1> ;----------------------------------------------------------------
   967                              <1> ; WRITE_C_CURRENT						:
   968                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
   969                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
   970                              <1> ; INPUT								:
   971                              <1> ;	(AH) = CURRENT CRT MODE					:
   972                              <1> ;	(BH) = DISPLAY PAGE					:
   973                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   974                              <1> ;	(AL) = CHAR TO WRITE					:
   975                              <1> ;	(DS) = DATA SEGMENT					:
   976                              <1> ;	(ES) = REGEN SEGMENT					:
   977                              <1> ; OUTPUT							:
   978                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   979                              <1> ;----------------------------------------------------------------
   980                              <1> 
   981                              <1> _write_c_current:  ; from 'write_tty'
   982                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   983                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   984                              <1> 	; 18/01/2014
   985                              <1> 	; 04/12/2013
   986                              <1> 	;
   987                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   988                              <1> 	;
   989                              <1> 
   990 0000178E FA                  <1> 	cli		
   991                              <1> 	; bl = video page
   992                              <1> 	; al = character
   993                              <1> 	; ah = color/attribute
   994 0000178F 6652                <1> 	push	dx
   995 00001791 6650                <1> 	push	ax	; save character & attribute/color
   996 00001793 E847FEFFFF          <1> 	call 	find_position  ; get regen location and port address
   997                              <1> 	; esi = regen location
   998                              <1> 	; dx = status port
   999                              <1> 	;
  1000                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  1001                              <1> 	;
  1002                              <1> p41:			; wait for horizontal retrace is low or vertical
  1003 00001798 FB                  <1> 	sti		; enable interrupts first
  1004 00001799 3A1D[08CF0000]      <1>         cmp     bl, [ACTIVE_PAGE]
  1005 0000179F 7510                <1> 	jne	short p44 
  1006 000017A1 FA                  <1> 	cli 		; block interrupts for single loop
  1007 000017A2 EC                  <1> 	in	al, dx	; get status from the adapter
  1008 000017A3 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  1009 000017A5 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  1010 000017A7 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1011 000017A9 75ED                <1> 	jnz	short p41 ; wait until it is
  1012                              <1> p42:			;  wait for either retrace high
  1013 000017AB EC                  <1> 	in	al, dx ; get status again
  1014 000017AC A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1015 000017AE 74FB                <1> 	jz	short p42 ; wait until either retrace active
  1016                              <1> p43:	
  1017 000017B0 FB                  <1> 	sti
  1018                              <1> p44:
  1019 000017B1 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  1020 000017B3 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  1021                              <1> 				; Retro UNIX 386 v1 feature only!
  1022 000017B9 668906              <1> 	mov	[esi], ax
  1023 000017BC 665A                <1> 	pop	dx
  1024 000017BE C3                  <1> 	retn
  1025                              <1> 
  1026                              <1> ; 18/01/2016
  1027                              <1> ; 16/01/2016
  1028                              <1> ; 30/06/2015
  1029                              <1> ; 27/06/2015
  1030                              <1> ; 11/03/2015
  1031                              <1> ; 02/09/2014
  1032                              <1> ; 30/08/2014
  1033                              <1> ; VIDEO FUNCTIONS
  1034                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1035                              <1> 
  1036                              <1> WRITE_TTY:
  1037                              <1> 	; 30/01/2016
  1038                              <1> 	; 18/01/2016
  1039                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1040                              <1> 	; 13/08/2015
  1041                              <1> 	; 02/09/2014
  1042                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1043                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1044                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1045                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1046                              <1> 	;
  1047                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  1048                              <1> 	;	   AL = Character to be written
  1049                              <1> 	;	   EBX = Video Page (0 to 7)
  1050                              <1> 	;	   (BH = 0 --> Video Mode 3)
  1051                              <1> 
  1052                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1053                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1054                              <1> 
  1055                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1056                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1057                              <1> ;
  1058                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1059                              <1> ;
  1060                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1061                              <1> ;										:
  1062                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1063                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1064                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1065                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1066                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1067                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1068                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1069                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1070                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1071                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1072                              <1> ;   THE 0 COLOR IS USED.							:
  1073                              <1> ;   ENTRY --									:
  1074                              <1> ;     (AH) = CURRENT CRT MODE							:
  1075                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1076                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1077                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1078                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1079                              <1> ;   EXIT -- 									:
  1080                              <1> ;     ALL REGISTERS SAVED							:
  1081                              <1> ;--------------------------------------------------------------------------------
  1082                              <1> 
  1083 000017BF FA                  <1> 	cli
  1084                              <1> 	;
  1085                              <1> 	; READ CURSOR (04/12/2013)
  1086                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  1087 000017C0 08FF                <1> 	or	bh, bh
  1088 000017C2 0F85D5000000        <1> 	jnz	beeper
  1089                              <1> 	; 01/09/2014
  1090 000017C8 803D[C6C80000]03    <1> 	cmp	byte [CRT_MODE], 3
  1091 000017CF 7405                <1> 	je	short m3
  1092                              <1> 	;
  1093 000017D1 E8FBFCFFFF          <1> 	call	set_mode_3 ; 16/01/2016
  1094                              <1> m3:
  1095 000017D6 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  1096 000017D8 66D1E6              <1> 	shl	si, 1
  1097 000017DB 81C6[F8CE0000]      <1> 	add	esi, CURSOR_POSN
  1098 000017E1 668B16              <1> 	mov	dx, [esi]
  1099                              <1> 	;
  1100                              <1> 	; dx now has the current cursor position
  1101                              <1> 	;
  1102 000017E4 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  1103 000017E6 762F                <1> 	jbe	short u8
  1104                              <1> 	;
  1105                              <1> 	; write the char to the screen
  1106                              <1> u0:	
  1107                              <1> 	; ah = attribute/color
  1108                              <1> 	; al = character
  1109                              <1> 	; bl = video page number (0 to 7)
  1110                              <1> 	; bh = 0
  1111                              <1> 	;
  1112 000017E8 E8A1FFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  1113                              <1> 	;
  1114                              <1> 	; position the cursor for next char
  1115 000017ED FEC2                <1> 	inc	dl		; next column
  1116                              <1> 	;cmp	dl, [CRT_COLS]
  1117 000017EF 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  1118 000017F2 755F                <1>         jne     _set_cpos
  1119 000017F4 B200                <1> 	mov	dl, 0		; column = 0
  1120                              <1> u10:				; (line feed found)
  1121 000017F6 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1122 000017F9 7218                <1> 	jb 	short u6
  1123                              <1> 	;
  1124                              <1> 	; scroll required
  1125                              <1> u1:	
  1126                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1127 000017FB E853000000          <1> 	call	_set_cpos
  1128                              <1> 	;
  1129                              <1> 	; determine value to fill with during scroll
  1130                              <1> u2:
  1131                              <1> 	; bl = video page number
  1132                              <1> 	;
  1133 00001800 E83FFFFFFF          <1> 	call _read_ac_current ; 18/01/2016
  1134                              <1> 	;
  1135                              <1> 	; al = character, ah = attribute
  1136                              <1> 	; bl = video page number 	
  1137                              <1> u3:
  1138                              <1> 	;;mov	ax, 0601h 	; scroll one line
  1139                              <1> 	;;sub	cx, cx		; upper left corner
  1140                              <1> 	;;mov	dh, 25-1 	; lower right row
  1141                              <1> 	;;;mov	dl, [CRT_COLS]
  1142                              <1> 	;mov	dl, 80		; lower right column	
  1143                              <1> 	;;dec	dl
  1144                              <1> 	;;mov	dl, 79
  1145                              <1> 
  1146                              <1> 	;;call	scroll_up	; 04/12/2013
  1147                              <1> 	;;; 11/03/2015
  1148                              <1> 	; 02/09/2014
  1149                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  1150                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  1151                              <1> 	; 11/03/2015
  1152 00001805 6629C9              <1> 	sub	cx, cx
  1153 00001808 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  1154                              <1> 	;
  1155 0000180C B001                <1> 	mov	al, 1		; scroll 1 line up
  1156                              <1> 		; ah = attribute
  1157 0000180E E902FEFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  1158                              <1> ;u4:
  1159                              <1> 	;;int	10h		; video-call return
  1160                              <1> 				; scroll up the screen
  1161                              <1> 				; tty return
  1162                              <1> ;u5:
  1163                              <1> 	;retn			; return to the caller
  1164                              <1> 
  1165                              <1> u6:				; set-cursor-inc
  1166 00001813 FEC6                <1> 	inc	dh		; next row
  1167                              <1> 				; set cursor
  1168                              <1> ;u7:					
  1169                              <1> 	;;mov	ah, 02h
  1170                              <1> 	;;jmp	short u4 	; establish the new cursor
  1171                              <1> 	;call	_set_cpos
  1172                              <1> 	;jmp 	short u5
  1173 00001815 EB3C                <1> 	jmp     _set_cpos
  1174                              <1> 
  1175                              <1> 	; check for control characters
  1176                              <1> u8:
  1177 00001817 7438                <1> 	je	short u9
  1178 00001819 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  1179 0000181B 74D9                <1> 	je	short u10
  1180 0000181D 3C07                <1> 	cmp	al, 07h 	; is it a bell
  1181 0000181F 747C                <1> 	je	short u11
  1182 00001821 3C08                <1> 	cmp	al, 08h		; is it a backspace
  1183                              <1> 	;jne	short u0
  1184 00001823 7424                <1> 	je	short bs	; 12/12/2013
  1185                              <1> 	; 12/12/2013 (tab stop)
  1186 00001825 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  1187 00001827 75BF                <1> 	jne	short u0
  1188 00001829 88D0                <1> 	mov	al, dl
  1189 0000182B 6698                <1> 	cbw
  1190 0000182D B108                <1> 	mov	cl, 8
  1191 0000182F F6F1                <1> 	div	cl
  1192 00001831 28E1                <1> 	sub	cl, ah
  1193                              <1> ts:
  1194                              <1> 	; 02/09/2014
  1195                              <1> 	; 01/09/2014
  1196 00001833 B020                <1> 	mov	al, 20h
  1197                              <1> tsloop:
  1198 00001835 6651                <1> 	push	cx
  1199 00001837 6650                <1> 	push	ax
  1200 00001839 30FF                <1> 	xor 	bh, bh
  1201                              <1> 	;mov	bl, [ACTIVE_PAGE]
  1202 0000183B E896FFFFFF          <1> 	call	m3
  1203 00001840 6658                <1> 	pop	ax  ; ah = attribute/color
  1204 00001842 6659                <1> 	pop	cx
  1205 00001844 FEC9                <1> 	dec	cl
  1206 00001846 75ED                <1> 	jnz	short tsloop
  1207 00001848 C3                  <1> 	retn
  1208                              <1> bs:	
  1209                              <1> 	; back space found
  1210                              <1> 
  1211 00001849 08D2                <1> 	or	dl, dl 		; is it already at start of line
  1212                              <1> 	;je	short u7 	; set_cursor
  1213 0000184B 7406                <1> 	jz	short _set_cpos
  1214 0000184D 664A                <1> 	dec	dx     		; no -- just move it back
  1215                              <1> 	;jmp	short u7
  1216 0000184F EB02                <1> 	jmp	short _set_cpos
  1217                              <1> 
  1218                              <1> 	; carriage return found
  1219                              <1> u9:
  1220 00001851 B200                <1> 	mov	dl, 0 		; move to first column
  1221                              <1> 	;jmp	short u7
  1222                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  1223                              <1> 
  1224                              <1> 	; line feed found
  1225                              <1> ;u10:
  1226                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  1227                              <1> ;	jne	short u6 	; no, just set the cursor
  1228                              <1> ;       jmp     u1              ; yes, scroll the screen
  1229                              <1> 
  1230                              <1> _set_cpos:
  1231                              <1> 	; 27/06/2015
  1232                              <1> 	; 01/09/2014
  1233                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1234                              <1> 	;
  1235                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  1236                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  1237                              <1> 	;
  1238                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1239                              <1> 	;
  1240                              <1> ;----------------------------------------------
  1241                              <1> ; SET_CPOS
  1242                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  1243                              <1> ;	NEW X-Y VALUES PASSED
  1244                              <1> ; INPUT
  1245                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  1246                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  1247                              <1> ; OUTPUT
  1248                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  1249                              <1> ;----------------------------------------------
  1250                              <1> 	;
  1251 00001853 BE[F8CE0000]        <1> 	mov	esi, CURSOR_POSN
  1252 00001858 0FB6C3              <1>         movzx   eax, bl	; BL = video page number ; 27/06/2015 (movzx)
  1253                              <1> ;	or	al, al
  1254                              <1> ;	jz	short _set_cpos_0
  1255 0000185B D0E0                <1>         shl     al, 1   ; word offset
  1256 0000185D 01C6                <1>         add     esi, eax
  1257                              <1> ;_set_cpos_0:
  1258 0000185F 668916              <1> 	mov	[esi], dx ; save the pointer
  1259 00001862 381D[08CF0000]      <1> 	cmp	[ACTIVE_PAGE], bl
  1260 00001868 7532                <1> 	jne	short m17
  1261                              <1> 	;call	m18	; CURSOR SET
  1262                              <1> ;m17:			; SET_CPOS_RETURN
  1263                              <1> 	; 01/09/2014
  1264                              <1> ;	retn
  1265                              <1> 		; DX  = row/column
  1266                              <1> m18:
  1267 0000186A E861FDFFFF          <1> 	call	position ; determine location in regen buffer	
  1268 0000186F 668B0D[F4CE0000]    <1> 	mov	cx, [CRT_START]
  1269 00001876 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  1270                              <1> 			; to the start address (offset) for this page
  1271 00001879 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  1272 0000187C B40E                <1> 	mov	ah, 14	; register number for cursor
  1273                              <1> 	;call	m16	; output value to the 6845	
  1274                              <1> 	;retn
  1275                              <1> 
  1276                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  1277                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  1278                              <1> m16:
  1279 0000187E FA                  <1> 	cli
  1280                              <1> 	;mov	dx, [addr_6845] ; address register
  1281 0000187F 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  1282 00001883 88E0                <1> 	mov	al, ah	; get value
  1283 00001885 EE                  <1> 	out	dx, al	; register set
  1284 00001886 6642                <1> 	inc	dx	; data register
  1285 00001888 EB00                <1> 	jmp	$+2	; i/o delay
  1286 0000188A 88E8                <1> 	mov	al, ch	; data
  1287 0000188C EE                  <1> 	out	dx, al	
  1288 0000188D 664A                <1> 	dec	dx	
  1289 0000188F 88E0                <1> 	mov	al, ah
  1290 00001891 FEC0                <1> 	inc	al	; point to other data register
  1291 00001893 EE                  <1> 	out	dx, al	; set for second register
  1292 00001894 6642                <1> 	inc	dx
  1293 00001896 EB00                <1> 	jmp	$+2	; i/o delay
  1294 00001898 88C8                <1> 	mov	al, cl	; second data value
  1295 0000189A EE                  <1> 	out	dx, al
  1296 0000189B FB                  <1> 	sti
  1297                              <1> m17:
  1298 0000189C C3                  <1> 	retn
  1299                              <1> 
  1300                              <1> beeper: 
  1301                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1302                              <1> 	; 18/01/2014
  1303                              <1> 	; 03/12/2013
  1304                              <1> 	; bell found
  1305                              <1> u11:
  1306 0000189D FB                  <1> 	sti
  1307 0000189E 3A1D[08CF0000]      <1> 	cmp	bl, [ACTIVE_PAGE]
  1308 000018A4 7551                <1> 	jne	short u12	; Do not sound the beep 
  1309                              <1> 				; if it is not written on the active page
  1310 000018A6 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  1311 000018AA B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  1312                              <1> 	;call	beep		; sound the pod bell
  1313                              <1> 	;jmp	short u5 	; tty_return
  1314                              <1> 	;retn
  1315                              <1> 	
  1316                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  1317                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  1318                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  1319                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  1320                              <1> 
  1321                              <1> beep:
  1322                              <1> 	; 07/02/2015
  1323                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1324                              <1> 	; 18/01/2014
  1325                              <1> 	; 03/12/2013
  1326                              <1> 	;
  1327                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  1328                              <1> 	;
  1329                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  1330                              <1> 	;
  1331                              <1> 	; ENTRY:
  1332                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  1333                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  1334                              <1> 	; EXIT:				:
  1335                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  1336                              <1> 
  1337 000018AC 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  1338 000018AD FA                  <1> 	cli			; block interrupts during update
  1339 000018AE B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  1340 000018B0 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  1341 000018B2 EB00                <1> 	jmp	$+2		; I/O delay
  1342 000018B4 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  1343 000018B6 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  1344 000018B8 EB00                <1> 	jmp	$+2		; I/O delay
  1345 000018BA 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  1346 000018BC E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  1347 000018BE E461                <1> 	in	al, PORT_B	; get current setting of port
  1348 000018C0 88C4                <1> 	mov	ah, al		; save that setting
  1349 000018C2 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  1350 000018C4 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  1351                              <1> 	;popf	; 18/01/2014
  1352 000018C6 FB                  <1> 	sti
  1353                              <1> g7:				; 1/64 second per count (bl)
  1354 000018C7 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  1355 000018CC E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  1356 000018D1 FECB                <1> 	dec	bl		; (bl) length count expired?
  1357 000018D3 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  1358                              <1> 	;
  1359                              <1> 	;pushf			; save interrupt status
  1360 000018D5 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  1361 000018D6 E461                <1> 	in	al, PORT_B	; get current port value
  1362                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  1363 000018D8 0CFC                <1>         or      al, ~(GATE2+SPK2)
  1364 000018DA 20C4                <1>         and	ah, al		; someone turned them off during beep
  1365 000018DC 88E0                <1> 	mov	al, ah		; recover value of port
  1366                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  1367 000018DE 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  1368 000018E0 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  1369                              <1> 	;popf			; restore interrupt flag state
  1370 000018E2 FB                  <1> 	sti
  1371 000018E3 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  1372 000018E8 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  1373                              <1> 	;pushf			; save interrupt status
  1374 000018ED FA                  <1> 	cli			; block interrupts during update
  1375 000018EE E461                <1> 	in	al, PORT_B	; get current port value in case	
  1376 000018F0 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  1377 000018F2 08E0                <1> 	or	al, ah		; recover value of port_b
  1378 000018F4 E661                <1> 	out	PORT_B, al	; restore speaker status
  1379 000018F6 9D                  <1> 	popf			; restore interrupt flag state
  1380                              <1> u12:	
  1381 000018F7 C3                  <1> 	retn
  1382                              <1> 
  1383                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  1384                              <1> 
  1385                              <1> WAITF:
  1386                              <1> waitf:
  1387                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1388                              <1> 	; 03/12/2013
  1389                              <1> 	;
  1390                              <1> ;	push ax			; save work register (ah)	
  1391                              <1> ;waitf1:
  1392                              <1> 				; use timer 1 output bits
  1393                              <1> ;	in	al, PORT_B	; read current counter output status
  1394                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  1395                              <1> ;	cmp	al, ah		; did it just change
  1396                              <1> ;	je	short waitf1	; wait for a change in output line
  1397                              <1> ;	;
  1398                              <1> ;	mov	ah, al		; save new lflag state
  1399                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  1400                              <1> ;	;
  1401                              <1> ;	pop	ax		; restore (ah)
  1402                              <1> ;	retn			; return (cx)=0
  1403                              <1> 
  1404                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  1405                              <1> ; 17/12/2014 (dsectrm2.s)
  1406                              <1> ; WAITF
  1407                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  1408                              <1> ;
  1409                              <1> ;---WAITF-----------------------------------------------------------------------
  1410                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  1411                              <1> ; ENTRY:
  1412                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  1413                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  1414                              <1> ; EXIT:
  1415                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  1416                              <1> ;	(CX) = 0	
  1417                              <1> ;-------------------------------------------------------------------------------
  1418                              <1> 
  1419                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  1420                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  1421                              <1> 
  1422                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  1423 000018F8 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  1424                              <1> 	; 16/12/2014
  1425                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  1426 000018FA D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  1427                              <1> ;17/12/2014	
  1428                              <1> ;WAITF1:
  1429                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  1430                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  1431                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  1432                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  1433                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  1434                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  1435                              <1> 	;
  1436                              <1> 	; 17/12/2014
  1437                              <1> 	;
  1438                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  1439                              <1> 	;
  1440                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  1441                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  1442                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  1443                              <1> WR_STATE_0:
  1444 000018FC E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1445 000018FE A810                <1> 	TEST	AL,010H
  1446 00001900 74FA                <1> 	JZ	SHORT WR_STATE_0
  1447                              <1> WR_STATE_1:
  1448 00001902 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1449 00001904 A810                <1> 	TEST	AL,010H
  1450 00001906 75FA                <1> 	JNZ	SHORT WR_STATE_1
  1451 00001908 E2F2                <1>         LOOP    WR_STATE_0
  1452                              <1> 	;
  1453 0000190A 6658                <1> 	POP	AX			; RESTORE (AH)
  1454 0000190C C3                  <1> 	RETn				; (CX) = 0
  1455                              <1> 
  1456                              <1> ; % include 'vidata.s' ; VIDEO DATA
  1457                              <1> 
  1458                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1703                                  
  1704                                  setup_rtc_int:
  1705                                  ; source: http://wiki.osdev.org/RTC
  1706 0000190D FA                      	cli		; disable interrupts
  1707                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  1708                                  	; in order to change this ...
  1709                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  1710                                  	; (rate must be above 2 and not over 15)
  1711                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  1712 0000190E B08A                    	mov	al, 8Ah 
  1713 00001910 E670                    	out	70h, al ; set index to register A, disable NMI
  1714 00001912 90                      	nop
  1715 00001913 E471                    	in	al, 71h ; get initial value of register A
  1716 00001915 88C4                    	mov 	ah, al
  1717 00001917 80E4F0                  	and	ah, 0F0h
  1718 0000191A B08A                    	mov	al, 8Ah 
  1719 0000191C E670                    	out	70h, al ; reset index to register A
  1720 0000191E 88E0                    	mov	al, ah
  1721 00001920 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1722 00001922 E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1723                                  	; enable RTC interrupt
  1724 00001924 B08B                    	mov	al, 8Bh ;
  1725 00001926 E670                    	out	70h, al ; select register B and disable NMI
  1726 00001928 90                      	nop
  1727 00001929 E471                    	in	al, 71h ; read the current value of register B
  1728 0000192B 88C4                    	mov	ah, al  ;
  1729 0000192D B08B                    	mov 	al, 8Bh ;
  1730 0000192F E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1731 00001931 88E0                    	mov	al, ah  ;
  1732 00001933 0C40                    	or	al, 40h ;
  1733 00001935 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1734 00001937 FB                      	sti
  1735 00001938 C3                      	retn
  1736                                  
  1737                                  ; Write memory information
  1738                                  ; 29/01/2016
  1739                                  ; 06/11/2014
  1740                                  ; 14/08/2015 
  1741                                  memory_info:	
  1742 00001939 A1[DCCE0000]            	mov	eax, [memory_size] ; in pages
  1743 0000193E 50                      	push	eax
  1744 0000193F C1E00C                  	shl	eax, 12		   ; in bytes
  1745 00001942 BB0A000000              	mov	ebx, 10
  1746 00001947 89D9                    	mov	ecx, ebx	   ; 10
  1747 00001949 BE[E7CA0000]            	mov	esi, mem_total_b_str	
  1748 0000194E E8BE000000              	call	bintdstr
  1749 00001953 58                      	pop	eax
  1750 00001954 B107                    	mov	cl, 7
  1751 00001956 BE[0BCB0000]            	mov	esi, mem_total_p_str
  1752 0000195B E8B1000000              	call	bintdstr	
  1753                                  	; 14/08/2015
  1754 00001960 E8C9000000              	call	calc_free_mem
  1755                                  	; edx = calculated free pages
  1756                                  	; ecx = 0
  1757 00001965 A1[E0CE0000]            	mov 	eax, [free_pages]
  1758 0000196A 39D0                    	cmp	eax, edx ; calculated free mem value 
  1759                                  		; and initial free mem value are same or not?
  1760 0000196C 751D                    	jne 	short pmim ; print mem info with '?' if not
  1761 0000196E 52                      	push 	edx ; free memory in pages	
  1762                                  	;mov 	eax, edx
  1763 0000196F C1E00C                  	shl	eax, 12 ; convert page count
  1764                                  			; to byte count
  1765 00001972 B10A                    	mov	cl, 10
  1766 00001974 BE[2BCB0000]            	mov	esi, free_mem_b_str
  1767 00001979 E893000000              	call	bintdstr
  1768 0000197E 58                      	pop	eax
  1769 0000197F B107                    	mov	cl, 7
  1770 00001981 BE[4FCB0000]            	mov	esi, free_mem_p_str
  1771 00001986 E886000000              	call	bintdstr
  1772                                  pmim:
  1773 0000198B BE[D5CA0000]            	mov	esi, msg_memory_info
  1774                                  	;
  1775 00001990 B407                    	mov	ah, 07h ; Black background, 
  1776                                  			; light gray forecolor
  1777                                  print_kmsg: ; 29/01/2016
  1778 00001992 8825[09CF0000]          	mov	[ccolor], ah
  1779                                  pkmsg_loop:
  1780 00001998 AC                      	lodsb
  1781 00001999 08C0                    	or	al, al
  1782 0000199B 7411                    	jz	short pkmsg_ok
  1783 0000199D 56                      	push	esi
  1784 0000199E 31DB                    	xor	ebx, ebx ; 0
  1785                                  			; Video page 0 (bl=0)
  1786 000019A0 8A25[09CF0000]          	mov	ah, [ccolor]
  1787 000019A6 E814FEFFFF              	call	WRITE_TTY
  1788 000019AB 5E                      	pop	esi
  1789 000019AC EBEA                    	jmp	short pkmsg_loop
  1790                                  pkmsg_ok:
  1791 000019AE C3                      	retn
  1792                                  
  1793                                  ; Convert binary number to hexadecimal string
  1794                                  ; 10/05/2015  
  1795                                  ; dsectpm.s (28/02/2015)
  1796                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  1797                                  ; 01/12/2014
  1798                                  ; 25/11/2014
  1799                                  ;
  1800                                  bytetohex:
  1801                                  	; INPUT ->
  1802                                  	; 	AL = byte (binary number)
  1803                                  	; OUTPUT ->
  1804                                  	;	AX = hexadecimal string
  1805                                  	;
  1806 000019AF 53                      	push	ebx
  1807 000019B0 31DB                    	xor	ebx, ebx
  1808 000019B2 88C3                    	mov	bl, al
  1809 000019B4 C0EB04                  	shr	bl, 4
  1810 000019B7 8A9B[011A0000]          	mov	bl, [ebx+hexchrs] 	 	
  1811 000019BD 86D8                    	xchg	bl, al
  1812 000019BF 80E30F                  	and	bl, 0Fh
  1813 000019C2 8AA3[011A0000]          	mov	ah, [ebx+hexchrs] 
  1814 000019C8 5B                      	pop	ebx	
  1815 000019C9 C3                      	retn
  1816                                  
  1817                                  wordtohex:
  1818                                  	; INPUT ->
  1819                                  	; 	AX = word (binary number)
  1820                                  	; OUTPUT ->
  1821                                  	;	EAX = hexadecimal string
  1822                                  	;
  1823 000019CA 53                      	push	ebx
  1824 000019CB 31DB                    	xor	ebx, ebx
  1825 000019CD 86E0                    	xchg	ah, al
  1826 000019CF 6650                    	push	ax
  1827 000019D1 88E3                    	mov	bl, ah
  1828 000019D3 C0EB04                  	shr	bl, 4
  1829 000019D6 8A83[011A0000]          	mov	al, [ebx+hexchrs] 	 	
  1830 000019DC 88E3                    	mov	bl, ah
  1831 000019DE 80E30F                  	and	bl, 0Fh
  1832 000019E1 8AA3[011A0000]          	mov	ah, [ebx+hexchrs]
  1833 000019E7 C1E010                  	shl	eax, 16
  1834 000019EA 6658                    	pop	ax
  1835 000019EC 5B                      	pop	ebx
  1836 000019ED EBC0                    	jmp	short bytetohex
  1837                                  	;mov	bl, al
  1838                                  	;shr	bl, 4
  1839                                  	;mov	bl, [ebx+hexchrs] 	 	
  1840                                  	;xchg	bl, al	 	
  1841                                  	;and	bl, 0Fh
  1842                                  	;mov	ah, [ebx+hexchrs] 
  1843                                  	;pop	ebx	
  1844                                  	;retn
  1845                                  
  1846                                  dwordtohex:
  1847                                  	; INPUT ->
  1848                                  	; 	EAX = dword (binary number)
  1849                                  	; OUTPUT ->
  1850                                  	;	EDX:EAX = hexadecimal string
  1851                                  	;
  1852 000019EF 50                      	push	eax
  1853 000019F0 C1E810                  	shr	eax, 16
  1854 000019F3 E8D2FFFFFF              	call	wordtohex
  1855 000019F8 89C2                    	mov	edx, eax
  1856 000019FA 58                      	pop	eax
  1857 000019FB E8CAFFFFFF              	call	wordtohex
  1858 00001A00 C3                      	retn
  1859                                  
  1860                                  ; 10/05/2015
  1861                                  hex_digits:
  1862                                  hexchrs:
  1863 00001A01 303132333435363738-     	db '0123456789ABCDEF'
  1863 00001A0A 39414243444546     
  1864                                  
  1865                                  ; Convert binary number to decimal/numeric string
  1866                                  ; 06/11/2014
  1867                                  ; Temporary Code
  1868                                  ;
  1869                                  
  1870                                  bintdstr:
  1871                                  	; EAX = binary number
  1872                                  	; ESI = decimal/numeric string address
  1873                                  	; EBX = divisor (10)
  1874                                  	; ECX = string length (<=10)
  1875 00001A11 01CE                    	add	esi, ecx
  1876                                  btdstr0:
  1877 00001A13 4E                      	dec	esi
  1878 00001A14 31D2                    	xor	edx, edx
  1879 00001A16 F7F3                    	div	ebx
  1880 00001A18 80C230                  	add	dl, 30h
  1881 00001A1B 8816                    	mov	[esi], dl
  1882 00001A1D FEC9                    	dec	cl
  1883 00001A1F 740C                    	jz	btdstr2
  1884 00001A21 09C0                    	or	eax, eax
  1885 00001A23 75EE                    	jnz	short btdstr0
  1886                                  btdstr1:
  1887 00001A25 4E                      	dec	esi
  1888 00001A26 C60620                          mov     byte [esi], 20h ; blank space
  1889 00001A29 FEC9                    	dec	cl
  1890 00001A2B 75F8                    	jnz	short btdstr1
  1891                                  btdstr2:
  1892 00001A2D C3                      	retn
  1893                                  
  1894                                  ; Calculate free memory pages on M.A.T.
  1895                                  ; 06/11/2014
  1896                                  ; Temporary Code
  1897                                  ;
  1898                                  
  1899                                  calc_free_mem:
  1900 00001A2E 31D2                    	xor	edx, edx
  1901                                  	;xor	ecx, ecx
  1902 00001A30 668B0D[F0CE0000]        	mov	cx, [mat_size] ; in pages
  1903 00001A37 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  1904 00001A3A BE00001000              	mov	esi, MEM_ALLOC_TBL
  1905                                  cfm0:
  1906 00001A3F AD                      	lodsd
  1907 00001A40 51                      	push	ecx
  1908 00001A41 B920000000              	mov	ecx, 32
  1909                                  cfm1:
  1910 00001A46 D1E8                    	shr	eax, 1
  1911 00001A48 7301                    	jnc	short cfm2
  1912 00001A4A 42                      	inc	edx
  1913                                  cfm2:
  1914 00001A4B E2F9                    	loop	cfm1
  1915 00001A4D 59                      	pop	ecx
  1916 00001A4E E2EF                    	loop	cfm0
  1917 00001A50 C3                      	retn
  1918                                  
  1919                                  %include 'diskio.s'  ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskio.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskio.inc (22/08/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKIO.INC
    20                              <1> ; Last Modification: 22/08/2015
    21                              <1> ; 	(Initialized Disk Parameters Data is in 'DISKDATA.INC') 
    22                              <1> ; 	(Uninitialized Disk Parameters Data is in 'DISKBSS.INC') 
    23                              <1> 
    24                              <1> ; DISK I/O SYSTEM - Erdogan Tan (Retro UNIX 386 v1 project)
    25                              <1> 
    26                              <1> ; ///////// DISK I/O SYSTEM ///////////////
    27                              <1> 
    28                              <1> ; 06/02/2015
    29                              <1> diskette_io:
    30 00001A51 9C                  <1> 	pushfd
    31 00001A52 0E                  <1> 	push 	cs
    32 00001A53 E809000000          <1> 	call 	DISKETTE_IO_1
    33 00001A58 C3                  <1> 	retn
    34                              <1> 	
    35                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
    36                              <1> ;//////////////////////////////////////////////////////
    37                              <1> 
    38                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
    39                              <1> ; 20/02/2015
    40                              <1> ; 06/02/2015 (unix386.s)
    41                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
    42                              <1> ;
    43                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
    44                              <1> ;
    45                              <1> ; ADISK.EQU
    46                              <1> 
    47                              <1> ;----- Wait control constants 
    48                              <1> 
    49                              <1> ;amount of time to wait while RESET is active.
    50                              <1> 
    51                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
    52                              <1> 						;at 250 KBS xfer rate.
    53                              <1> 						;see INTEL MCS, 1985, pg. 5-456
    54                              <1> 
    55                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
    56                              <1> 						;status register to become valid
    57                              <1> 						;before re-reading.
    58                              <1> 
    59                              <1> ;After sending a byte to NEC, status register may remain
    60                              <1> ;incorrectly set for 24 us.
    61                              <1> 
    62                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
    63                              <1> 						;RQM low.
    64                              <1> 
    65                              <1> ; COMMON.MAC
    66                              <1> ;
    67                              <1> ;	Timing macros
    68                              <1> ;
    69                              <1> 
    70                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
    71                              <1> 		jmp short $+2
    72                              <1> %endmacro		
    73                              <1> 
    74                              <1> %macro		IODELAY  0			; NORMAL IODELAY
    75                              <1> 		jmp short $+2
    76                              <1> 		jmp short $+2
    77                              <1> %endmacro
    78                              <1> 
    79                              <1> %macro		NEWIODELAY 0
    80                              <1> 		out	0ebh,al
    81                              <1> %endmacro 
    82                              <1> 
    83                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
    84                              <1> ;;; WAIT_FOR_MEM
    85                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
    86                              <1> ;WAIT_FDU_INT_HI	equ	1
    87                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
    88                              <1> ;;; WAIT_FOR_PORT
    89                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
    90                              <1> ;WAIT_FDU_SEND_HI	equ	0
    91                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
    92                              <1> ;Time to wait while waiting for each byte of NEC results = .5
    93                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
    94                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
    95                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
    96                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
    97                              <1> ;;; WAIT_REFRESH
    98                              <1> ;amount of time to wait for head settle, per unit in parameter
    99                              <1> ;table = 1 ms.
   100                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
   101                              <1> 
   102                              <1> 
   103                              <1> ; //////////////// DISKETTE I/O ////////////////
   104                              <1> 
   105                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
   106                              <1> 
   107                              <1> ;----------------------------------------
   108                              <1> ;	EQUATES USED BY POST AND BIOS	:
   109                              <1> ;----------------------------------------
   110                              <1> 
   111                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   112                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   113                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
   114                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
   115                              <1> 
   116                              <1> ;----------------------------------------
   117                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
   118                              <1> ;-------------------------------------------------------------------------------
   119                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
   120                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
   121                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
   122                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
   123                              <1> 
   124                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
   125                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
   126                              <1> ;		EQU	011H		; - RESERVED			      ;C
   127                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
   128                              <1> ;		EQU	013H		; - RESERVED			      ;E
   129                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
   130                              <1> 
   131                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
   132                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
   133                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
   134                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
   135                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
   136                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
   137                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
   138                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
   139                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
   140                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
   141                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
   142                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
   143                              <1> 
   144                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
   145                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
   146                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
   147                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
   148                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
   149                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
   150                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
   151                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
   152                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
   153                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
   154                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
   155                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
   156                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
   157                              <1> 
   158                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
   159                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
   160                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
   161                              <1> 
   162                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
   163                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
   164                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
   165                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
   166                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
   167                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
   168                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
   169                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
   170                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
   171                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
   172                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
   173                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
   174                              <1> 
   175                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
   176                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
   177                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
   178                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
   179                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
   180                              <1> 
   181                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
   182                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
   183                              <1> ;INTA00		EQU	020H		; 8259 PORT
   184                              <1> INTA01		EQU	021H		; 8259 PORT
   185                              <1> INTB00		EQU	0A0H		; 2ND 8259
   186                              <1> INTB01		EQU	0A1H		;
   187                              <1> 
   188                              <1> ;-------------------------------------------------------------------------------
   189                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
   190                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
   191                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
   192                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
   193                              <1> ;-------------------------------------------------------------------------------
   194                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
   195                              <1> 
   196                              <1> ;-------------------------------------------------------------------------------
   197                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
   198                              <1> 
   199                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
   200                              <1> ; (unix386.s <-- dsectrm2.s)
   201                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
   202                              <1> 
   203                              <1> ; 10/12/2014
   204                              <1> ;
   205                              <1> ;int40h:
   206                              <1> ;	pushf
   207                              <1> ;	push 	cs
   208                              <1> ;	;cli
   209                              <1> ;	call 	DISKETTE_IO_1
   210                              <1> ;	retn
   211                              <1> 
   212                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
   213                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
   214                              <1> ;
   215                              <1> 
   216                              <1> ;-- INT13H ---------------------------------------------------------------------
   217                              <1> ; DISKETTE I/O
   218                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
   219                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
   220                              <1> ; INPUT
   221                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
   222                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
   223                              <1> ;		ON ALL DRIVES
   224                              <1> ;------------------------------------------------------------------------------- 
   225                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
   226                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
   227                              <1> ;-------------------------------------------------------------------------------
   228                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
   229                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   230                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
   231                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
   232                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
   233                              <1> ;		320/360	320/360	    0-39
   234                              <1> ;		320/360	1.2M	    0-39
   235                              <1> ;		1.2M	1.2M	    0-79
   236                              <1> ;		720K	720K	    0-79
   237                              <1> ;		1.44M	1.44M	    0-79	
   238                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
   239                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
   240                              <1> ;		320/360	320/360	     1-8/9
   241                              <1> ;		320/360	1.2M	     1-8/9
   242                              <1> ;		1.2M	1.2M	     1-15
   243                              <1> ;		720K	720K	     1-9
   244                              <1> ;		1.44M	1.44M	     1-18		
   245                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
   246                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
   247                              <1> ;		320/360	320/360	        8/9
   248                              <1> ;		320/360	1.2M	        8/9
   249                              <1> ;		1.2M	1.2M		15
   250                              <1> ;		720K	720K		9
   251                              <1> ;		1.44M	1.44M		18
   252                              <1> ;
   253                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
   254                              <1> ;
   255                              <1> ;-------------------------------------------------------------------------------
   256                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
   257                              <1> ;-------------------------------------------------------------------------------
   258                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
   259                              <1> ;-------------------------------------------------------------------------------
   260                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
   261                              <1> ;-------------------------------------------------------------------------------
   262                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
   263                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
   264                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
   265                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
   266                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
   267                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
   268                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
   269                              <1> ;		READ/WRITE ACCESS.
   270                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
   271                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
   272                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
   273                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
   274                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
   275                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
   276                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
   277                              <1> ;
   278                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
   279                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
   280                              <1> ;		---------------------------------------------
   281                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
   282                              <1> ;		---------------------------------------------
   283                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
   284                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
   285                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
   286                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
   287                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
   288                              <1> ;		---------------------------------------------
   289                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
   290                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
   291                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
   292                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
   293                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
   294                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
   295                              <1> ;-------------------------------------------------------------------------------
   296                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
   297                              <1> ;	REGISTERS
   298                              <1> ;	  INPUT
   299                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   300                              <1> ;	  OUTPUT
   301                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
   302                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
   303                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   304                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   305                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
   306                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
   307                              <1> ;	    (BH) - 0
   308                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
   309                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
   310                              <1> ;	    (AX) - 0
   311                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
   312                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
   313                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
   314                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
   315                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
   316                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
   317                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
   318                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
   319                              <1> ;-------------------------------------------------------------------------------
   320                              <1> ;	(AH)= 15H  READ DASD TYPE
   321                              <1> ;	OUTPUT REGISTERS
   322                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
   323                              <1> ;		00 - DRIVE NOT PRESENT	
   324                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
   325                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
   326                              <1> ;		03 - RESERVED (FIXED DISK)
   327                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   328                              <1> ;-------------------------------------------------------------------------------
   329                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
   330                              <1> ;	OUTPUT REGISTERS
   331                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
   332                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
   333                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   334                              <1> ;-------------------------------------------------------------------------------
   335                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
   336                              <1> ;	INPUT REGISTERS
   337                              <1> ;	(AL) -	00 - NOT USED	
   338                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
   339                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
   340                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
   341                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
   342                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
   343                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
   344                              <1> ;-------------------------------------------------------------------------------
   345                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
   346                              <1> ;	INPUT REGISTERS
   347                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
   348                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   349                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   350                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
   351                              <1> ;	OUTPUT REGISTERS:
   352                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
   353                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
   354                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
   355                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
   356                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
   357                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
   358                              <1> ;-------------------------------------------------------------------------------
   359                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
   360                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
   361                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
   362                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
   363                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
   364                              <1> ;		CHANGE ERROR CODE
   365                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
   366                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
   367                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
   368                              <1> ;
   369                              <1> ; DATA VARIABLE -- @DISK_POINTER
   370                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
   371                              <1> ;-------------------------------------------------------------------------------
   372                              <1> ; OUTPUT FOR ALL FUNCTIONS
   373                              <1> ;	AH = STATUS OF OPERATION
   374                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
   375                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
   376                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
   377                              <1> ;		TYPE AH=(15)).
   378                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
   379                              <1> ;	FOR READ/WRITE/VERIFY
   380                              <1> ;		DS,BX,DX,CX PRESERVED
   381                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
   382                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
   383                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
   384                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
   385                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
   386                              <1> ;-------------------------------------------------------------------------------
   387                              <1> ;
   388                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
   389                              <1> ;
   390                              <1> ;   -----------------------------------------------------------------
   391                              <1> ;   |       |       |       |       |       |       |       |       |
   392                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
   393                              <1> ;   |       |       |       |       |       |       |       |       |
   394                              <1> ;   -----------------------------------------------------------------
   395                              <1> ;	|	|	|	|	|	|	|	|
   396                              <1> ;	|	|	|	|	|	-----------------
   397                              <1> ;	|	|	|	|	|		|
   398                              <1> ;	|	|	|	|    RESERVED		|
   399                              <1> ;	|	|	|	|		  PRESENT STATE
   400                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
   401                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
   402                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
   403                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
   404                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
   405                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
   406                              <1> ;	|	|	|	|	110: RESERVED
   407                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
   408                              <1> ;	|	|	|	|
   409                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
   410                              <1> ;	|	|	|
   411                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
   412                              <1> ;	|	|			DRIVE)
   413                              <1> ;	|	|
   414                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
   415                              <1> ;
   416                              <1> ;						00: 500 KBS
   417                              <1> ;						01: 300 KBS
   418                              <1> ;						10: 250 KBS
   419                              <1> ;						11: RESERVED
   420                              <1> ;
   421                              <1> ;
   422                              <1> ;-------------------------------------------------------------------------------
   423                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
   424                              <1> ;-------------------------------------------------------------------------------
   425                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
   426                              <1> ;-------------------------------------------------------------------------------
   427                              <1> 
   428                              <1> struc MD
   429 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   430 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   431 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   432 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
   433 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
   434 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
   435 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
   436 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
   437 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
   438 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
   439 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
   440 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
   441 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
   442                              <1> endstruc
   443                              <1> 
   444                              <1> BIT7OFF	EQU	7FH
   445                              <1> BIT7ON	EQU	80H
   446                              <1> 
   447                              <1> ;;int13h: ; 16/02/2015
   448                              <1> ;; 16/02/2015 - 21/02/2015
   449                              <1> int40h:
   450 00001A59 9C                  <1> 	pushfd
   451 00001A5A 0E                  <1> 	push 	cs
   452 00001A5B E801000000          <1> 	call 	DISKETTE_IO_1
   453 00001A60 C3                  <1> 	retn	
   454                              <1> 
   455                              <1> DISKETTE_IO_1:
   456                              <1> 
   457 00001A61 FB                  <1> 	STI				; INTERRUPTS BACK ON
   458 00001A62 55                  <1> 	PUSH	eBP			; USER REGISTER
   459 00001A63 57                  <1> 	PUSH	eDI			; USER REGISTER
   460 00001A64 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   461 00001A65 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   462 00001A66 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   463 00001A67 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
   464                              <1> 					; [BP]   = SECTOR #
   465                              <1> 					; [BP+1] = TRACK #
   466                              <1> 					; [BP+2] = BUFFER OFFSET
   467                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
   468                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
   469                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
   470                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
   471                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
   472                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
   473                              <1> 					; BH/[BP+3] = 0
   474                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
   475                              <1> 					; DH/[BP+5] = MAX HEAD #
   476                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
   477 00001A69 06                  <1> 	push	es ; 06/02/2015	
   478 00001A6A 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   479 00001A6B 56                  <1> 	PUSH	eSI			; USER REGISTERS
   480                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
   481                              <1> 	;mov	cx, cs
   482                              <1> 	;mov	ds, cx
   483 00001A6C 66B91000            <1> 	mov	cx, KDATA
   484 00001A70 8ED9                <1>         mov     ds, cx
   485 00001A72 8EC1                <1>         mov     es, cx
   486                              <1> 
   487                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   488 00001A74 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
   489 00001A77 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   490 00001A79 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   491                              <1> OK_FUNC:
   492 00001A7B 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   493 00001A7E 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   494 00001A80 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   495 00001A83 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   496 00001A85 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   497 00001A88 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   498 00001A8A B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   499                              <1> OK_DRV:
   500 00001A8C 31C9                <1> 	xor	ecx, ecx
   501                              <1> 	;mov	esi, ecx ; 08/02/2015
   502 00001A8E 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   503 00001A90 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   504                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   505                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   506 00001A92 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   507 00001A95 BB[CD1A0000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   508 00001A9A 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   509 00001A9C 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   510 00001A9E 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   511 00001AA0 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   512 00001AA3 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   513                              <1> 	;
   514                              <1> 	; 11/12/2014
   515 00001AA6 8815[61C90000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   516                              <1> 	;
   517 00001AAC 8A25[64CF0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   518 00001AB2 C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
   519                              <1> 
   520                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
   521                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
   522                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
   523                              <1> ;
   524                              <1> ;		DI	: DRIVE #
   525                              <1> ;		SI-HI	: HEAD #
   526                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
   527                              <1> ;		ES	: BUFFER SEGMENT
   528                              <1> ;		[BP]	: SECTOR #
   529                              <1> ;		[BP+1]	: TRACK #
   530                              <1> ;		[BP+2]	: BUFFER OFFSET
   531                              <1> ;
   532                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
   533                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
   534                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
   535                              <1> ;	SPECIFIC ERROR CODE.
   536                              <1> ;
   537                              <1> 					; (AH) = @DSKETTE_STATUS
   538 00001AB9 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   539 00001ABB 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   540 00001ABC 1F                  <1> 	POP	DS
   541 00001ABD 07                  <1> 	pop	es	; 06/02/2015
   542 00001ABE 59                  <1> 	POP	eCX
   543 00001ABF 5B                  <1> 	POP	eBX
   544 00001AC0 5A                  <1> 	POP	eDX
   545 00001AC1 5F                  <1> 	POP	eDI
   546 00001AC2 89E5                <1> 	MOV	eBP, eSP
   547 00001AC4 50                  <1> 	PUSH	eAX
   548 00001AC5 9C                  <1> 	PUSHFd
   549 00001AC6 58                  <1> 	POP	eAX
   550                              <1> 	;MOV	[BP+6], AX
   551 00001AC7 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   552 00001ACA 58                  <1> 	POP	eAX
   553 00001ACB 5D                  <1> 	POP	eBP
   554 00001ACC CF                  <1> 	IRETd
   555                              <1> 
   556                              <1> ;-------------------------------------------------------------------------------
   557                              <1> ; DW --> dd (06/02/2015)
   558 00001ACD [311B0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   559 00001AD1 [AA1B0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   560 00001AD5 [BB1B0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   561 00001AD9 [CC1B0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   562 00001ADD [DD1B0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   563 00001AE1 [EE1B0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   564 00001AE5 [731C0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   565 00001AE9 [731C0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   566 00001AED [801C0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   567 00001AF1 [731C0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   568 00001AF5 [731C0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   569 00001AF9 [731C0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   570 00001AFD [731C0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   571 00001B01 [731C0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   572 00001B05 [731C0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   573 00001B09 [731C0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   574 00001B0D [731C0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   575 00001B11 [731C0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   576 00001B15 [731C0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   577 00001B19 [731C0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   578 00001B1D [731C0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   579 00001B21 [411D0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   580 00001B25 [6C1D0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   581 00001B29 [A61D0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   582 00001B2D [291E0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
   583                              <1> FNC_TAE EQU     $                       ; END
   584                              <1> 
   585                              <1> ;-------------------------------------------------------------------------------
   586                              <1> ; DISK_RESET	(AH = 00H)	
   587                              <1> ;		RESET THE DISKETTE SYSTEM.
   588                              <1> ;
   589                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   590                              <1> ;-------------------------------------------------------------------------------
   591                              <1> DSK_RESET:
   592 00001B31 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   593 00001B35 FA                  <1> 	CLI				; NO INTERRUPTS
   594 00001B36 A0[62CF0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   595 00001B3B 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   596 00001B3D C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   597                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   598 00001B40 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   599 00001B42 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   600 00001B43 C605[61CF0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
   601                              <1> 	;JMP	$+2			; WAIT FOR I/O
   602                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
   603                              <1> 					;      PULSE WIDTH)
   604                              <1> 	; 19/12/2014
   605                              <1> 	NEWIODELAY
   605 00001B4A E6EB                <2>  out 0ebh,al
   606                              <1> 
   607                              <1> 	; 17/12/2014 
   608                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   609 00001B4C B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   610                              <1> wdw1:
   611                              <1> 	NEWIODELAY   ; 27/02/2015
   611 00001B51 E6EB                <2>  out 0ebh,al
   612 00001B53 E2FC                <1> 	loop	wdw1
   613                              <1> 	;
   614 00001B55 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   615 00001B57 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   616                              <1> 	; 16/12/2014
   617                              <1> 	IODELAY
   617 00001B58 EB00                <2>  jmp short $+2
   617 00001B5A EB00                <2>  jmp short $+2
   618                              <1> 	;
   619                              <1> 	;STI				; ENABLE THE INTERRUPTS
   620 00001B5C E8250C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   621 00001B61 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   622 00001B63 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   623                              <1> NXT_DRV:
   624 00001B67 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   625 00001B69 B8[9F1B0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   626 00001B6E 50                  <1> 	PUSH	eAX			; "
   627 00001B6F B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   628 00001B71 E8030B0000          <1> 	CALL	NEC_OUTPUT
   629 00001B76 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   630 00001B77 E83A0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   631 00001B7C 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   632 00001B7E 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   633 00001B80 3A0D[65CF0000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   634 00001B86 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   635 00001B88 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   636 00001B8A 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   637 00001B8D 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   638                              <1> 	;
   639 00001B8F E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   640                              <1> RESBAC:
   641 00001B94 E806090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   642 00001B99 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   643 00001B9C 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   644 00001B9E C3                  <1> 	RETn		
   645                              <1> DR_POP_ERR:
   646 00001B9F 6659                <1> 	POP	CX			; CLEAR STACK
   647                              <1> DR_ERR:
   648 00001BA1 800D[64CF0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   649 00001BA8 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
   650                              <1> 
   651                              <1> ;-------------------------------------------------------------------------------
   652                              <1> ; DISK_STATUS	(AH = 01H)
   653                              <1> ;	DISKETTE STATUS.
   654                              <1> ;
   655                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
   656                              <1> ;
   657                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
   658                              <1> ;-------------------------------------------------------------------------------
   659                              <1> DSK_STATUS:
   660 00001BAA 8825[64CF0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   661 00001BB0 E8EA080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   662 00001BB5 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   663 00001BB8 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   664 00001BBA C3                  <1> 	RETn		
   665                              <1> 
   666                              <1> ;-------------------------------------------------------------------------------
   667                              <1> ; DISK_READ	(AH = 02H)	
   668                              <1> ;	DISKETTE READ.
   669                              <1> ;
   670                              <1> ; ON ENTRY:	DI	: DRIVE #
   671                              <1> ;		SI-HI	: HEAD #
   672                              <1> ;		SI-LOW	: # OF SECTORS
   673                              <1> ;		ES	: BUFFER SEGMENT
   674                              <1> ;		[BP]	: SECTOR #
   675                              <1> ;		[BP+1]	: TRACK #
   676                              <1> ;		[BP+2]	: BUFFER OFFSET
   677                              <1> ;
   678                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   679                              <1> ;-------------------------------------------------------------------------------
   680                              <1> 
   681                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   682                              <1> 
   683                              <1> DSK_READ:
   684 00001BBB 8025[62CF0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   685 00001BC2 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   686 00001BC6 E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   687 00001BCB C3                  <1> 	RETn
   688                              <1> 
   689                              <1> ;-------------------------------------------------------------------------------
   690                              <1> ; DISK_WRITE	(AH = 03H)
   691                              <1> ;	DISKETTE WRITE.
   692                              <1> ;
   693                              <1> ; ON ENTRY:	DI	: DRIVE #
   694                              <1> ;		SI-HI	: HEAD #
   695                              <1> ;		SI-LOW	: # OF SECTORS
   696                              <1> ;		ES	: BUFFER SEGMENT
   697                              <1> ;		[BP]	: SECTOR #
   698                              <1> ;		[BP+1]	: TRACK #
   699                              <1> ;		[BP+2]	: BUFFER OFFSET
   700                              <1> ;
   701                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   702                              <1> ;-------------------------------------------------------------------------------
   703                              <1> 
   704                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   705                              <1> 
   706                              <1> DSK_WRITE:
   707 00001BCC 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   708 00001BD0 800D[62CF0000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   709 00001BD7 E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   710 00001BDC C3                  <1> 	RETn
   711                              <1> 
   712                              <1> ;-------------------------------------------------------------------------------
   713                              <1> ; DISK_VERF	(AH = 04H)
   714                              <1> ;	DISKETTE VERIFY.
   715                              <1> ;
   716                              <1> ; ON ENTRY:	DI	: DRIVE #
   717                              <1> ;		SI-HI	: HEAD #
   718                              <1> ;		SI-LOW	: # OF SECTORS
   719                              <1> ;		ES	: BUFFER SEGMENT
   720                              <1> ;		[BP]	: SECTOR #
   721                              <1> ;		[BP+1]	: TRACK #
   722                              <1> ;		[BP+2]	: BUFFER OFFSET
   723                              <1> ;
   724                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   725                              <1> ;-------------------------------------------------------------------------------
   726                              <1> DSK_VERF:
   727 00001BDD 8025[62CF0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   728 00001BE4 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   729 00001BE8 E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   730 00001BED C3                  <1> 	RETn
   731                              <1> 
   732                              <1> ;-------------------------------------------------------------------------------
   733                              <1> ; DISK_FORMAT	(AH = 05H)
   734                              <1> ;	DISKETTE FORMAT.
   735                              <1> ;
   736                              <1> ; ON ENTRY:	DI	: DRIVE #
   737                              <1> ;		SI-HI	: HEAD #
   738                              <1> ;		SI-LOW	: # OF SECTORS
   739                              <1> ;		ES	: BUFFER SEGMENT
   740                              <1> ;		[BP]	: SECTOR #
   741                              <1> ;		[BP+1]	: TRACK #
   742                              <1> ;		[BP+2]	: BUFFER OFFSET
   743                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
   744                              <1> ;
   745                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   746                              <1> ;-------------------------------------------------------------------------------
   747                              <1> DSK_FORMAT:
   748 00001BEE E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   749 00001BF3 E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   750 00001BF8 800D[62CF0000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   751 00001BFF E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   752 00001C04 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   753 00001C06 E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   754 00001C0B E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   755 00001C10 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   756 00001C12 E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   757                              <1> FM_WR:
   758 00001C17 E873060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   759 00001C1C 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   760 00001C1E B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   761 00001C20 E8D0060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   762 00001C25 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   763 00001C27 B8[631C0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   764 00001C2C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   765 00001C2D B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   766 00001C2F E83F090000          <1> 	CALL	GET_PARM
   767 00001C34 E8400A0000          <1> 	CALL	NEC_OUTPUT
   768 00001C39 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   769 00001C3B E833090000          <1> 	CALL	GET_PARM
   770 00001C40 E8340A0000          <1> 	CALL	NEC_OUTPUT
   771 00001C45 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   772 00001C47 E827090000          <1> 	CALL	GET_PARM
   773 00001C4C E8280A0000          <1> 	CALL	NEC_OUTPUT
   774 00001C51 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   775 00001C53 E81B090000          <1> 	CALL	GET_PARM
   776 00001C58 E81C0A0000          <1> 	CALL	NEC_OUTPUT
   777 00001C5D 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   778 00001C5E E810070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   779                              <1> FM_DON:
   780 00001C63 E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   781 00001C68 E832080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   782 00001C6D 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   783 00001C70 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   784 00001C72 C3                  <1> 	RETn
   785                              <1> 
   786                              <1> ;-------------------------------------------------------------------------------
   787                              <1> ; FNC_ERR
   788                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
   789                              <1> ;	SET BAD COMMAND IN STATUS.
   790                              <1> ;
   791                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   792                              <1> ;-------------------------------------------------------------------------------
   793                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
   794 00001C73 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   795 00001C76 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   796 00001C78 8825[64CF0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   797 00001C7E F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   798 00001C7F C3                  <1> 	RETn
   799                              <1> 
   800                              <1> ;-------------------------------------------------------------------------------
   801                              <1> ; DISK_PARMS	(AH = 08H)	
   802                              <1> ;	READ DRIVE PARAMETERS.
   803                              <1> ;
   804                              <1> ; ON ENTRY:	DI : DRIVE #
   805                              <1> ;
   806                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
   807                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
   808                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
   809                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
   810                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
   811                              <1> ;		BH/[BP+3] = 0
   812                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
   813                              <1> ;		DH/[BP+5] = MAX HEAD #
   814                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
   815                              <1> ;		ES        = SEGMENT OF DISK_BASE
   816                              <1> ;		AX        = 0
   817                              <1> ;
   818                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
   819                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
   820                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
   821                              <1> ;		       CALLER.
   822                              <1> ;-------------------------------------------------------------------------------
   823                              <1> DSK_PARMS:
   824 00001C80 E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
   825                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
   826 00001C85 29D2                <1> 	sub     edx, edx ; 20/02/2015
   827 00001C87 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
   828                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
   829                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
   830                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
   831                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
   832                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
   833                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
   834                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
   835                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
   836                              <1> 	;sub	edx, edx
   837 00001C8A 66A1[6EC90000]      <1> 	mov     ax, [fd0_type]
   838 00001C90 6621C0              <1> 	and     ax, ax
   839 00001C93 7474                <1> 	jz      short NON_DRV
   840 00001C95 FEC2                <1> 	inc     dl
   841 00001C97 20E4                <1> 	and     ah, ah
   842 00001C99 7402                <1> 	jz      short STO_DL
   843 00001C9B FEC2                <1> 	inc     dl
   844                              <1> STO_DL:
   845                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   846 00001C9D 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   847 00001CA0 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   848 00001CA4 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
   849                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   850 00001CA6 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   851 00001CAA E8BB080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
   852                              <1> 	;;20/02/2015
   853                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
   854                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
   855 00001CAF 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
   856 00001CB1 E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   857 00001CB6 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
   858                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
   859 00001CB8 884504              <1>         mov	[ebp+4], al ; 06/02/2015
   860 00001CBB 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   861 00001CBE 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   862 00001CC1 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   863                              <1> CHK_EST:
   864 00001CC3 8AA7[71CF0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   865 00001CC9 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   866 00001CCC 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   867                              <1> USE_EST:
   868 00001CCE 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   869 00001CD1 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   870 00001CD4 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
   871                              <1> 
   872                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
   873                              <1> 
   874 00001CD6 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   875 00001CD8 E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   876 00001CDD 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   877 00001CE0 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   878 00001CE3 F687[71CF0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   879 00001CEA 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
   880                              <1> 
   881                              <1> ;-----	IT IS 1.44 MB DRIVE
   882                              <1> 
   883                              <1> PARM144:
   884 00001CEC B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   885 00001CEE E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   886 00001CF3 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   887 00001CF6 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   888                              <1> STO_CX:
   889 00001CF9 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
   890                              <1> ES_DI:
   891                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
   892 00001CFC 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
   893                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
   894                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   895                              <1> DP_OUT:
   896 00001CFF E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   897 00001D04 6631C0              <1> 	XOR	AX,AX			; CLEAR
   898 00001D07 F8                  <1> 	CLC
   899 00001D08 C3                  <1> 	RETn
   900                              <1> 
   901                              <1> ;-----	NO DRIYE PRESENT HANDLER
   902                              <1> 
   903                              <1> NON_DRV:
   904                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
   905 00001D09 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   906                              <1> NON_DRV1:
   907 00001D0C 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   908 00001D11 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
   909                              <1> 
   910                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
   911                              <1> 	
   912 00001D13 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   913 00001D18 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   914 00001D1B B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   915 00001D1D F9                  <1> 	STC
   916 00001D1E C3                  <1> 	RETn
   917                              <1> 
   918                              <1> NON_DRV2:
   919                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   920 00001D1F 31C0                <1> 	xor	eax, eax	
   921 00001D21 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   922                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   923 00001D25 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   924                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   925 00001D28 89450C              <1> 	mov	[ebp+12], eax
   926                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   927 00001D2B EBD2                <1> 	JMP	SHORT DP_OUT
   928                              <1> 
   929                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
   930                              <1> 
   931                              <1> USE_EST2:
   932 00001D2D B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   933 00001D2F E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   934 00001D34 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   935 00001D37 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   936 00001D3A 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   937 00001D3D 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   938 00001D3F EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
   939                              <1> 
   940                              <1> ;-------------------------------------------------------------------------------
   941                              <1> ; DISK_TYPE (AH = 15H)	
   942                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
   943                              <1> ;
   944                              <1> ;  ON ENTRY:	DI = DRIVE #
   945                              <1> ;
   946                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
   947                              <1> ;-------------------------------------------------------------------------------
   948                              <1> DSK_TYPE:
   949 00001D41 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   950 00001D46 8A87[71CF0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
   951 00001D4C 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
   952 00001D4E 7418                <1> 	JZ	short NO_DRV
   953 00001D50 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
   954 00001D52 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
   955 00001D54 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
   956 00001D56 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
   957                              <1> DT_BACK:
   958 00001D58 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
   959 00001D5A E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   960 00001D5F 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
   961 00001D61 F8                  <1> 	CLC				; NO ERROR
   962 00001D62 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   963 00001D65 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   964 00001D67 C3                  <1> 	RETn
   965                              <1> NO_DRV:	
   966 00001D68 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
   967 00001D6A EBEC                <1> 	JMP	SHORT DT_BACK
   968                              <1> 
   969                              <1> ;-------------------------------------------------------------------------------
   970                              <1> ; DISK_CHANGE	(AH = 16H)
   971                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
   972                              <1> ;
   973                              <1> ; ON ENTRY:	DI = DRIVE #
   974                              <1> ;
   975                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
   976                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
   977                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
   978                              <1> ;-------------------------------------------------------------------------------
   979                              <1> DSK_CHANGE:
   980 00001D6C E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   981 00001D71 8A87[71CF0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
   982 00001D77 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
   983 00001D79 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
   984 00001D7B A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
   985 00001D7D 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
   986                              <1> DC0:
   987 00001D7F E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
   988 00001D84 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
   989                              <1> 
   990 00001D86 C605[64CF0000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
   991                              <1> 
   992 00001D8D E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   993 00001D92 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   994 00001D97 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   995 00001D9A 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   996 00001D9C C3                  <1> 	RETn
   997                              <1> DC_NON:
   998 00001D9D 800D[64CF0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
   999 00001DA4 EBE7                <1> 	JMP	SHORT FINIS
  1000                              <1> 
  1001                              <1> ;-------------------------------------------------------------------------------
  1002                              <1> ; FORMAT_SET	(AH = 17H)
  1003                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  1004                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  1005                              <1> ;
  1006                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  1007                              <1> ;		DI     = DRIVE #
  1008                              <1> ;
  1009                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  1010                              <1> ;		AH = @DSKETTE_STATUS
  1011                              <1> ;		CY = 1 IF ERROR
  1012                              <1> ;-------------------------------------------------------------------------------
  1013                              <1> FORMAT_SET:
  1014 00001DA6 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1015 00001DAB 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1016 00001DAD 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1017 00001DB0 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1018 00001DB2 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1019 00001DB5 80A7[71CF0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1020 00001DBC 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1021 00001DBE 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1022 00001DC0 808F[71CF0000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1023 00001DC7 EB48                <1> 	JMP	SHORT S0
  1024                              <1> 
  1025                              <1> NOT_320:
  1026 00001DC9 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1027 00001DCE 803D[64CF0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1028 00001DD5 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1029                              <1> S3:
  1030 00001DD7 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1031 00001DD9 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1032 00001DDB 808F[71CF0000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1033 00001DE2 EB2D                <1> 	JMP	SHORT S0
  1034                              <1> 
  1035                              <1> NOT_320_12:
  1036 00001DE4 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1037 00001DE6 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1038 00001DE8 808F[71CF0000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1039 00001DEF EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1040                              <1> 
  1041                              <1> NOT_12:	
  1042 00001DF1 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1043 00001DF3 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1044                              <1> 
  1045 00001DF5 F687[71CF0000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1046 00001DFC 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1047 00001DFE B050                <1> 	MOV	AL,MED_DET+RATE_300
  1048 00001E00 F687[71CF0000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1049 00001E07 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1050                              <1> 
  1051                              <1> ASSUME:
  1052 00001E09 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1053                              <1> 
  1054                              <1> OR_IT_IN:
  1055 00001E0B 0887[71CF0000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1056                              <1> S0:
  1057 00001E11 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1058 00001E16 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1059 00001E1B 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1060 00001E1D 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1061 00001E1F C3                  <1> 	RETn
  1062                              <1> 
  1063                              <1> FS_ERR:
  1064 00001E20 C605[64CF0000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1065 00001E27 EBE8                <1> 	JMP	SHORT S0
  1066                              <1> 
  1067                              <1> ;-------------------------------------------------------------------------------
  1068                              <1> ; SET_MEDIA	(AH = 18H)
  1069                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  1070                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  1071                              <1> ;
  1072                              <1> ; ON ENTRY:
  1073                              <1> ;	[BP]	= SECTOR PER TRACK
  1074                              <1> ;	[BP+1]	= TRACK #
  1075                              <1> ;	DI	= DRIVE #
  1076                              <1> ;
  1077                              <1> ; ON EXIT:
  1078                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  1079                              <1> ;	IF NO ERROR:
  1080                              <1> ;		AH = 0
  1081                              <1> ;		CY = 0
  1082                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1083                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  1084                              <1> ;	IF ERROR:	
  1085                              <1> ;		AH = @DSKETTE_STATUS
  1086                              <1> ;		CY = 1
  1087                              <1> ;-------------------------------------------------------------------------------
  1088                              <1> SET_MEDIA:
  1089 00001E29 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1090 00001E2E F687[71CF0000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1091 00001E35 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1092 00001E37 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1093 00001E3C 803D[64CF0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1094 00001E43 746B                <1> 	JE	short SM_RTN
  1095 00001E45 C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1096                              <1> SM_CMOS:
  1097 00001E4C E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1098                              <1> 	;;20/02/2015
  1099                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  1100                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  1101 00001E51 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1102 00001E53 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1103 00001E58 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1104 00001E5A 57                  <1> 	PUSH	eDI			; SAVE REG.
  1105 00001E5B 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1106 00001E5D B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1107                              <1> DR_SEARCH:
  1108 00001E62 8AA3[ECC80000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1109 00001E68 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1110 00001E6B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1111 00001E6D 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1112                              <1> DR_FND:
  1113 00001E6F 8BBB[EDC80000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1114                              <1> MD_SEARCH:
  1115 00001E75 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1116 00001E78 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1117 00001E7B 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1118 00001E7D 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1119 00001E80 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1120 00001E83 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1121                              <1> NXT_MD:
  1122                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1123 00001E85 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1124 00001E88 E2D8                <1> 	LOOP    DR_SEARCH
  1125 00001E8A 5F                  <1> 	POP	eDI			; RESTORE REG.
  1126                              <1> MD_NOT_FND:
  1127 00001E8B C605[64CF0000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1128 00001E92 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1129                              <1> MD_FND:
  1130 00001E94 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1131 00001E97 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1132 00001E99 7502                <1> 	JNE	short MD_SET
  1133 00001E9B 0C20                <1> 	OR	AL,DBL_STEP
  1134                              <1> MD_SET:
  1135                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1136 00001E9D 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1137 00001EA0 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1138 00001EA2 5F                  <1> 	POP	eDI
  1139 00001EA3 80A7[71CF0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1140 00001EAA 0887[71CF0000]      <1> 	OR	[DSK_STATE+eDI], AL
  1141                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1142                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  1143                              <1> SM_RTN:
  1144 00001EB0 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1145 00001EB5 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1146 00001EBA C3                  <1> 	RETn
  1147                              <1> 
  1148                              <1> ;----------------------------------------------------------------
  1149                              <1> ; DR_TYPE_CHECK							:
  1150                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  1151                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  1152                              <1> ; ON ENTRY:							:
  1153                              <1> ;	AL = DRIVE TYPE						:
  1154                              <1> ; ON EXIT:							:
  1155                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  1156                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  1157                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  1158                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  1159                              <1> ; REGISTERS ALTERED: eBX						:
  1160                              <1> ;----------------------------------------------------------------		
  1161                              <1> DR_TYPE_CHECK:
  1162 00001EBB 6650                <1> 	PUSH	AX			
  1163 00001EBD 51                  <1> 	PUSH	eCX
  1164 00001EBE 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1165 00001EC0 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1166                              <1> TYPE_CHK:	
  1167 00001EC5 8AA3[ECC80000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1168 00001ECB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1169 00001ECD 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1170                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1171 00001ECF 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1172 00001ED2 E2F1                <1> 	LOOP    TYPE_CHK
  1173                              <1> 	;
  1174 00001ED4 BB[4BC90000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1175                              <1> 					; Default for GET_PARM (11/12/2014)
  1176                              <1> 	;
  1177 00001ED9 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1178 00001EDA EB06                <1> 	JMP	SHORT TYPE_RTN
  1179                              <1> DR_TYPE_VALID:
  1180 00001EDC 8B9B[EDC80000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1181                              <1> TYPE_RTN:
  1182 00001EE2 59                  <1> 	POP	eCX
  1183 00001EE3 6658                <1> 	POP	AX
  1184 00001EE5 C3                  <1> 	RETn	
  1185                              <1> 		
  1186                              <1> ;----------------------------------------------------------------
  1187                              <1> ; SEND_SPEC							:
  1188                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1189                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  1190                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  1191                              <1> ; ON EXIT:	NONE						:	
  1192                              <1> ; REGISTERS ALTERED: CX, DX					:
  1193                              <1> ;----------------------------------------------------------------		
  1194                              <1> SEND_SPEC:
  1195 00001EE6 50                  <1> 	PUSH	eAX			; SAVE AX
  1196 00001EE7 B8[0D1F0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1197 00001EEC 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1198 00001EED B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1199 00001EEF E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1200 00001EF4 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1201 00001EF6 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1202 00001EFB E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1203 00001F00 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1204 00001F02 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1205 00001F07 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1206 00001F0C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1207                              <1> SPECBAC:
  1208 00001F0D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1209 00001F0E C3                  <1> 	RETn
  1210                              <1> 
  1211                              <1> ;----------------------------------------------------------------
  1212                              <1> ; SEND_SPEC_MD							:
  1213                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1214                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  1215                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  1216                              <1> ; ON EXIT:	NONE						:	
  1217                              <1> ; REGISTERS ALTERED: AX						:
  1218                              <1> ;----------------------------------------------------------------		
  1219                              <1> SEND_SPEC_MD:
  1220 00001F0F 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1221 00001F10 B8[2D1F0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1222 00001F15 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1223 00001F16 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1224 00001F18 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1225 00001F1D 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1226 00001F1F E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1227 00001F24 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1228 00001F27 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1229 00001F2C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1230                              <1> SPEC_ESBAC:
  1231 00001F2D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1232 00001F2E C3                  <1> 	RETn
  1233                              <1> 
  1234                              <1> ;-------------------------------------------------------------------------------
  1235                              <1> ; XLAT_NEW  
  1236                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  1237                              <1> ;	MODE TO NEW ARCHITECTURE.
  1238                              <1> ;
  1239                              <1> ; ON ENTRY:	DI = DRIVE #
  1240                              <1> ;-------------------------------------------------------------------------------
  1241                              <1> XLAT_NEW:
  1242 00001F2F 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1243 00001F32 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1244 00001F34 80BF[71CF0000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1245 00001F3B 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1246 00001F3D 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1247 00001F40 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1248 00001F43 A0[70CF0000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1249 00001F48 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1250 00001F4A 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1251 00001F4C 80A7[71CF0000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1252 00001F53 0887[71CF0000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1253                              <1> XN_OUT:
  1254 00001F59 C3                  <1> 	RETn
  1255                              <1> DO_DET:
  1256 00001F5A E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1257 00001F5F C3                  <1> 	RETn
  1258                              <1> 
  1259                              <1> ;-------------------------------------------------------------------------------
  1260                              <1> ; XLAT_OLD 
  1261                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  1262                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  1263                              <1> ;
  1264                              <1> ; ON ENTRY:	DI = DRIVE
  1265                              <1> ;-------------------------------------------------------------------------------
  1266                              <1> XLAT_OLD:
  1267 00001F60 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1268                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1269 00001F63 0F8786000000        <1>         ja      XO_OUT
  1270 00001F69 80BF[71CF0000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1271 00001F70 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  1272                              <1> 
  1273                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  1274                              <1> 
  1275 00001F72 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1276 00001F75 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1277 00001F78 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1278 00001F7A D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1279 00001F7C 8425[70CF0000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1280 00001F82 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  1281                              <1> 
  1282                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  1283                              <1> 
  1284 00001F84 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1285 00001F86 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1286 00001F88 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1287 00001F8A 2025[70CF0000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  1288                              <1> 
  1289                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  1290                              <1> 
  1291 00001F90 8A87[71CF0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1292 00001F96 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1293 00001F98 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1294 00001F9A 0805[70CF0000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1295                              <1> 
  1296                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1297                              <1> 
  1298                              <1> SAVE_SET:
  1299 00001FA0 8AA7[71CF0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1300 00001FA6 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1301 00001FA8 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1302 00001FAB 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1303 00001FAE 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1304 00001FB0 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1305 00001FB2 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1306 00001FB5 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1307 00001FB7 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1308 00001FBA 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1309                              <1> UNKNO:
  1310 00001FBC B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1311 00001FBE EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1312                              <1> CHK_144:
  1313 00001FC0 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1314                              <1> 	;;20/02/2015
  1315                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  1316 00001FC5 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1317 00001FC7 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1318 00001FC9 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1319 00001FCB B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1320 00001FCD EB0C                <1> 	JMP	SHORT TST_DET
  1321                              <1> CHK_250:
  1322 00001FCF B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1323 00001FD1 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1324 00001FD4 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1325 00001FD6 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1326 00001FD9 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1327                              <1> TST_DET:
  1328 00001FDB F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1329 00001FDE 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1330 00001FE0 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1331                              <1> AL_SET:
  1332 00001FE2 80A7[71CF0000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1333 00001FE9 0887[71CF0000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1334                              <1> XO_OUT:
  1335 00001FEF C3                  <1> 	RETn
  1336                              <1> 
  1337                              <1> ;-------------------------------------------------------------------------------
  1338                              <1> ; RD_WR_VF
  1339                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  1340                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  1341                              <1> ;
  1342                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  1343                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  1344                              <1> ;
  1345                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1346                              <1> ;-------------------------------------------------------------------------------
  1347                              <1> RD_WR_VF:
  1348 00001FF0 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1349 00001FF2 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1350 00001FF7 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1351 00001FFC 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1352                              <1> DO_AGAIN:
  1353 00001FFE 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1354 00002000 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1355 00002005 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1356 00002007 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1357                              <1> RWV:
  1358 0000200D 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1359 0000200F 8AB7[71CF0000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1360 00002015 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1361 00002018 E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  1362                              <1> 	;;20/02/2015
  1363                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  1364 0000201D 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1365 0000201F 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1366 00002021 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1367 00002023 F687[71CF0000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1368 0000202A 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1369 0000202C B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1370 0000202E EB0F                <1> 	JMP	SHORT RWV_2
  1371                              <1> RWV_1:
  1372 00002030 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1373 00002032 F687[71CF0000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1374 00002039 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1375 0000203B B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1376 0000203D EB04                <1> 	jmp	short rwv_3
  1377                              <1> RWV_2:
  1378 0000203F 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1379 00002041 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1380                              <1> rwv_3:
  1381 00002043 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1382 00002048 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  1383                              <1> 
  1384                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  1385                              <1> 
  1386 0000204A 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1387 0000204B 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1388 0000204D B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1389                              <1> RWV_DR_SEARCH:
  1390 00002052 8AA3[ECC80000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1391 00002058 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1392 0000205B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1393 0000205D 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1394                              <1> RWV_DR_FND:
  1395 0000205F 8BBB[EDC80000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1396                              <1> RWV_MD_SEARH:
  1397 00002065 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1398 00002068 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  1399                              <1> RWV_NXT_MD:
  1400                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1401 0000206A 83C305              <1> 	add	eBX, 5
  1402 0000206D E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1403 0000206F 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1404                              <1> 
  1405                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1406                              <1> 
  1407                              <1> RWV_ASSUME:
  1408 00002070 BB[0AC90000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1409 00002075 F687[71CF0000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1410 0000207C 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1411 0000207E BB[24C90000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1412 00002083 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  1413                              <1> 
  1414                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  1415                              <1> 	 			
  1416                              <1> RWV_MD_FND:
  1417 00002085 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1418 00002087 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1419                              <1> 	
  1420                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  1421                              <1> 
  1422                              <1> RWV_MD_FND1:
  1423 00002088 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1424 0000208D E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1425 00002092 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1426 00002094 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1427                              <1> RWV_DBL:
  1428 00002099 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1429 0000209A E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1430 0000209F 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1431 000020A0 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1432 000020A2 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1433 000020A4 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1434 000020A6 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1435 000020A7 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1436 000020AC 5B                  <1> 	POP	eBX 
  1437 000020AD 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1438 000020AF 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1439 000020B1 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1440 000020B3 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1441 000020B4 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1442 000020B9 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1443 000020BA 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1444 000020BC E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1445 000020C1 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1446 000020C3 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1447                              <1> CHK_RET:
  1448 000020C8 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1449 000020CD 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1450 000020CF 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1451 000020D1 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1452                              <1> RWV_END:
  1453 000020D6 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1454 000020DB E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1455                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1456 000020E0 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1457 000020E2 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1458 000020E7 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1459 000020E9 E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1460 000020EE C3                  <1> 	RETn
  1461                              <1> 
  1462                              <1> ;-------------------------------------------------------------------------------
  1463                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1464                              <1> ;-------------------------------------------------------------------------------
  1465                              <1> SETUP_STATE:
  1466 000020EF F687[71CF0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1467 000020F6 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1468 000020F8 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1469 000020FC F687[71CF0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1470 00002103 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1471 00002105 F687[71CF0000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1472 0000210C 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1473 0000210E 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1474                              <1> AX_SET:	
  1475 00002112 80A7[71CF0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1476 00002119 08A7[71CF0000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1477 0000211F 8025[6CCF0000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1478 00002126 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1479 00002129 0805[6CCF0000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1480                              <1> J1C:	
  1481 0000212F C3                  <1> 	RETn
  1482                              <1> 
  1483                              <1> ;-------------------------------------------------------------------------------
  1484                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  1485                              <1> ;-------------------------------------------------------------------------------
  1486                              <1> FMT_INIT:
  1487 00002130 F687[71CF0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1488 00002137 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1489 00002139 E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  1490                              <1> 	;; 20/02/2015
  1491                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  1492 0000213E 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1493 00002140 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1494                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1495 00002142 8AA7[71CF0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1496 00002148 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1497 0000214B 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1498 0000214D 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1499 0000214F 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1500 00002152 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1501                              <1> N_360:	
  1502 00002154 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1503 00002156 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1504                              <1> F1_RATE:
  1505 00002158 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1506 0000215B EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1507                              <1> N_12:	
  1508 0000215D FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1509 0000215F 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1510 00002161 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1511 00002164 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1512 00002166 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1513 00002169 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1514 0000216B 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1515 0000216E EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1516                              <1> N_720:
  1517 00002170 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1518 00002172 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1519 00002174 EBE2                <1> 	JMP	SHORT F1_RATE
  1520                              <1> ISNT_12: 
  1521 00002176 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1522                              <1> 
  1523                              <1> SKP_STATE:
  1524 00002179 88A7[71CF0000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1525                              <1> F1_OUT:
  1526 0000217F C3                  <1> 	RETn
  1527                              <1> CL_DRV:	
  1528 00002180 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1529 00002182 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  1530                              <1> 
  1531                              <1> ;-------------------------------------------------------------------------------
  1532                              <1> ; MED_CHANGE	
  1533                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  1534                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  1535                              <1> ;
  1536                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  1537                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  1538                              <1> ;-------------------------------------------------------------------------------
  1539                              <1> MED_CHANGE:
  1540 00002184 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1541 00002189 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1542 0000218B 80A7[71CF0000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  1543                              <1> 
  1544                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  1545                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  1546                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  1547                              <1> 
  1548 00002192 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1549 00002195 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1550 00002197 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1551 00002199 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1552 0000219B FA                  <1> 	CLI				; NO INTERRUPTS
  1553 0000219C 2005[62CF0000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1554 000021A2 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1555 000021A3 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  1556                              <1> 
  1557                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  1558                              <1> 
  1559 000021A8 E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1560 000021AD B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1561 000021AF E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1562 000021B4 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1563 000021B6 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1564 000021BB C605[64CF0000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1565                              <1> OK1:
  1566 000021C2 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1567 000021C7 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1568                              <1> OK4:
  1569 000021C9 C605[64CF0000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1570                              <1> OK2:		
  1571 000021D0 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1572 000021D1 C3                  <1> 	RETn
  1573                              <1> MC_OUT:
  1574 000021D2 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1575 000021D3 C3                  <1> 	RETn
  1576                              <1> 
  1577                              <1> ;-------------------------------------------------------------------------------
  1578                              <1> ; SEND_RATE
  1579                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  1580                              <1> ; ON ENTRY:	DI = DRIVE #
  1581                              <1> ; ON EXIT:	NONE
  1582                              <1> ; REGISTERS ALTERED: DX
  1583                              <1> ;-------------------------------------------------------------------------------
  1584                              <1> SEND_RATE:
  1585 000021D4 6650                <1> 	PUSH	AX			; SAVE REG.
  1586 000021D6 8025[6CCF0000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1587 000021DD 8A87[71CF0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1588 000021E3 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1589 000021E5 0805[6CCF0000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1590 000021EB C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1591 000021EE 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1592 000021F2 EE                  <1> 	OUT	DX,AL
  1593 000021F3 6658                <1> 	POP	AX			; RESTORE REG.
  1594 000021F5 C3                  <1> 	RETn
  1595                              <1> 
  1596                              <1> ;-------------------------------------------------------------------------------
  1597                              <1> ; CHK_LASTRATE
  1598                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  1599                              <1> ; ON ENTRY:
  1600                              <1> ;	DI = DRIVE #
  1601                              <1> ; ON EXIT:
  1602                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  1603                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  1604                              <1> ; REGISTERS ALTERED: DX
  1605                              <1> ;-------------------------------------------------------------------------------
  1606                              <1> CHK_LASTRATE:
  1607 000021F6 6650                <1> 	PUSH	AX			; SAVE REG
  1608 000021F8 2225[6CCF0000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1609 000021FE 8A87[71CF0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1610 00002204 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1611 00002208 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1612                              <1> 					; ZF = 1 RATE IS THE SAME
  1613 0000220A 6658                <1> 	POP	AX			; RESTORE REG.
  1614 0000220C C3                  <1> 	RETn
  1615                              <1> 
  1616                              <1> ;-------------------------------------------------------------------------------
  1617                              <1> ; DMA_SETUP
  1618                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  1619                              <1> ;
  1620                              <1> ; ON ENTRY:	AL = DMA COMMAND
  1621                              <1> ;
  1622                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1623                              <1> ;-------------------------------------------------------------------------------
  1624                              <1> 
  1625                              <1> ; SI = Head #, # of Sectors or DASD Type
  1626                              <1> 
  1627                              <1> ; 22/08/2015
  1628                              <1> ; 08/02/2015 - Protected Mode Modification
  1629                              <1> ; 06/02/2015 - 07/02/2015
  1630                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  1631                              <1> ; (DMA Addres = Physical Address)
  1632                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  1633                              <1> ;
  1634                              <1> 
  1635                              <1> 
  1636                              <1> ; 04/02/2016 (clc)
  1637                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  1638                              <1> ; 16/12/2014 (IODELAY)
  1639                              <1> 
  1640                              <1> DMA_SETUP:
  1641                              <1> 
  1642                              <1> ;; 20/02/2015
  1643 0000220D 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1644 00002210 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1645 00002216 756E                <1> 	jnz	short dma_bnd_err_stc
  1646                              <1> 	;
  1647 00002218 6650                <1> 	push	ax			; DMA command
  1648 0000221A 52                  <1> 	push	edx			; *
  1649 0000221B B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1650 0000221D E851030000          <1> 	call	GET_PARM		; 
  1651 00002222 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1652 00002224 6689F0              <1> 	mov	ax, si			; Sector count
  1653 00002227 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1654 00002229 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1655 0000222B 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1656 0000222E 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1657 00002231 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1658 00002233 6689C1              <1> 	mov	cx, ax
  1659 00002236 5A                  <1> 	pop	edx			; *
  1660 00002237 6658                <1> 	pop	ax
  1661 00002239 3C42                <1> 	cmp	al, 42h
  1662 0000223B 7507                <1>         jne     short NOT_VERF
  1663 0000223D BA0000FF00          <1> 	mov	edx, 0FF0000h
  1664 00002242 EB08                <1> 	jmp	short J33
  1665                              <1> NOT_VERF:
  1666 00002244 6601CA              <1> 	add	dx, cx			; check for overflow
  1667 00002247 723E                <1> 	jc	short dma_bnd_err
  1668                              <1> 	;
  1669 00002249 6629CA              <1> 	sub	dx, cx			; Restore start address
  1670                              <1> J33:
  1671 0000224C FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1672 0000224D E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1673                              <1> 	IODELAY				; WAIT FOR I/O
  1673 0000224F EB00                <2>  jmp short $+2
  1673 00002251 EB00                <2>  jmp short $+2
  1674 00002253 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1675 00002255 89D0                <1> 	mov	eax, edx		; Buffer address
  1676 00002257 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1677                              <1> 	IODELAY				; WAIT FOR I/O
  1677 00002259 EB00                <2>  jmp short $+2
  1677 0000225B EB00                <2>  jmp short $+2
  1678 0000225D 88E0                <1> 	MOV	AL,AH
  1679 0000225F E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1680 00002261 C1E810              <1> 	shr	eax, 16
  1681                              <1> 	IODELAY				; I/O WAIT STATE
  1681 00002264 EB00                <2>  jmp short $+2
  1681 00002266 EB00                <2>  jmp short $+2
  1682 00002268 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1683                              <1> 	IODELAY
  1683 0000226A EB00                <2>  jmp short $+2
  1683 0000226C EB00                <2>  jmp short $+2
  1684 0000226E 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1685 00002271 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1686                              <1> 	IODELAY				; WAIT FOR I/O
  1686 00002273 EB00                <2>  jmp short $+2
  1686 00002275 EB00                <2>  jmp short $+2
  1687 00002277 88E0                <1> 	MOV	AL, AH
  1688 00002279 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1689                              <1> 	IODELAY
  1689 0000227B EB00                <2>  jmp short $+2
  1689 0000227D EB00                <2>  jmp short $+2
  1690 0000227F FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1691 00002280 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1692 00002282 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1693                              <1> 
  1694 00002284 F8                  <1> 	clc	; 04/02/2016
  1695 00002285 C3                  <1> 	retn
  1696                              <1> 
  1697                              <1> dma_bnd_err_stc:
  1698 00002286 F9                  <1> 	stc
  1699                              <1> dma_bnd_err:
  1700 00002287 C605[64CF0000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1701 0000228E C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  1702                              <1> 
  1703                              <1> ;; 16/12/2014
  1704                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1705                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1706                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1707                              <1> ;;	IODELAY
  1708                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1709                              <1> ;;	;SIODELAY
  1710                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  1711                              <1> ;;      ;JNE	short NOT_VERF		; NO
  1712                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  1713                              <1> ;;      ;JMP	SHORT J33
  1714                              <1> ;;;NOT_VERF:	
  1715                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1716                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1717                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1718                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1719                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1720                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  1721                              <1> ;;	;JNC	short J33
  1722                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1723                              <1> ;;;J33:
  1724                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  1725                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1726                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1727                              <1> ;;	IODELAY
  1728                              <1> ;;	MOV	AL,AH
  1729                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1730                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  1731                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1732                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1733                              <1> ;;	IODELAY
  1734                              <1> ;;	;AND	AL,00001111B
  1735                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1736                              <1> ;;	;SIODELAY
  1737                              <1> ;;
  1738                              <1> ;;;----- DETERMINE COUNT
  1739                              <1> ;;	sub	eax, eax ; 08/02/2015
  1740                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  1741                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  1742                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  1743                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  1744                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  1745                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  1746                              <1> ;;	CALL	GET_PARM		; "
  1747                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1748                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  1749                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  1750                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1751                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  1752                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1753                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1754                              <1> ;;	IODELAY
  1755                              <1> ;;	MOV	AL, AH
  1756                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1757                              <1> ;;	;IODELAY
  1758                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1759                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  1760                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  1761                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1762                              <1> ;;	add	ecx, eax ; 08/02/2015
  1763                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1764                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1765                              <1> ;;	SIODELAY
  1766                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1767                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  1768                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  1769                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  1770                              <1> ;;	jz	short NO_BAD
  1771                              <1> ;;dma_bnd_err:
  1772                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1773                              <1> ;;NO_BAD:
  1774                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1775                              <1> 
  1776                              <1> ;-------------------------------------------------------------------------------
  1777                              <1> ; FMTDMA_SET
  1778                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  1779                              <1> ;
  1780                              <1> ; ON ENTRY:	NOTHING REQUIRED
  1781                              <1> ;
  1782                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1783                              <1> ;-------------------------------------------------------------------------------
  1784                              <1> 
  1785                              <1> FMTDMA_SET:
  1786                              <1> ;; 20/02/2015 modification	
  1787 0000228F 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1788 00002292 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1789 00002298 75EC                <1> 	jnz	short dma_bnd_err_stc
  1790                              <1> 	;
  1791 0000229A 6652                <1> 	push	dx			; *
  1792 0000229C B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1793 0000229E E8D0020000          <1> 	call	GET_PARM		; "
  1794 000022A3 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1795 000022A5 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1796 000022A7 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1797 000022AB 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1798 000022AD 6689C1              <1> 	mov	cx, ax
  1799 000022B0 665A                <1> 	pop	dx			; *
  1800 000022B2 6601CA              <1> 	add	dx, cx			; check for overflow
  1801 000022B5 72D0                <1> 	jc	short dma_bnd_err
  1802                              <1> 	;
  1803 000022B7 6629CA              <1> 	sub	dx, cx			; Restore start address
  1804                              <1> 	;
  1805 000022BA B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1806 000022BC FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1807 000022BD E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1808                              <1> 	IODELAY				; WAIT FOR I/O
  1808 000022BF EB00                <2>  jmp short $+2
  1808 000022C1 EB00                <2>  jmp short $+2
  1809 000022C3 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1810 000022C5 89D0                <1> 	mov	eax, edx		; Buffer address
  1811 000022C7 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1812                              <1> 	IODELAY				; WAIT FOR I/O
  1812 000022C9 EB00                <2>  jmp short $+2
  1812 000022CB EB00                <2>  jmp short $+2
  1813 000022CD 88E0                <1> 	MOV	AL,AH
  1814 000022CF E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1815 000022D1 C1E810              <1> 	shr	eax, 16
  1816                              <1> 	IODELAY				; I/O WAIT STATE
  1816 000022D4 EB00                <2>  jmp short $+2
  1816 000022D6 EB00                <2>  jmp short $+2
  1817 000022D8 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1818                              <1> 	IODELAY
  1818 000022DA EB00                <2>  jmp short $+2
  1818 000022DC EB00                <2>  jmp short $+2
  1819 000022DE 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1820 000022E1 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1821                              <1> 	IODELAY				; WAIT FOR I/O
  1821 000022E3 EB00                <2>  jmp short $+2
  1821 000022E5 EB00                <2>  jmp short $+2
  1822 000022E7 88E0                <1> 	MOV	AL, AH
  1823 000022E9 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1824                              <1> 	IODELAY
  1824 000022EB EB00                <2>  jmp short $+2
  1824 000022ED EB00                <2>  jmp short $+2
  1825 000022EF FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1826 000022F0 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1827 000022F2 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1828 000022F4 C3                  <1> 	retn
  1829                              <1> 
  1830                              <1> ;; 08/02/2015 - Protected Mode Modification
  1831                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1832                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1833                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1834                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1835                              <1> ;;	IODELAY
  1836                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1837                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1838                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1839                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1840                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1841                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1842                              <1> ;;	;JNC	short J33A
  1843                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1844                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  1845                              <1> ;;;J33A:
  1846                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  1847                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1848                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1849                              <1> ;;	IODELAY
  1850                              <1> ;;	MOV	AL,AH
  1851                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1852                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  1853                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1854                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1855                              <1> ;;	IODELAY
  1856                              <1> ;;	;AND	AL,00001111B
  1857                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1858                              <1> ;;
  1859                              <1> ;;;----- DETERMINE COUNT
  1860                              <1> ;;	sub	eax, eax ; 08/02/2015
  1861                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1862                              <1> ;;	CALL	GET_PARM		; "
  1863                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  1864                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  1865                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1866                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1867                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  1868                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1869                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1870                              <1> ;;	IODELAY
  1871                              <1> ;;	MOV	AL, AH
  1872                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1873                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1874                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  1875                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  1876                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1877                              <1> ;;	add	ecx, eax ; 08/02/2015
  1878                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1879                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1880                              <1> ;;	SIODELAY
  1881                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1882                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  1883                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  1884                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  1885                              <1> ;;	jz	short FMTDMA_OK
  1886                              <1> ;;	stc	; 20/02/2015
  1887                              <1> ;;fmtdma_bnd_err:
  1888                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1889                              <1> ;;FMTDMA_OK:
  1890                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1891                              <1> 
  1892                              <1> ;-------------------------------------------------------------------------------
  1893                              <1> ; NEC_INIT	
  1894                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  1895                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  1896                              <1> ;
  1897                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  1898                              <1> ;
  1899                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1900                              <1> ;-------------------------------------------------------------------------------
  1901                              <1> NEC_INIT:
  1902 000022F5 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1903 000022F7 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1904                              <1> 
  1905                              <1> ;-----	DO THE SEEK OPERATION
  1906                              <1> 
  1907 000022FC 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1908 000022FF E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1909 00002304 6658                <1> 	POP	AX			; RECOVER COMMAND
  1910 00002306 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1911 00002308 BB[26230000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1912 0000230D 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1913                              <1> 
  1914                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1915                              <1> 
  1916 0000230E E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1917 00002313 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1918 00002316 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1919 00002318 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1920 0000231B 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1921 0000231E 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1922 00002320 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1923 00002325 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1924                              <1> ER_1:
  1925 00002326 C3                  <1> 	RETn
  1926                              <1> 
  1927                              <1> ;-------------------------------------------------------------------------------
  1928                              <1> ; RWV_COM
  1929                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  1930                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  1931                              <1> ;
  1932                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  1933                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1934                              <1> ;-------------------------------------------------------------------------------
  1935                              <1> RWV_COM:
  1936 00002327 B8[72230000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1937 0000232C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1938 0000232D 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1939 00002330 E844030000          <1> 	CALL	NEC_OUTPUT
  1940 00002335 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  1941 00002338 E83C030000          <1> 	CALL	NEC_OUTPUT
  1942 0000233D 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  1943 00002340 E834030000          <1> 	CALL	NEC_OUTPUT
  1944 00002345 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  1945 00002347 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1946 0000234C E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1947 00002351 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  1948 00002353 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1949 00002358 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1950 0000235D 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  1951                              <1> _R15:
  1952 00002360 E814030000          <1> 	CALL	NEC_OUTPUT
  1953 00002365 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  1954 00002367 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  1955 0000236C E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1956 00002371 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  1957                              <1> ER_2:
  1958 00002372 C3                  <1> 	RETn
  1959                              <1> 
  1960                              <1> ;-------------------------------------------------------------------------------
  1961                              <1> ; NEC_TERM
  1962                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  1963                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  1964                              <1> ;
  1965                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1966                              <1> ;-------------------------------------------------------------------------------
  1967                              <1> NEC_TERM:
  1968                              <1> 
  1969                              <1> ;-----	LET THE OPERATION HAPPEN
  1970                              <1> 
  1971 00002373 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  1972 00002374 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  1973 00002379 9C                  <1> 	PUSHF
  1974 0000237A E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  1975 0000237F 724B                <1> 	JC	short SET_END_POP
  1976 00002381 9D                  <1> 	POPF
  1977 00002382 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  1978                              <1> 
  1979                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  1980                              <1> 
  1981 00002384 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  1982 00002385 BE[65CF0000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  1983 0000238A AC                  <1> 	lodsb				; GET ST0
  1984 0000238B 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  1985 0000238D 7433                <1> 	JZ	short SET_END
  1986 0000238F 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  1987 00002391 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  1988                              <1> 
  1989                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  1990                              <1> 
  1991 00002393 AC                  <1> 	lodsb				; GET ST1
  1992 00002394 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  1993 00002396 B404                <1> 	MOV	AH,RECORD_NOT_FND
  1994 00002398 7222                <1> 	JC	short J19
  1995 0000239A C0E002              <1> 	SAL	AL,2
  1996 0000239D B410                <1> 	MOV	AH,BAD_CRC
  1997 0000239F 721B                <1> 	JC	short J19
  1998 000023A1 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  1999 000023A3 B408                <1> 	MOV	AH,BAD_DMA
  2000 000023A5 7215                <1> 	JC	short J19
  2001 000023A7 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2002 000023AA B404                <1> 	MOV	AH,RECORD_NOT_FND
  2003 000023AC 720E                <1> 	JC	short J19
  2004 000023AE D0E0                <1> 	SAL	AL,1
  2005 000023B0 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2006 000023B2 7208                <1> 	JC	short J19
  2007 000023B4 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2008 000023B6 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2009 000023B8 7202                <1> 	JC	short J19
  2010                              <1> 
  2011                              <1> ;----- 	NEC MUST HAVE FAILED
  2012                              <1> J18:
  2013 000023BA B420                <1> 	MOV	AH,BAD_NEC
  2014                              <1> J19:
  2015 000023BC 0825[64CF0000]      <1> 	OR	[DSKETTE_STATUS], AH
  2016                              <1> SET_END:
  2017 000023C2 803D[64CF0000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2018 000023C9 F5                  <1> 	CMC
  2019 000023CA 5E                  <1> 	POP	eSI
  2020 000023CB C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2021                              <1> 
  2022                              <1> SET_END_POP:
  2023 000023CC 9D                  <1> 	POPF
  2024 000023CD EBF3                <1> 	JMP	SHORT SET_END
  2025                              <1> 
  2026                              <1> ;-------------------------------------------------------------------------------
  2027                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2028                              <1> ;-------------------------------------------------------------------------------
  2029                              <1> DSTATE:
  2030 000023CF 803D[64CF0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2031 000023D6 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2032 000023D8 808F[71CF0000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2033 000023DF F687[71CF0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2034 000023E6 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2035 000023E8 8A87[71CF0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2036 000023EE 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2037 000023F0 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2038 000023F2 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  2039                              <1> 
  2040                              <1> ;----- 	CHECK IF IT IS 1.44M
  2041                              <1> 
  2042 000023F4 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2043                              <1> 	;;20/02/2015
  2044                              <1> 	;;JC	short M_12		; CMOS BAD
  2045 000023F9 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2046 000023FB 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2047 000023FD 7410                <1> 	JE	short M_12		; YES
  2048                              <1> M_720:
  2049 000023FF 80A7[71CF0000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2050 00002406 808F[71CF0000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2051 0000240D EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2052                              <1> M_12:	
  2053 0000240F 808F[71CF0000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2054                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2055                              <1> SETBAC:
  2056 00002416 C3                  <1> 	RETn
  2057                              <1> 
  2058                              <1> ;-------------------------------------------------------------------------------
  2059                              <1> ; RETRY	
  2060                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  2061                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  2062                              <1> ;
  2063                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  2064                              <1> ;-------------------------------------------------------------------------------
  2065                              <1> RETRY:
  2066 00002417 803D[64CF0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2067 0000241E 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2068 00002420 803D[64CF0000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2069 00002427 743C                <1> 	JZ	short NO_RETRY
  2070 00002429 8AA7[71CF0000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2071 0000242F F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2072 00002432 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2073 00002434 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2074 00002437 8A2D[6CCF0000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2075 0000243D C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2076 00002440 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2077 00002443 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2078 00002445 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  2079                              <1> 
  2080                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  2081                              <1> ;	 00000000B (500) -> 10000000B	(250)
  2082                              <1> ;	 10000000B (250) -> 01000000B	(300)
  2083                              <1> ;	 01000000B (300) -> 00000000B	(500)
  2084                              <1> 
  2085 00002447 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2086 0000244A D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2087 0000244C 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2088 0000244F 80A7[71CF0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2089                              <1> 					; RATE, DBL STEP OFF
  2090 00002456 08A7[71CF0000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2091 0000245C C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2092 00002463 F9                  <1> 	STC				; SET CARRY FOR RETRY
  2093 00002464 C3                  <1> 	RETn				; RETRY RETURN
  2094                              <1> 
  2095                              <1> NO_RETRY:
  2096 00002465 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2097 00002466 C3                  <1> 	RETn				; NO RETRY RETURN
  2098                              <1> 
  2099                              <1> ;-------------------------------------------------------------------------------
  2100                              <1> ; NUM_TRANS
  2101                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  2102                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  2103                              <1> ;
  2104                              <1> ; ON ENTRY:	[BP+1] = TRACK
  2105                              <1> ;		SI-HI  = HEAD
  2106                              <1> ;		[BP]   = START SECTOR
  2107                              <1> ;
  2108                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  2109                              <1> ;-------------------------------------------------------------------------------
  2110                              <1> NUM_TRANS:
  2111 00002467 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2112 00002469 803D[64CF0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2113 00002470 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2114 00002472 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2115 00002474 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2116 00002479 8A1D[6ACF0000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2117 0000247F 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2118 00002482 3A2D[69CF0000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2119 00002488 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2120 0000248A 8A2D[68CF0000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2121 00002490 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2122 00002493 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2123 00002495 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2124                              <1> DIF_HD:
  2125 00002497 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2126                              <1> SAME_TRK:
  2127 00002499 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2128 0000249C 88D8                <1> 	MOV	AL,BL			; TO AL
  2129                              <1> NT_OUT:
  2130 0000249E C3                  <1> 	RETn
  2131                              <1> 
  2132                              <1> ;-------------------------------------------------------------------------------
  2133                              <1> ; SETUP_END
  2134                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2135                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2136                              <1> ;
  2137                              <1> ; ON EXIT:
  2138                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2139                              <1> ;-------------------------------------------------------------------------------
  2140                              <1> SETUP_END:
  2141 0000249F B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2142 000024A1 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2143 000024A3 E8CB000000          <1> 	CALL	GET_PARM
  2144 000024A8 8825[63CF0000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2145 000024AE 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2146 000024B0 8A25[64CF0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2147 000024B6 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2148 000024B8 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  2149 000024BA 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2150                              <1> NUN_ERR: 
  2151 000024BC 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2152 000024BF F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2153 000024C0 C3                  <1> 	RETn
  2154                              <1> 
  2155                              <1> ;-------------------------------------------------------------------------------
  2156                              <1> ; SETUP_DBL
  2157                              <1> ;	CHECK DOUBLE STEP.
  2158                              <1> ;
  2159                              <1> ; ON ENTRY :	DI = DRIVE
  2160                              <1> ;
  2161                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  2162                              <1> ;-------------------------------------------------------------------------------
  2163                              <1> SETUP_DBL:
  2164 000024C1 8AA7[71CF0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2165 000024C7 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2166 000024CA 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  2167                              <1> 
  2168                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  2169                              <1> 
  2170 000024CC C605[61CF0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2171 000024D3 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2172 000024D8 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2173 000024DA E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2174 000024DF E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2175 000024E4 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  2176                              <1> 
  2177                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  2178                              <1> 
  2179 000024E6 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2180 000024EA F687[71CF0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2181 000024F1 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2182 000024F3 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  2183                              <1> 
  2184                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  2185                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  2186                              <1> ;	THEN SET DOUBLE STEP ON.
  2187                              <1> 
  2188                              <1> CNT_OK:
  2189 000024F5 C605[63CF0000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2190 000024FC 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2191 000024FE C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2192 00002505 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2193 00002508 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2194 0000250A C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2195 0000250D 6650                <1> 	PUSH	AX			; SAVE HEAD
  2196 0000250F E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2197 00002514 6658                <1> 	POP	AX			; RESTORE HEAD
  2198 00002516 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2199 00002519 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2200 0000251E 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2201 0000251F 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2202 00002524 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2203 00002525 6659                <1> 	POP	CX			; RESTORE COUNT
  2204 00002527 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2205 00002529 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2206 0000252B 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2207 0000252D 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  2208                              <1> 
  2209                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  2210                              <1> 
  2211                              <1> SD_ERR:	
  2212 0000252F F9                  <1> 	STC				; SET CARRY FOR ERROR
  2213 00002530 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2214                              <1> 
  2215                              <1> DO_CHK:
  2216 00002531 8A0D[68CF0000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2217 00002537 888F[75CF0000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2218 0000253D D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2219 0000253F 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2220 00002541 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2221 00002543 808F[71CF0000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2222                              <1> NO_DBL:
  2223 0000254A F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2224 0000254B C3                  <1> 	RETn
  2225                              <1> 
  2226                              <1> ;-------------------------------------------------------------------------------
  2227                              <1> ; READ_ID
  2228                              <1> ;	READ ID FUNCTION.
  2229                              <1> ;
  2230                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  2231                              <1> ;
  2232                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  2233                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2234                              <1> ;-------------------------------------------------------------------------------
  2235                              <1> READ_ID:
  2236 0000254C B8[69250000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2237 00002551 50                  <1> 	PUSH	eAX
  2238 00002552 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2239 00002554 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2240 00002559 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2241 0000255C 88C4                <1> 	MOV	AH,AL
  2242 0000255E E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2243 00002563 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2244 00002568 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2245                              <1> ER_3:
  2246 00002569 C3                  <1> 	RETn
  2247                              <1> 
  2248                              <1> ;-------------------------------------------------------------------------------
  2249                              <1> ; CMOS_TYPE
  2250                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  2251                              <1> ;
  2252                              <1> ; ON ENTRY:	DI = DRIVE #
  2253                              <1> ;
  2254                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  2255                              <1> ;-------------------------------------------------------------------------------
  2256                              <1> 
  2257                              <1> CMOS_TYPE: ; 11/12/2014
  2258 0000256A 8A87[6EC90000]      <1> mov	al, [eDI+fd0_type]
  2259 00002570 20C0                <1> and 	al, al ; 18/12/2014
  2260 00002572 C3                  <1> retn
  2261                              <1> 
  2262                              <1> ;CMOS_TYPE:
  2263                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  2264                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  2265                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  2266                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  2267                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  2268                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  2269                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  2270                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  2271                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  2272                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  2273                              <1> ;TB:
  2274                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  2275                              <1> ;BAD_CM:
  2276                              <1> ;	RETn				; CY, STATUS OF READ
  2277                              <1> 
  2278                              <1> ;-------------------------------------------------------------------------------
  2279                              <1> ; GET_PARM
  2280                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  2281                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  2282                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  2283                              <1> ;	THE PARAMETER IN DL.
  2284                              <1> ;
  2285                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  2286                              <1> ;
  2287                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  2288                              <1> ;		AL,DH DESTROYED
  2289                              <1> ;-------------------------------------------------------------------------------
  2290                              <1> GET_PARM:
  2291                              <1> 	;PUSH	DS
  2292 00002573 56                  <1> 	PUSH	eSI
  2293                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  2294                              <1>     	;MOV	DS,AX
  2295                              <1> 	;;mov	ax, cs
  2296                              <1> 	;;mov	ds, ax
  2297                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  2298 00002574 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2299                              <1> 	;SUB	BH,BH			; BX = INDEX
  2300 00002576 81E3FF000000        <1> 	and	ebx, 0FFh
  2301                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2302                              <1> 	;
  2303                              <1> 	; 17/12/2014
  2304 0000257C 66A1[61C90000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2305 00002582 38E0                <1> 	cmp	al, ah
  2306 00002584 7425                <1> 	je	short gpndc
  2307 00002586 A2[62C90000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2308 0000258B 53                  <1> 	push	ebx ; 08/02/2015
  2309 0000258C 88C3                <1> 	mov	bl, al 
  2310                              <1> 	; 11/12/2014
  2311 0000258E 8A83[6EC90000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2312                              <1> 	; 18/12/2014
  2313 00002594 20C0                <1> 	and	al, al
  2314 00002596 7507                <1> 	jnz	short gpdtc
  2315 00002598 BB[4BC90000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2316 0000259D EB05                <1>         jmp     short gpdpu
  2317                              <1> gpdtc:	
  2318 0000259F E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2319                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2320                              <1> gpdpu:
  2321 000025A4 891D[E8C80000]      <1> 	mov	[DISK_POINTER], ebx
  2322 000025AA 5B                  <1> 	pop	ebx
  2323                              <1> gpndc:
  2324 000025AB 8B35[E8C80000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2325 000025B1 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2326 000025B4 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2327 000025B6 5E                  <1> 	POP	eSI
  2328                              <1> 	;POP	DS
  2329 000025B7 C3                  <1> 	RETn
  2330                              <1> 
  2331                              <1> ;-------------------------------------------------------------------------------
  2332                              <1> ; MOTOR_ON
  2333                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  2334                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  2335                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  2336                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  2337                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  2338                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  2339                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  2340                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  2341                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  2342                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  2343                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  2344                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  2345                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  2346                              <1> ;
  2347                              <1> ; ON ENTRY:	DI = DRIVE #
  2348                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  2349                              <1> ;-------------------------------------------------------------------------------
  2350                              <1> MOTOR_ON:
  2351 000025B8 53                  <1> 	PUSH	eBX			; SAVE REG.
  2352 000025B9 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2353 000025BE 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2354 000025C0 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2355 000025C5 E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  2356                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  2357                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  2358                              <1> M_WAIT:
  2359 000025CA B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2360 000025CC E8A2FFFFFF          <1> 	CALL	GET_PARM
  2361                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  2362                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  2363                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  2364 000025D1 80FC08              <1> 	cmp	ah, 8
  2365                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2366 000025D4 7702                <1> 	ja	short J13
  2367                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2368 000025D6 B408                <1> 	mov	ah, 8
  2369                              <1> 
  2370                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  2371                              <1> GP2:	
  2372                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  2373                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  2374 000025D8 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2375 000025DD E816F3FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2376                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2377 000025E2 FECC                <1> 	dec	ah
  2378 000025E4 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2379                              <1> MOT_IS_ON:
  2380 000025E6 5B                  <1> 	POP	eBX			; RESTORE REG.
  2381 000025E7 C3                  <1> 	RETn
  2382                              <1> 
  2383                              <1> ;-------------------------------------------------------------------------------
  2384                              <1> ; TURN_ON
  2385                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  2386                              <1> ;
  2387                              <1> ; ON ENTRY:	DI = DRIVE #
  2388                              <1> ;
  2389                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  2390                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  2391                              <1> ;		AX,BX,CX,DX DESTROYED
  2392                              <1> ;-------------------------------------------------------------------------------
  2393                              <1> TURN_ON:
  2394 000025E8 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2395 000025EA 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2396 000025EC C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2397 000025EF FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2398 000025F0 C605[63CF0000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2399 000025F7 A0[62CF0000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2400 000025FC 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2401 000025FE B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2402 00002600 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  2403                              <1> 
  2404                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  2405                              <1> ;  BL = DRIVE SELECT DESIRED
  2406                              <1> ;  AH = MOTOR ON MASK DESIRED
  2407                              <1> 
  2408 00002602 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2409 00002604 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2410 00002606 8425[62CF0000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2411 0000260C 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2412                              <1> 
  2413                              <1> TURN_IT_ON:
  2414 0000260E 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2415 00002610 8A3D[62CF0000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2416 00002616 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2417 00002619 8025[62CF0000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2418 00002620 0825[62CF0000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2419 00002626 A0[62CF0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2420 0000262B 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2421 0000262D 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2422 00002630 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2423 00002631 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2424 00002633 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2425 00002636 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2426 00002638 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2427 0000263C EE                  <1> 	OUT	DX,AL
  2428 0000263D 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2429                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2430 0000263F 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2431 00002641 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2432 00002642 C3                  <1> 	RETn
  2433                              <1> 
  2434                              <1> NO_MOT_WAIT:
  2435 00002643 FB                  <1> 	sti
  2436                              <1> no_mot_w1: ; 27/02/2015
  2437 00002644 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2438                              <1> 	;STI				; INTERRUPTS BACK ON
  2439 00002645 C3                  <1> 	RETn
  2440                              <1> 
  2441                              <1> ;-------------------------------------------------------------------------------
  2442                              <1> ; HD_WAIT
  2443                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  2444                              <1> ;
  2445                              <1> ; ON ENTRY:	DI = DRIVE #
  2446                              <1> ;
  2447                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  2448                              <1> ;-------------------------------------------------------------------------------
  2449                              <1> HD_WAIT:
  2450 00002646 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2451 00002648 E826FFFFFF          <1> 	CALL	GET_PARM
  2452 0000264D 08E4                <1> 	or	ah, ah	; 17/12/2014
  2453 0000264F 7519                <1> 	jnz	short DO_WAT
  2454 00002651 F605[62CF0000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  2455                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  2456                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  2457                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  2458 00002658 741E                <1> 	jz	short HW_DONE
  2459 0000265A B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2460 0000265C 8A87[71CF0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2461 00002662 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2462 00002664 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2463 00002666 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2464                              <1> ;GP3:
  2465 00002668 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  2466                              <1> ;	JMP	SHORT DO_WAT
  2467                              <1> 
  2468                              <1> ;ISNT_WRITE:
  2469                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  2470                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  2471                              <1> 
  2472                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  2473                              <1> DO_WAT:
  2474                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  2475                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  2476                              <1> J29:					; 	1 MILLISECOND LOOP
  2477                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  2478 0000266A B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2479 0000266F E884F2FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2480                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2481 00002674 FECC                <1> 	dec	ah
  2482 00002676 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2483                              <1> HW_DONE:
  2484 00002678 C3                  <1> 	RETn
  2485                              <1> 
  2486                              <1> ;-------------------------------------------------------------------------------
  2487                              <1> ; NEC_OUTPUT
  2488                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  2489                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  2490                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  2491                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  2492                              <1> ; 
  2493                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  2494                              <1> ;
  2495                              <1> ; ON EXIT:	CY = 0  SUCCESS
  2496                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  2497                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  2498                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  2499                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  2500                              <1> ;		AX,CX,DX DESTROYED
  2501                              <1> ;-------------------------------------------------------------------------------
  2502                              <1> 
  2503                              <1> ; 09/12/2014 [Erdogan Tan] 
  2504                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  2505                              <1> ; Diskette Drive Controller Status Register (3F4h)
  2506                              <1> ;	This read only register facilitates the transfer of data between
  2507                              <1> ;	the system microprocessor and the controller.
  2508                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  2509                              <1> ;	  with the system micrprocessor.
  2510                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  2511                              <1> ;	  the transfer is to the controller.
  2512                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  2513                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  2514                              <1> ; Bit 3 - Reserved.
  2515                              <1> ; Bit 2 - Reserved.
  2516                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2517                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2518                              <1> 
  2519                              <1> ; Data Register (3F5h)
  2520                              <1> ; This read/write register passes data, commands and parameters, and provides
  2521                              <1> ; diskette status information.
  2522                              <1>   		
  2523                              <1> NEC_OUTPUT:
  2524                              <1> 	;PUSH	BX			; SAVE REG.
  2525 00002679 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2526                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  2527                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  2528                              <1> 	; 16/12/2014
  2529                              <1> 	; waiting for (max.) 0.5 seconds
  2530                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  2531                              <1> 	;
  2532                              <1> 	; 17/12/2014
  2533                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  2534                              <1> 	;
  2535                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  2536                              <1> 	;		go on.
  2537                              <1> 	;INPUT:
  2538                              <1> 	;	AH=Mask for isolation bits.
  2539                              <1> 	;	AL=pattern to look for.
  2540                              <1> 	;	DX=Port to test for
  2541                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2542                              <1> 	;	     (normally 30 microseconds per period.)
  2543                              <1> 	;
  2544                              <1> 	;WFP_SHORT:  
  2545                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  2546                              <1> 	;
  2547                              <1> 
  2548                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  2549                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  2550 0000267D B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  2551                              <1> ;
  2552                              <1> ;WFPS_OUTER_LP:
  2553                              <1> ;	;
  2554                              <1> ;WFPS_CHECK_PORT:
  2555                              <1> J23:
  2556 00002682 EC                  <1> 	IN	AL,DX			; GET STATUS
  2557 00002683 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2558 00002685 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2559 00002687 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2560                              <1> WFPS_HI:
  2561 00002689 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2562 0000268B A810                <1> 	TEST	AL,010H			; transition on memory
  2563 0000268D 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2564                              <1> WFPS_LO:
  2565 0000268F E461                <1> 	IN	AL, PORT_B		; SYS1
  2566 00002691 A810                <1> 	TEST	AL,010H
  2567 00002693 74FA                <1> 	JZ	SHORT WFPS_LO
  2568                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2569 00002695 E2EB                <1> 	loop	J23	; 27/02/2015
  2570                              <1> ;	;
  2571                              <1> ;	dec	bl
  2572                              <1> ;	jnz	short WFPS_OUTER_LP
  2573                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  2574                              <1> ;J23:
  2575                              <1> ;	IN	AL,DX			; GET STATUS
  2576                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2577                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2578                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  2579                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  2580                              <1> 	;DEC	BL			; DECREMENT COUNTER
  2581                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  2582                              <1>    
  2583                              <1> 	;;27/02/2015
  2584                              <1> 	;16/12/2014
  2585                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  2586                              <1> 	;;jb	short J23
  2587                              <1> 
  2588                              <1> ;WFPS_TIMEOUT:
  2589                              <1> 
  2590                              <1> ;-----	FALL THRU TO ERROR RETURN
  2591                              <1> 
  2592 00002697 800D[64CF0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2593                              <1> 	;POP	BX			; RESTORE REG.
  2594 0000269E 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2595 0000269F F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2596 000026A0 C3                  <1> 	RETn
  2597                              <1> 
  2598                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2599                              <1> 
  2600                              <1> J27:	
  2601 000026A1 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2602 000026A3 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2603 000026A5 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2604                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2605                              <1> 	; 27/02/2015
  2606 000026A6 9C                  <1> 	PUSHF				; SAVE FLAGS
  2607 000026A7 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2608 000026AC E847F2FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2609 000026B1 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2610                              <1> 	;POP	BX			; RESTORE REG
  2611 000026B2 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  2612                              <1> 
  2613                              <1> ;-------------------------------------------------------------------------------
  2614                              <1> ; SEEK
  2615                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  2616                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  2617                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  2618                              <1> ;
  2619                              <1> ; ON ENTRY:	DI = DRIVE #
  2620                              <1> ;		CH = TRACK #
  2621                              <1> ;
  2622                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2623                              <1> ;		AX,BX,CX DX DESTROYED
  2624                              <1> ;-------------------------------------------------------------------------------
  2625                              <1> SEEK:
  2626 000026B3 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2627 000026B5 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2628 000026B7 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2629 000026B9 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2630 000026BB 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2631 000026BD 8405[61CF0000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2632 000026C3 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2633                              <1> 
  2634 000026C5 0805[61CF0000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2635 000026CB E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2636 000026D0 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2637                              <1> 
  2638                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2639                              <1> 
  2640 000026D2 C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2641 000026D9 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2642 000026DE 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2643                              <1> 
  2644                              <1> AFT_RECAL:
  2645 000026E0 C687[75CF0000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2646 000026E7 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2647 000026E9 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  2648                              <1> 
  2649                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  2650                              <1> 
  2651 000026EB F687[71CF0000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2652 000026F2 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2653 000026F4 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2654                              <1> 
  2655 000026F6 3AAF[75CF0000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2656 000026FC 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2657                              <1> 
  2658 000026FE BA[31270000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2659 00002703 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2660 00002704 88AF[75CF0000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2661 0000270A B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2662 0000270C E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2663 00002711 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2664 00002713 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2665 00002715 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2666 0000271A 8AA7[75CF0000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2667 00002720 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2668 00002725 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  2669                              <1> 
  2670                              <1> ;-----	WAIT FOR HEAD SETTLE
  2671                              <1> 
  2672                              <1> DO_WAIT:
  2673 0000272A 9C                  <1> 	PUSHF				; SAVE STATUS
  2674 0000272B E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2675 00002730 9D                  <1> 	POPF				; RESTORE STATUS
  2676                              <1> RB:
  2677                              <1> NEC_ERR:
  2678                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  2679                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  2680 00002731 C3                  <1> 	RETn				; RETURN TO CALLER
  2681                              <1> 
  2682                              <1> ;-------------------------------------------------------------------------------
  2683                              <1> ; RECAL
  2684                              <1> ;	RECALIBRATE DRIVE
  2685                              <1> ;
  2686                              <1> ; ON ENTRY:	DI = DRIVE #
  2687                              <1> ;
  2688                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  2689                              <1> ;-------------------------------------------------------------------------------
  2690                              <1> RECAL:
  2691 00002732 6651                <1> 	PUSH	CX
  2692 00002734 B8[50270000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2693 00002739 50                  <1> 	PUSH	eAX
  2694 0000273A B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2695 0000273C E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2696 00002741 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2697 00002743 88DC                <1> 	MOV	AH,BL
  2698 00002745 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2699 0000274A E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2700 0000274F 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2701                              <1> RC_BACK:
  2702 00002750 6659                <1> 	POP	CX
  2703 00002752 C3                  <1> 	RETn
  2704                              <1> 
  2705                              <1> ;-------------------------------------------------------------------------------
  2706                              <1> ; CHK_STAT_2
  2707                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  2708                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  2709                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  2710                              <1> ;
  2711                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2712                              <1> ;-------------------------------------------------------------------------------
  2713                              <1> CHK_STAT_2:
  2714 00002753 B8[7B270000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2715 00002758 50                  <1> 	PUSH	eAX
  2716 00002759 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2717 0000275E 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2718 00002760 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2719 00002762 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2720 00002767 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2721 0000276C 720C                <1> 	JC	short J34
  2722 0000276E A0[65CF0000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2723 00002773 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2724 00002775 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2725 00002777 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2726 00002779 F8                  <1> 	CLC				; GOOD RETURN
  2727                              <1> J34:
  2728 0000277A 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2729                              <1> CS_BACK:
  2730 0000277B C3                  <1> 	RETn
  2731                              <1> J35:
  2732 0000277C 800D[64CF0000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2733 00002783 F9                  <1> 	STC				; ERROR RETURN CODE
  2734 00002784 EBF4                <1> 	JMP	SHORT J34
  2735                              <1> 
  2736                              <1> ;-------------------------------------------------------------------------------
  2737                              <1> ; WAIT_INT
  2738                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  2739                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  2740                              <1> ;	IF THE DRIVE IS NOT READY.
  2741                              <1> ;
  2742                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2743                              <1> ;-------------------------------------------------------------------------------
  2744                              <1> 
  2745                              <1> ; 17/12/2014
  2746                              <1> ; 2.5 seconds waiting !
  2747                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  2748                              <1> ; amount of time to wait for completion interrupt from NEC.
  2749                              <1> 
  2750                              <1> 
  2751                              <1> WAIT_INT:
  2752 00002786 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2753 00002787 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  2754                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  2755                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  2756                              <1> 
  2757                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  2758                              <1> 	;
  2759                              <1> 	;WAIT_FOR_MEM:	
  2760                              <1> 	;	Waits for a bit at a specified memory location pointed
  2761                              <1> 	;	to by ES:[DI] to become set.
  2762                              <1> 	;INPUT:
  2763                              <1> 	;	AH=Mask to test with.
  2764                              <1> 	;	ES:[DI] = memory location to watch.
  2765                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2766                              <1> 	;	     (normally 30 microseconds per period.)
  2767                              <1> 
  2768                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  2769                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  2770                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  2771                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  2772                              <1> 	; 27/02/2015
  2773 00002788 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2774                              <1> WFMS_CHECK_MEM:
  2775 0000278D F605[61CF0000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2776 00002794 7516                <1>         jnz     short J37
  2777                              <1> WFMS_HI:
  2778 00002796 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2779 00002798 A810                <1> 	TEST	AL,010H			; transition on memory
  2780 0000279A 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2781                              <1> WFMS_LO:
  2782 0000279C E461                <1> 	IN	AL,PORT_B		;SYS1
  2783 0000279E A810                <1> 	TEST	AL,010H
  2784 000027A0 74FA                <1> 	JZ	SHORT WFMS_LO
  2785 000027A2 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  2786                              <1> ;WFMS_OUTER_LP:
  2787                              <1> ;;	or	bl, bl			; check outer counter
  2788                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  2789                              <1> ;	dec	bl
  2790                              <1> ;	jz	short J36A	
  2791                              <1> ;	jmp	short WFMS_CHECK_MEM
  2792                              <1> 
  2793                              <1> 	;17/12/2014
  2794                              <1> 	;16/12/2014
  2795                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  2796                              <1> ;J36:
  2797                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2798                              <1> ;	JNZ	short J37
  2799                              <1> 	;16/12/2014
  2800                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  2801                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  2802                              <1> 	;JNZ	short J36
  2803                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  2804                              <1> ;	jb	short J36
  2805                              <1> 
  2806                              <1> ;WFMS_TIMEOUT:
  2807                              <1> ;J36A:
  2808 000027A4 800D[64CF0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2809 000027AB F9                  <1> 	STC				; ERROR RETURN
  2810                              <1> J37:
  2811 000027AC 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2812 000027AD 8025[61CF0000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2813 000027B4 9D                  <1> 	POPF				; RECOVER CARRY
  2814 000027B5 C3                  <1> 	RETn				; GOOD RETURN CODE
  2815                              <1> 
  2816                              <1> ;-------------------------------------------------------------------------------
  2817                              <1> ; RESULTS
  2818                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  2819                              <1> ;	FOLLOWING AN INTERRUPT.
  2820                              <1> ;
  2821                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2822                              <1> ;		AX,BX,CX,DX DESTROYED
  2823                              <1> ;-------------------------------------------------------------------------------
  2824                              <1> RESULTS:
  2825 000027B6 57                  <1> 	PUSH	eDI
  2826 000027B7 BF[65CF0000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2827 000027BC B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2828 000027BE 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2829                              <1> 
  2830                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  2831                              <1> 
  2832                              <1> _R10: 
  2833                              <1> 	; 16/12/2014
  2834                              <1> 	; wait for (max) 0.5 seconds
  2835                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  2836                              <1> 	;XOR	CX,CX			; COUNTER
  2837                              <1> 
  2838                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  2839                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2840                              <1> 	; 27/02/2015
  2841 000027C2 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  2842                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  2843                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  2844                              <1> 
  2845                              <1> WFPSR_OUTER_LP:
  2846                              <1> 	;
  2847                              <1> WFPSR_CHECK_PORT:
  2848                              <1> J39:					; WAIT FOR MASTER
  2849 000027C7 EC                  <1> 	IN	AL,DX			; GET STATUS
  2850 000027C8 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2851 000027CA 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2852 000027CC 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2853                              <1> WFPSR_HI:
  2854 000027CE E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2855 000027D0 A810                <1> 	TEST	AL,010H			; transition on memory
  2856 000027D2 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2857                              <1> WFPSR_LO:
  2858 000027D4 E461                <1> 	IN	AL, PORT_B		; SYS1
  2859 000027D6 A810                <1> 	TEST	AL,010H
  2860 000027D8 74FA                <1> 	JZ	SHORT WFPSR_LO
  2861 000027DA E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  2862                              <1> 	;; 27/02/2015
  2863                              <1> 	;;dec	bh
  2864                              <1> 	;;jnz	short WFPSR_OUTER_LP
  2865                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  2866                              <1> 
  2867                              <1> 	;;mov	byte [wait_count], 0
  2868                              <1> ;J39:					; WAIT FOR MASTER
  2869                              <1> ;	IN	AL,DX			; GET STATUS
  2870                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2871                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2872                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  2873                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  2874                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  2875                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  2876                              <1> 	;
  2877                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  2878                              <1> 	;;jb	short J39	
  2879                              <1> 
  2880                              <1> ;WFPSR_TIMEOUT:
  2881 000027DC 800D[64CF0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2882 000027E3 F9                  <1> 	STC				; SET ERROR RETURN
  2883 000027E4 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2884                              <1> 
  2885                              <1> ;-----	READ IN THE STATUS
  2886                              <1> 
  2887                              <1> J42:
  2888 000027E6 EB00                <1> 	JMP	$+2			; I/O DELAY
  2889 000027E8 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2890 000027EA EC                  <1> 	IN	AL,DX			; GET THE DATA
  2891                              <1> 	; 16/12/2014
  2892                              <1> 	NEWIODELAY
  2892 000027EB E6EB                <2>  out 0ebh,al
  2893 000027ED 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2894 000027EF 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  2895                              <1> 	; 16/12/2014
  2896                              <1> ;	push	cx
  2897                              <1> ;	mov	cx, 30
  2898                              <1> ;wdw2:
  2899                              <1> ;	NEWIODELAY
  2900                              <1> ;	loop	wdw2
  2901                              <1> ;	pop	cx
  2902                              <1> 
  2903 000027F0 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2904 000027F5 E8FEF0FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2905 000027FA 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2906 000027FC EC                  <1> 	IN	AL,DX			; GET STATUS
  2907                              <1> 	; 16/12/2014
  2908                              <1> 	NEWIODELAY
  2908 000027FD E6EB                <2>  out 0ebh,al
  2909                              <1> 	;
  2910 000027FF A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2911 00002801 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2912                              <1> 
  2913 00002803 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2914 00002805 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2915 00002807 800D[64CF0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2916 0000280E F9                  <1> 	STC				; SET ERROR FLAG
  2917                              <1> 
  2918                              <1> ;-----	RESULT OPERATION IS DONE
  2919                              <1> POPRES:
  2920 0000280F 5F                  <1> 	POP	eDI
  2921 00002810 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  2922                              <1> 
  2923                              <1> ;-------------------------------------------------------------------------------
  2924                              <1> ; READ_DSKCHNG
  2925                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  2926                              <1> ;
  2927                              <1> ; ON ENTRY:	DI = DRIVE #
  2928                              <1> ;
  2929                              <1> ; ON EXIT:	DI = DRIVE #
  2930                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  2931                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  2932                              <1> ;		AX,CX,DX DESTROYED
  2933                              <1> ;-------------------------------------------------------------------------------
  2934                              <1> READ_DSKCHNG:
  2935 00002811 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2936 00002816 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2937 0000281A EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2938 0000281B A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2939 0000281D C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  2940                              <1> 
  2941                              <1> ;-------------------------------------------------------------------------------
  2942                              <1> ; DRIVE_DET
  2943                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  2944                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  2945                              <1> ; ON ENTRY:	DI = DRIVE #
  2946                              <1> ;-------------------------------------------------------------------------------
  2947                              <1> DRIVE_DET:
  2948 0000281E E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  2949 00002823 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2950 00002828 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  2951 0000282A B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  2952 0000282C E882FEFFFF          <1> 	CALL	SEEK
  2953 00002831 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  2954 00002833 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  2955                              <1> SK_GIN:
  2956 00002835 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  2957 00002837 6651                <1> 	PUSH	CX			; SAVE TRACK
  2958 00002839 E875FEFFFF          <1> 	CALL	SEEK
  2959 0000283E 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  2960 00002840 B8[7C280000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  2961 00002845 50                  <1> 	PUSH	eAX
  2962 00002846 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  2963 00002848 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2964 0000284D 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  2965 00002850 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  2966 00002852 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2967 00002857 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  2968 0000285C 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2969 0000285D 6659                <1> 	POP	CX			; RESTORE TRACK
  2970 0000285F F605[65CF0000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  2971 00002866 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  2972 00002868 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  2973 0000286A 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  2974                              <1> 
  2975                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  2976                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  2977                              <1> 
  2978 0000286C 808F[71CF0000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  2979 00002873 C3                  <1> 	RETn				; ALL INFORMATION SET
  2980                              <1> IS_80:
  2981 00002874 808F[71CF0000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  2982                              <1> DD_BAC:
  2983 0000287B C3                  <1> 	RETn
  2984                              <1> POP_BAC:
  2985 0000287C 6659                <1> 	POP	CX			; THROW AWAY
  2986 0000287E C3                  <1> 	RETn
  2987                              <1> 
  2988                              <1> fdc_int:  
  2989                              <1> 	  ; 30/07/2015	
  2990                              <1> 	  ; 16/02/2015
  2991                              <1> ;int_0Eh: ; 11/12/2014
  2992                              <1> 
  2993                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  2994                              <1> ; DISK_INT
  2995                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  2996                              <1> ;
  2997                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  2998                              <1> ;-------------------------------------------------------------------------------
  2999                              <1> DISK_INT_1:
  3000                              <1> 
  3001 0000287F 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3002 00002881 1E                  <1> 	push	ds
  3003 00002882 66B81000            <1> 	mov	ax, KDATA
  3004 00002886 8ED8                <1> 	mov 	ds, ax
  3005 00002888 800D[61CF0000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3006 0000288F B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3007 00002891 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3008 00002893 1F                  <1> 	pop	ds
  3009 00002894 6658                <1> 	POP	AX			; RECOVER REGISTER
  3010 00002896 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  3011                              <1> 
  3012                              <1> ;-------------------------------------------------------------------------------
  3013                              <1> ; DSKETTE_SETUP
  3014                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  3015                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  3016                              <1> ;-------------------------------------------------------------------------------
  3017                              <1> DSKETTE_SETUP:
  3018                              <1> 	;PUSH	AX			; SAVE REGISTERS
  3019                              <1> 	;PUSH	BX
  3020                              <1> 	;PUSH	CX
  3021 00002897 52                  <1> 	PUSH	eDX
  3022                              <1> 	;PUSH	DI
  3023                              <1> 	;;PUSH	DS
  3024                              <1> 	; 14/12/2014
  3025                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  3026                              <1> 	;mov	[DISK_POINTER+2], cs
  3027                              <1> 	;
  3028                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  3029 00002898 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3030 0000289A 66C705[71CF0000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3030 000028A2 00                  <1>
  3031 000028A3 8025[6CCF0000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3032 000028AA 800D[6CCF0000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3033 000028B1 C605[61CF0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3034 000028B8 C605[63CF0000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3035 000028BF C605[62CF0000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3036 000028C6 C605[64CF0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3037                              <1> 	;
  3038                              <1> 	; 28/02/2015
  3039                              <1> 	;mov	word [cfd], 100h 
  3040 000028CD E85FF2FFFF          <1> 	call	DSK_RESET
  3041 000028D2 5A                  <1> 	pop	edx
  3042 000028D3 C3                  <1> 	retn
  3043                              <1> 
  3044                              <1> ;SUP0:
  3045                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  3046                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3047                              <1> ;	; 02/01/2015
  3048                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  3049                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  3050                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  3051                              <1> ;       cmp     byte [fd1_type], 0	
  3052                              <1> ;	jna	short sup1
  3053                              <1> ;	or	di, di
  3054                              <1> ;	jnz	short sup1
  3055                              <1> ;	inc	di
  3056                              <1> ;       jmp     short SUP0
  3057                              <1> ;sup1:
  3058                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  3059                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  3060                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  3061                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  3062                              <1> ;	;POP	DI
  3063                              <1> ;	POP	eDX
  3064                              <1> ;	;POP	CX
  3065                              <1> ;	;POP	BX
  3066                              <1> ;	;POP	AX
  3067                              <1> ;	RETn
  3068                              <1> 
  3069                              <1> ;//////////////////////////////////////////////////////
  3070                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3071                              <1> ;
  3072                              <1> 
  3073                              <1> int13h: ; 21/02/2015
  3074 000028D4 9C                  <1> 	pushfd
  3075 000028D5 0E                  <1> 	push 	cs
  3076 000028D6 E858000000          <1> 	call 	DISK_IO
  3077 000028DB C3                  <1> 	retn
  3078                              <1> 
  3079                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  3080                              <1> ;/////////////////////////////////////////////////////////////////////
  3081                              <1> 
  3082                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  3083                              <1> ; 18/02/2016
  3084                              <1> ; 17/02/2016
  3085                              <1> ; 23/02/2015
  3086                              <1> ; 21/02/2015 (unix386.s)
  3087                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  3088                              <1> ;
  3089                              <1> ; Original Source Code:
  3090                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  3091                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  3092                              <1> ;
  3093                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  3094                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  3095                              <1> ;
  3096                              <1> 
  3097                              <1> 
  3098                              <1> ;The wait for controller to be not busy is 10 seconds.
  3099                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3100                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  3101                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  3102                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  3103                              <1> 
  3104                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  3105                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3106                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  3107                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  3108                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  3109                              <1> 
  3110                              <1> ;The wait for Data request on read and write longs is
  3111                              <1> ;2000 us. (?)
  3112                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  3113                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  3114                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  3115                              <1> 
  3116                              <1> ; Port 61h (PORT_B)
  3117                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  3118                              <1> 
  3119                              <1> ; 23/12/2014
  3120                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  3121                              <1> 
  3122                              <1> 
  3123                              <1> ;--- INT 13H -------------------------------------------------------------------
  3124                              <1> ;									       :
  3125                              <1> ; FIXED DISK I/O INTERFACE						       :
  3126                              <1> ;									       :
  3127                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  3128                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  3129                              <1> ;									       :
  3130                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  3131                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  3132                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  3133                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  3134                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  3135                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  3136                              <1> ;									       :
  3137                              <1> ;------------------------------------------------------------------------------:
  3138                              <1> ;									       :
  3139                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  3140                              <1> ;									       :
  3141                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  3142                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  3143                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  3144                              <1> ;			  DL > 80H - DISK				       :
  3145                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  3146                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  3147                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  3148                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  3149                              <1> ;	(AH)= 06H  UNUSED						       :
  3150                              <1> ;	(AH)= 07H  UNUSED						       :
  3151                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  3152                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  3153                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  3154                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  3155                              <1> ;	(AH)= 0AH  READ LONG						       :
  3156                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  3157                              <1> ;	(AH)= 0CH  SEEK 						       :
  3158                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  3159                              <1> ;	(AH)= 0EH  UNUSED						       :
  3160                              <1> ;	(AH)= 0FH  UNUSED						       :
  3161                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  3162                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  3163                              <1> ;	(AH)= 12H  UNUSED						       :
  3164                              <1> ;	(AH)= 13H  UNUSED						       :
  3165                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  3166                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  3167                              <1> ;									       :
  3168                              <1> ;-------------------------------------------------------------------------------
  3169                              <1> ;									       :
  3170                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  3171                              <1> ;									       :
  3172                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  3173                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  3174                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  3175                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  3176                              <1> ;									       :
  3177                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  3178                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  3179                              <1> ;				 (10 BITS TOTAL)			       :
  3180                              <1> ;									       :
  3181                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  3182                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  3183                              <1> ;									       :
  3184                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  3185                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  3186                              <1> ;									       :
  3187                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  3188                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  3189                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  3190                              <1> ;			       80H FOR A BAD SECTOR			       :
  3191                              <1> ;			   N = SECTOR NUMBER				       :
  3192                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  3193                              <1> ;			   THE TABLE SHOULD BE: 			       :
  3194                              <1> ;									       :
  3195                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  3196                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  3197                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  3198                              <1> ;									       :
  3199                              <1> ;-------------------------------------------------------------------------------
  3200                              <1> 
  3201                              <1> ;-------------------------------------------------------------------------------
  3202                              <1> ; OUTPUT								       :
  3203                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  3204                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  3205                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  3206                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  3207                              <1> ;									       :
  3208                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  3209                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  3210                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  3211                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  3212                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  3213                              <1> ;		REWRITTEN.						       :
  3214                              <1> ;									       :
  3215                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  3216                              <1> ;	   INPUT:							       :
  3217                              <1> ;	     (DL) = DRIVE NUMBER					       :
  3218                              <1> ;	   OUTPUT:							       :
  3219                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  3220                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  3221                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  3222                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  3223                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  3224                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  3225                              <1> ;									       :
  3226                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  3227                              <1> ;									       :
  3228                              <1> ;	AH = 0 - NOT PRESENT						       :
  3229                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  3230                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  3231                              <1> ;	     3 - FIXED DISK						       :
  3232                              <1> ;									       :
  3233                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  3234                              <1> ;									       :
  3235                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  3236                              <1> ;	INFORMATION.							       :
  3237                              <1> ;									       :
  3238                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  3239                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  3240                              <1> ;									       :
  3241                              <1> ;-------------------------------------------------------------------------------
  3242                              <1> 
  3243                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  3244                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  3245                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  3246                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  3247                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  3248                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  3249                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  3250                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  3251                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  3252                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  3253                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  3254                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  3255                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  3256                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  3257                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  3258                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  3259                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  3260                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  3261                              <1> 
  3262                              <1> ;--------------------------------------------------------
  3263                              <1> ;							:
  3264                              <1> ; FIXED DISK PARAMETER TABLE				:
  3265                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  3266                              <1> ;							:
  3267                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  3268                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  3269                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  3270                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  3271                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  3272                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  3273                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  3274                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  3275                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  3276                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  3277                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  3278                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  3279                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  3280                              <1> ;							:
  3281                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  3282                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  3283                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  3284                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  3285                              <1> ;							:
  3286                              <1> ;--------------------------------------------------------
  3287                              <1> 
  3288                              <1> ;--------------------------------------------------------
  3289                              <1> ;							:
  3290                              <1> ; HARDWARE SPECIFIC VALUES				:
  3291                              <1> ;							:
  3292                              <1> ;  -  CONTROLLER I/O PORT				:
  3293                              <1> ;							:
  3294                              <1> ;     > WHEN READ FROM: 				:
  3295                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  3296                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  3297                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  3298                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  3299                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  3300                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  3301                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  3302                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  3303                              <1> ;							:
  3304                              <1> ;     > WHEN WRITTEN TO:				:
  3305                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  3306                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  3307                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  3308                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  3309                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  3310                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  3311                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  3312                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  3313                              <1> ;							:
  3314                              <1> ;--------------------------------------------------------
  3315                              <1> 
  3316                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  3317                              <1> ;HF1_PORT	equ	0170h	
  3318                              <1> ;HF_REG_PORT	EQU	03F6H
  3319                              <1> ;HF1_REG_PORT	equ	0376h
  3320                              <1> 
  3321                              <1> HDC1_BASEPORT	equ	1F0h
  3322                              <1> HDC2_BASEPORT	equ	170h		
  3323                              <1> 
  3324                              <1> align 2
  3325                              <1> 
  3326                              <1> ;-----		STATUS REGISTER
  3327                              <1> 
  3328                              <1> ST_ERROR	EQU	00000001B	;
  3329                              <1> ST_INDEX	EQU	00000010B	;
  3330                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  3331                              <1> ST_DRQ		EQU	00001000B	;
  3332                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  3333                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  3334                              <1> ST_READY	EQU	01000000B	;
  3335                              <1> ST_BUSY 	EQU	10000000B	;
  3336                              <1> 
  3337                              <1> ;-----		ERROR REGISTER
  3338                              <1> 
  3339                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  3340                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  3341                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  3342                              <1> ;		EQU	00001000B	; NOT USED
  3343                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  3344                              <1> ;		EQU	00100000B	; NOT USED
  3345                              <1> ERR_DATA_ECC	EQU	01000000B
  3346                              <1> ERR_BAD_BLOCK	EQU	10000000B
  3347                              <1> 
  3348                              <1> 
  3349                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  3350                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  3351                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  3352                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  3353                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  3354                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  3355                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  3356                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  3357                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  3358                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  3359                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  3360                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  3361                              <1> 
  3362                              <1> ;MAX_FILE	EQU	2
  3363                              <1> ;S_MAX_FILE	EQU	2
  3364                              <1> MAX_FILE	equ	4		; 22/12/2014
  3365                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  3366                              <1> 
  3367                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  3368                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  3369                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  3370                              <1> 
  3371                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  3372                              <1> 
  3373                              <1> ;-----		COMMAND BLOCK REFERENCE
  3374                              <1> 
  3375                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  3376                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  3377                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  3378                              <1> ; 19/12/2014
  3379                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  3380                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  3381                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3382                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3383                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  3384                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  3385                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  3386                              <1> 
  3387                              <1> align 2
  3388                              <1> 
  3389                              <1> ;----------------------------------------------------------------
  3390                              <1> ; FIXED DISK I/O SETUP						:
  3391                              <1> ;								:
  3392                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  3393                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  3394                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  3395                              <1> ;								:
  3396                              <1> ;----------------------------------------------------------------
  3397                              <1> 
  3398                              <1> DISK_SETUP:
  3399                              <1> 	;CLI
  3400                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  3401                              <1> 	;xor	ax,ax
  3402                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  3403                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  3404                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  3405                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  3406                              <1> 	;MOV	[DISK_VECTOR+2],AX
  3407                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  3408                              <1> 	;MOV	[ORG_VECTOR+2],CS
  3409                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  3410                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  3411                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  3412                              <1> 	;;MOV	[HDISK_INT+2],CS
  3413                              <1> 	;mov	[HDISK_INT1+2],CS
  3414                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  3415                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  3416                              <1> 	;mov	[HDISK_INT2+2],CS
  3417                              <1> 	;
  3418                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  3419                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  3420                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  3421                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  3422                              <1> 	;push	cs
  3423                              <1> 	;pop	ds
  3424                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  3425                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  3426 000028DC C705[7CCF0000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3426 000028E4 0900                <1>
  3427                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  3428                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  3429 000028E6 C705[80CF0000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3429 000028EE 0900                <1>
  3430                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  3431                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  3432 000028F0 C705[84CF0000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3432 000028F8 0900                <1>
  3433                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  3434                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  3435 000028FA C705[88CF0000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3435 00002902 0900                <1>
  3436                              <1> 	;
  3437                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  3438                              <1> 	;;;AND	AL,0BFH
  3439                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  3440                              <1> 	;;;JMP	$+2
  3441                              <1> 	;;IODELAY
  3442                              <1> 	;;OUT	INTB01,AL
  3443                              <1> 	;;IODELAY
  3444                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  3445                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  3446                              <1> 	;;;JMP	$+2
  3447                              <1> 	;;IODELAY
  3448                              <1> 	;;OUT	INTA01,AL
  3449                              <1> 	;
  3450                              <1> 	;STI
  3451                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  3452                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  3453                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  3454                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3455                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  3456                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  3457                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  3458                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  3459                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  3460                              <1> 	;mov	si, hd0_type
  3461 00002904 BE[70C90000]        <1> 	mov	esi, hd0_type
  3462                              <1> 	;mov	cx, 4
  3463 00002909 B904000000          <1> 	mov	ecx, 4
  3464                              <1> hde_l:
  3465 0000290E AC                  <1> 	lodsb
  3466 0000290F 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3467 00002911 7206                <1> 	jb	short _L4
  3468 00002913 FE05[78CF0000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3469                              <1> _L4: ; 26/02/2015
  3470 00002919 E2F3                <1> 	loop	hde_l	
  3471                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  3472                              <1> ;L4:
  3473                              <1> 	; 
  3474                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  3475                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  3476                              <1> 	;;mov 	cl, 3
  3477                              <1> 	;;
  3478                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  3479                              <1> ;;hdc_dl:
  3480                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  3481                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  3482                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  3483                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  3484                              <1> 	;;jnc	short hdc_reset0
  3485                              <1> 	;;loop	hdc_dl
  3486                              <1> 	;;; 27/12/2014
  3487                              <1> 	;;stc
  3488                              <1> 	;;retn
  3489                              <1> 	;
  3490                              <1> ;;hdc_reset0:
  3491                              <1> 	; 18/01/2015
  3492 0000291B 8A0D[78CF0000]      <1> 	mov	cl, [HF_NUM]
  3493 00002921 20C9                <1> 	and	cl, cl
  3494 00002923 740D                <1> 	jz	short POD_DONE
  3495                              <1> 	;
  3496 00002925 B27F                <1> 	mov	dl, 7Fh
  3497                              <1> hdc_reset1:
  3498 00002927 FEC2                <1> 	inc	dl
  3499                              <1> 	;; 31/12/2015
  3500                              <1> 	;;push	dx
  3501                              <1> 	;;push	cx
  3502                              <1> 	;;push	ds
  3503                              <1> 	;;sub	ax, ax
  3504                              <1> 	;;mov	ds, ax
  3505                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  3506                              <1> 	;;pop	ds
  3507                              <1> 	;;MOV	BX,AX
  3508                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  3509                              <1> 	;;MOV	CX,AX
  3510                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  3511                              <1> 	;;
  3512                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  3513                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  3514                              <1> 	;;pop	cx
  3515                              <1> 	;;pop	dx
  3516                              <1> 	;;
  3517                              <1> 	; 18/01/2015
  3518 00002929 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3519                              <1> 	;int	13h
  3520 0000292B E8A4FFFFFF          <1> 	call	int13h
  3521 00002930 E2F5                <1> 	loop	hdc_reset1
  3522                              <1> POD_DONE:
  3523 00002932 C3                  <1> 	RETn
  3524                              <1> 
  3525                              <1> ;;-----	POD_ERROR
  3526                              <1> 
  3527                              <1> ;;CTL_ERRX:
  3528                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  3529                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  3530                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3531                              <1> ;	;JMP	short POD_DONE
  3532                              <1> 
  3533                              <1> ;;HD_RESET_1:
  3534                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  3535                              <1> ;;	;PUSH	CX
  3536                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  3537                              <1> ;;	INT	13H
  3538                              <1> ;;	JC	short RES_2
  3539                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  3540                              <1> ;;	INT	13H
  3541                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  3542                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  3543                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3544                              <1> ;;					; (30 seconds)		
  3545                              <1> ;;	;cmc
  3546                              <1> ;;	;JNC	short RES_1
  3547                              <1> ;;	jb	short RES_1
  3548                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  3549                              <1> ;;	;TEST	DL,1
  3550                              <1> ;;	;JNZ	RES_E1
  3551                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  3552                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  3553                              <1> ;;	;JMP	SHORT RES_E1
  3554                              <1> ;;RES_ER: ; 22/12/2014
  3555                              <1> ;;RES_OK:
  3556                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3557                              <1> ;;	;POP	BX
  3558                              <1> ;;	RETn
  3559                              <1> ;;
  3560                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  3561                              <1> ;;	INT	13H
  3562                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  3563                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  3564                              <1> ;;	INT	13H
  3565                              <1> ;;	JC	short RES_ER
  3566                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  3567                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  3568                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  3569                              <1> ;;	INT	13H
  3570                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  3571                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  3572                              <1> ;;	JE	short RES_OK
  3573                              <1> ;;	CMP	AH,DATA_CORRECTED
  3574                              <1> ;;	JE	short RES_OK
  3575                              <1> ;;	CMP	AH,BAD_ECC
  3576                              <1> ;;	JE	short RES_OK
  3577                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  3578                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3579                              <1> ;;					; (60 seconds)		
  3580                              <1> ;;	cmc
  3581                              <1> ;;	JC	short RES_ER		; FAILED
  3582                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  3583                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  3584                              <1> ;;	AND	AL,3FH
  3585                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  3586                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  3587                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  3588                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  3589                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  3590                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  3591                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  3592                              <1> ;;	;TEST	DL,1
  3593                              <1> ;;	;JNZ	short RES_E1
  3594                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  3595                              <1> ;;;RES_E1:
  3596                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3597                              <1> ;;;RES_OK:
  3598                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3599                              <1> ;;	;POP	BX
  3600                              <1> ;;	;RETn
  3601                              <1> ;
  3602                              <1> ;;SET_FAIL:
  3603                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  3604                              <1> ;	;CALL	CMOS_READ
  3605                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  3606                              <1> ;	;XCHG	AH,AL			; SAVE IT
  3607                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  3608                              <1> ;	;RETn
  3609                              <1> ;
  3610                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  3611                              <1> ;	;POP	AX			; SAVE RETURN
  3612                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  3613                              <1> ;	;POP	BX
  3614                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  3615                              <1> ;	;PUSH	CX
  3616                              <1> ;	;PUSH	AX
  3617                              <1> ;	;push	ds
  3618                              <1> ;	;xor	ax, ax
  3619                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  3620                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  3621                              <1> ;	;				; BX = START TIME
  3622                              <1> ;	;				; CX = END TIME
  3623                              <1> ;	;pop	ds
  3624                              <1> ;	;CMP	BX,CX
  3625                              <1> ;	;JB	short TCHK1		; START < END
  3626                              <1> ;	;CMP	BX,AX
  3627                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  3628                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  3629                              <1> ;;TCHK1: CMP	AX,BX
  3630                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  3631                              <1> ;;TCHK2: CMP	AX,CX
  3632                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  3633                              <1> ;;					; OR CURRENT < END < START
  3634                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  3635                              <1> ;;	RETn
  3636                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  3637                              <1> ;;	RETn
  3638                              <1> ;;
  3639                              <1> ;;int_13h:
  3640                              <1> 
  3641                              <1> ;----------------------------------------
  3642                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  3643                              <1> ;----------------------------------------
  3644                              <1> 
  3645                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  3646                              <1> int33h:  ; DISK I/O
  3647                              <1> 
  3648                              <1> DISK_IO:
  3649 00002933 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  3650                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  3651                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  3652                              <1> 	;;call	int40h
  3653 00002936 0F8225F1FFFF        <1> 	jb	DISKETTE_IO_1
  3654                              <1> ;RET_2:
  3655                              <1> 	;RETf	2			; BACK TO CALLER
  3656                              <1> ;	retf	4
  3657                              <1> A1:
  3658 0000293C FB                  <1> 	STI				; ENABLE INTERRUPTS
  3659                              <1> 	;; 04/01/2015
  3660                              <1> 	;;OR	AH,AH
  3661                              <1> 	;;JNZ	short A2
  3662                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  3663                              <1> 	;;SUB	AH,AH
  3664 0000293D 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  3665 00002940 772C                <1> 	JA	short RET_2
  3666                              <1> 	; 18/01/2015
  3667 00002942 08E4                <1> 	or	ah,ah
  3668 00002944 742B                <1> 	jz	short A4
  3669 00002946 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  3670 00002949 7504                <1> 	jne	short A2
  3671 0000294B 28E4                <1> 	sub	ah,ah	; Reset
  3672 0000294D EB22                <1> 	jmp	short A4
  3673                              <1> A2:
  3674 0000294F 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3675                              <1> 	;JNZ	short A3
  3676                              <1>         ;JMP    GET_PARM_N
  3677 00002952 0F841C030000        <1> 	je	GET_PARM_N
  3678 00002958 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3679                              <1> 	;JNZ	short A4
  3680                              <1>         ;JMP    READ_DASD_TYPE
  3681 0000295B 0F84C7020000        <1>         je      READ_DASD_TYPE
  3682                              <1> 	; 02/02/2015
  3683 00002961 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3684                              <1> 	; 12/01/2015
  3685 00002964 F5                  <1> 	cmc
  3686 00002965 730A                <1> 	jnc	short A4
  3687                              <1> 	; 30/01/2015
  3688                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  3689 00002967 C605[77CF0000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  3690                              <1> 	;jmp	short RET_2
  3691                              <1> RET_2:
  3692 0000296E CA0400              <1> 	retf	4
  3693                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3694 00002971 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3695 00002975 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3696 00002976 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3697 00002977 52                  <1> 	PUSH	eDX
  3698 00002978 1E                  <1> 	PUSH	DS
  3699 00002979 06                  <1> 	PUSH	ES
  3700 0000297A 56                  <1> 	PUSH	eSI
  3701 0000297B 57                  <1> 	PUSH	eDI
  3702                              <1> 	;;04/01/2015
  3703                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  3704                              <1> 	;;JNZ	short A5
  3705                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  3706                              <1> ;;A5:	
  3707                              <1> 	;push	cs
  3708                              <1> 	;pop	ds
  3709                              <1> 	; 21/02/2015
  3710 0000297C 6650                <1> 	push	ax
  3711 0000297E 66B81000            <1> 	mov	ax, KDATA
  3712 00002982 8ED8                <1> 	mov	ds, ax
  3713 00002984 8EC0                <1> 	mov	es, ax	
  3714 00002986 6658                <1> 	pop	ax
  3715 00002988 E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3716                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3717 0000298D 8A25[77CF0000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  3718 00002993 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  3719 00002996 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  3720 00002997 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  3721 00002998 5E                  <1> 	POP	eSI
  3722 00002999 07                  <1>         POP     ES
  3723 0000299A 1F                  <1>         POP     DS
  3724 0000299B 5A                  <1> 	POP	eDX
  3725 0000299C 59                  <1> 	POP	eCX
  3726 0000299D 5B                  <1> 	POP	eBX
  3727 0000299E C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  3728                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  3729 0000299F CA0400              <1> 	retf	4
  3730                              <1> 
  3731                              <1> ; 21/02/2015
  3732                              <1> ;       dw --> dd
  3733                              <1> D1:					; FUNCTION TRANSFER TABLE
  3734 000029A2 [642B0000]          <1> 	dd	DISK_RESET		; 000H
  3735 000029A6 [DB2B0000]          <1> 	dd	RETURN_STATUS		; 001H
  3736 000029AA [E82B0000]          <1> 	dd	DISK_READ		; 002H
  3737 000029AE [F12B0000]          <1> 	dd	DISK_WRITE		; 003H
  3738 000029B2 [FA2B0000]          <1> 	dd	DISK_VERF		; 004H
  3739 000029B6 [122C0000]          <1> 	dd	FMT_TRK 		; 005H
  3740 000029BA [5A2B0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  3741 000029BE [5A2B0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  3742 000029C2 [5A2B0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  3743 000029C6 [D92C0000]          <1> 	dd	INIT_DRV		; 009H
  3744 000029CA [382D0000]          <1> 	dd	RD_LONG 		; 00AH
  3745 000029CE [412D0000]          <1> 	dd	WR_LONG 		; 00BH
  3746 000029D2 [4A2D0000]          <1> 	dd	DISK_SEEK		; 00CH
  3747 000029D6 [642B0000]          <1> 	dd	DISK_RESET		; 00DH
  3748 000029DA [5A2B0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  3749 000029DE [5A2B0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  3750 000029E2 [722D0000]          <1> 	dd	TST_RDY 		; 010H
  3751 000029E6 [962D0000]          <1> 	dd	HDISK_RECAL		; 011H
  3752 000029EA [5A2B0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  3753 000029EE [5A2B0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  3754 000029F2 [CC2D0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  3755                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  3756 000029F6 [5A2B0000]          <1> 	dd	BAD_COMMAND		; 015h
  3757 000029FA [5A2B0000]          <1> 	dd	BAD_COMMAND		; 016h
  3758 000029FE [5A2B0000]          <1> 	dd	BAD_COMMAND		; 017h
  3759 00002A02 [5A2B0000]          <1> 	dd	BAD_COMMAND		; 018h
  3760 00002A06 [5A2B0000]          <1> 	dd	BAD_COMMAND		; 019h
  3761 00002A0A [5A2B0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  3762 00002A0E [E82B0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  3763 00002A12 [F12B0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  3764                              <1> D1L     EQU    $ - D1
  3765                              <1> 
  3766                              <1> DISK_IO_CONT:
  3767                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3768 00002A16 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  3769                              <1> 	;;JNZ	short SU0
  3770                              <1>         ;;JMP    RETURN_STATUS
  3771 00002A19 0F84BC010000        <1> 	je	RETURN_STATUS
  3772                              <1> SU0:
  3773 00002A1F C605[77CF0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3774                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  3775                              <1> 	;mov	si, bx ;; 14/02/2015
  3776 00002A26 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  3777 00002A28 8A1D[78CF0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  3778                              <1> 	;; 04/01/2015
  3779                              <1> 	;;PUSH	AX
  3780 00002A2E 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  3781                              <1> 					; (get drive number as 0 to 3)
  3782 00002A31 38D3                <1> 	CMP	BL,DL
  3783                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  3784 00002A33 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  3785                              <1>         ;
  3786                              <1> 	;;03/01/2015
  3787 00002A39 29DB                <1> 	sub	ebx, ebx
  3788 00002A3B 88D3                <1> 	mov	bl, dl
  3789                              <1> 	;sub	bh, bh
  3790 00002A3D 883D[8CCF0000]      <1> 	mov	[LBAMode], bh 	; 0
  3791                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  3792                              <1> 	;test	byte [ebx+hd0_type], 1
  3793                              <1> 	;jz	short su1		; no
  3794                              <1> 	;inc	byte [LBAMode]
  3795                              <1> ;su1:
  3796                              <1> 	; 21/02/2015 (32 bit modification)
  3797                              <1> 	;04/01/2015
  3798 00002A43 6650                <1> 	push	ax ; ***
  3799                              <1> 	;PUSH	ES ; **
  3800 00002A45 6652                <1> 	PUSH	DX ; *
  3801 00002A47 6650                <1> 	push	ax
  3802 00002A49 E864060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  3803                              <1> 	; 02/02/2015
  3804                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  3805 00002A4E 668B4310            <1> 	mov	ax, [ebx+16]
  3806 00002A52 66A3[64C90000]      <1> 	mov	[HF_PORT], ax
  3807                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  3808 00002A58 668B5312            <1> 	mov	dx, [ebx+18]
  3809 00002A5C 668915[66C90000]    <1> 	mov	[HF_REG_PORT], dx
  3810                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  3811 00002A63 8A4314              <1> 	mov	al, [ebx+20]
  3812                              <1> 	; 23/02/2015
  3813 00002A66 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  3814 00002A68 7406                <1> 	jz 	short su1
  3815 00002A6A FE05[8CCF0000]      <1> 	inc	byte [LBAMode] ; 1 
  3816                              <1> su1: 	 
  3817 00002A70 C0E804              <1> 	shr 	al, 4
  3818 00002A73 2401                <1> 	and	al, 1			
  3819 00002A75 A2[68C90000]        <1> 	mov	[hf_m_s], al 
  3820                              <1> 	;
  3821                              <1> 	; 03/01/2015
  3822                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  3823 00002A7A 8A4308              <1> 	mov	al, [ebx+8]
  3824                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  3825 00002A7D EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  3826                              <1> 					; Control Byte:  (= 08h, here)
  3827                              <1> 					; bit 0 - 0
  3828                              <1> 					; bit 1 - nIEN (1 = disable irq)
  3829                              <1> 					; bit 2 - SRST (software RESET)
  3830                              <1> 					; bit 3 - use extra heads (8 to 15)
  3831                              <1> 					;         -always set to 1-	
  3832                              <1> 					; (bits 3 to 7 are reserved
  3833                              <1> 					;          for ATA devices)
  3834 00002A7E 8A25[79CF0000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  3835 00002A84 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  3836 00002A87 08C4                <1> 	OR	AH,AL
  3837 00002A89 8825[79CF0000]      <1> 	MOV	[CONTROL_BYTE],AH	
  3838                              <1> 	; 04/01/2015
  3839 00002A8F 6658                <1> 	pop	ax
  3840 00002A91 665A                <1> 	pop	dx ; * ;; 14/02/2015
  3841 00002A93 20E4                <1> 	and	ah, ah	; Reset function ?
  3842 00002A95 7507                <1> 	jnz	short su2
  3843                              <1> 	;;pop	dx ; * ;; 14/02/2015
  3844                              <1> 	;pop	es ; **
  3845 00002A97 6658                <1> 	pop	ax ; ***
  3846                              <1> 	;;pop	bx
  3847 00002A99 E9C6000000          <1>         jmp     DISK_RESET
  3848                              <1> su2:
  3849 00002A9E 803D[8CCF0000]00    <1> 	cmp	byte [LBAMode], 0
  3850 00002AA5 7661                <1> 	jna	short su3
  3851                              <1> 	;
  3852                              <1> 	; 02/02/2015 (LBA read/write function calls)
  3853 00002AA7 80FC1B              <1> 	cmp	ah, 1Bh
  3854 00002AAA 720B                <1> 	jb	short lbarw1
  3855 00002AAC 80FC1C              <1> 	cmp	ah, 1Ch
  3856 00002AAF 775C                <1> 	ja 	short invldfnc
  3857                              <1> 	;;pop	dx ; * ; 14/02/2015
  3858                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  3859 00002AB1 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  3860                              <1> 	;; 14/02/2015
  3861 00002AB3 88D1                <1> 	mov	cl, dl ; 14/02/2015
  3862                              <1> 	;;mov	dx, bx
  3863                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  3864                              <1> 	;;mov	bx, di
  3865                              <1> 	;mov	si, di ; Buffer offset
  3866 00002AB5 EB31                <1> 	jmp	short lbarw2
  3867                              <1> lbarw1:
  3868                              <1> 	; convert CHS to LBA
  3869                              <1> 	;
  3870                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  3871                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  3872                              <1> 	;	+ Sector - 1
  3873 00002AB7 6652                <1> 	push	dx ; * ;; 14/02/2015
  3874                              <1> 	;xor	dh, dh
  3875 00002AB9 31D2                <1> 	xor	edx, edx
  3876                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  3877 00002ABB 8A530E              <1> 	mov	dl, [ebx+14]
  3878                              <1> 	;xor	ah, ah
  3879 00002ABE 31C0                <1> 	xor	eax, eax
  3880                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  3881 00002AC0 8A4302              <1> 	mov	al, [ebx+2]
  3882 00002AC3 FEC8                <1> 	dec	al
  3883 00002AC5 6640                <1> 	inc	ax		; 0 =  256
  3884 00002AC7 66F7E2              <1> 	mul 	dx
  3885                              <1> 		; AX = # of Heads" * Sectors/Track
  3886 00002ACA 6689CA              <1> 	mov	dx, cx
  3887                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  3888 00002ACD 83E13F              <1> 	and	ecx, 3fh
  3889 00002AD0 86D6                <1> 	xchg	dl, dh
  3890 00002AD2 C0EE06              <1> 	shr	dh, 6
  3891                              <1> 		; DX = cylinder (0 to 1023)
  3892                              <1> 	;mul 	dx
  3893                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  3894 00002AD5 F7E2                <1> 	mul	edx
  3895 00002AD7 FEC9                <1> 	dec	cl  ; sector - 1
  3896                              <1> 	;add	ax, cx
  3897                              <1> 	;adc	dx, 0
  3898                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  3899 00002AD9 01C8                <1> 	add	eax, ecx
  3900 00002ADB 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  3901                              <1> 	;push	dx
  3902                              <1> 	;push	ax
  3903 00002ADD 50                  <1> 	push	eax
  3904                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  3905 00002ADE 8A430E              <1> 	mov	al, [ebx+14]
  3906 00002AE1 F6E5                <1> 	mul	ch
  3907                              <1> 		;  AX = Head * Sectors/Track
  3908 00002AE3 6699                <1>         cwd
  3909                              <1> 	;pop	dx
  3910 00002AE5 5A                  <1> 	pop	edx
  3911                              <1> 	;add	ax, dx
  3912                              <1> 	;pop	dx
  3913                              <1> 	;adc	dx, 0 ; add carry bit
  3914 00002AE6 01D0                <1> 	add	eax, edx
  3915                              <1> lbarw2:
  3916 00002AE8 29D2                <1> 	sub	edx, edx ; 21/02/2015
  3917 00002AEA 88CA                <1> 	mov	dl, cl ; 21/02/2015
  3918 00002AEC C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  3919                              <1> 				; NOTE: Features register (1F1h, 171h)
  3920                              <1> 				; is not used for ATA device R/W functions. 
  3921                              <1> 				; It is old/obsolete 'write precompensation'
  3922                              <1> 				; register and error register
  3923                              <1> 				; for old ATA/IDE devices.
  3924                              <1> 	; 18/01/2014
  3925                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  3926 00002AF0 8A0D[68C90000]      <1> 	mov	cl, [hf_m_s]
  3927                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  3928                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  3929                              <1> 				; bit 6 = 1 = LBA mode
  3930                              <1> 				; bit 7 = 1
  3931 00002AF6 80C90E              <1> 	or	cl, 0Eh ; 1110b
  3932                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  3933 00002AF9 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  3934 00002AFE C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  3935                              <1> 	;or	dh, ch
  3936 00002B01 09C8                <1> 	or	eax, ecx	
  3937                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  3938                              <1> 				  ; (Sector Number Register)
  3939                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  3940                              <1> 				  ; (Cylinder Low Register)
  3941                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  3942                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  3943                              <1> 				  ; (Cylinder High Register)
  3944                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  3945                              <1> 				  ; (Drive/Head Register)
  3946                              <1> 	
  3947                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  3948 00002B03 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  3949                              <1> 	;14/02/2015
  3950                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  3951 00002B06 EB38                <1> 	jmp	short su4
  3952                              <1> su3:
  3953                              <1> 	; 02/02/2015 
  3954                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  3955 00002B08 80FC14              <1> 	cmp 	ah, 14h
  3956 00002B0B 7604                <1> 	jna 	short chsfnc
  3957                              <1> invldfnc:
  3958                              <1>         ; 14/02/2015  
  3959                              <1> 	;pop	es ; **
  3960 00002B0D 6658                <1>         pop     ax ; ***
  3961                              <1>         ;jmp     short BAD_COMMAND_POP
  3962 00002B0F EB49                <1>         jmp     short BAD_COMMAND
  3963                              <1> chsfnc:	
  3964                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  3965 00002B11 668B4305            <1> 	mov	ax, [ebx+5]
  3966 00002B15 66C1E802            <1> 	SHR	AX,2
  3967 00002B19 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  3968                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  3969                              <1> 	;;PUSH	DX
  3970                              <1> 	;;MOV	DX,[HF_REG_PORT]
  3971                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  3972                              <1> 	;;POP	DX ; * 
  3973                              <1> 	;;POP	ES ; **
  3974                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  3975                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  3976                              <1> 	;;OR	AH,AL
  3977                              <1> 	;;MOV	[CONTROL_BYTE],AH
  3978                              <1> 	;
  3979 00002B1C 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  3980 00002B1E 243F                <1> 	AND	AL,3FH
  3981 00002B20 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  3982 00002B23 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  3983 00002B26 88C8                <1> 	MOV	AL,CL
  3984 00002B28 C0E806              <1> 	SHR	AL,6
  3985 00002B2B 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  3986                              <1> 	;;05/01/2015
  3987                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  3988 00002B2E A0[68C90000]        <1> 	mov	al, [hf_m_s]
  3989 00002B33 C0E004              <1> 	SHL	AL,4
  3990 00002B36 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  3991 00002B39 08F0                <1> 	OR	AL,DH
  3992                              <1> 	;OR	AL,80H or 20H
  3993 00002B3B 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  3994 00002B3D 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  3995                              <1> su4:
  3996                              <1> 	;POP	ES ; **
  3997                              <1>         ;; 14/02/2015
  3998                              <1>         ;;POP   AX
  3999                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  4000                              <1>         ;;PUSH  AX
  4001                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  4002                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  4003                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  4004 00002B40 6658                <1>         pop     ax ; ***
  4005 00002B42 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4006 00002B45 29DB                <1>         sub	ebx, ebx
  4007 00002B47 88E3                <1> 	mov     bl, ah
  4008                              <1>         ;xor     bh, bh
  4009                              <1>         ;sal     bx, 1
  4010 00002B49 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  4011                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  4012                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  4013                              <1>         ;;JNB   short BAD_COMMAND_POP
  4014                              <1>         ;cmp     bx, D1L
  4015 00002B4D 83FB74              <1> 	cmp	ebx, D1L
  4016 00002B50 7308                <1> 	jnb	short BAD_COMMAND
  4017                              <1>         ;xchg    bx, si
  4018 00002B52 87DE                <1>         xchg	ebx, esi
  4019                              <1> 	;;;POP	AX			; RESTORE AX
  4020                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  4021                              <1> 	
  4022                              <1> 	;;PUSH	CX
  4023                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  4024                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  4025                              <1> 	;SHR	CX,4
  4026                              <1> 	;MOV	AX,ES
  4027                              <1> 	;ADD	AX,CX
  4028                              <1> 	;MOV	ES,AX
  4029                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  4030                              <1> 	;;POP	AX
  4031                              <1> 	;;POP	CX
  4032                              <1> 	;;JMP	word [CS:SI+D1]
  4033                              <1> 	;jmp	word [SI+D1]
  4034 00002B54 FFA6[A2290000]      <1> 	jmp	dword [esi+D1]
  4035                              <1> ;;BAD_COMMAND_POP:
  4036                              <1> ;;	POP	AX
  4037                              <1> ;;	POP	BX
  4038                              <1> BAD_COMMAND:
  4039 00002B5A C605[77CF0000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4040 00002B61 B000                <1> 	MOV	AL,0
  4041 00002B63 C3                  <1> 	RETn
  4042                              <1> 
  4043                              <1> ;----------------------------------------
  4044                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  4045                              <1> ;----------------------------------------
  4046                              <1> 
  4047                              <1> ; 18-1-2015 : one controller reset (not other one)
  4048                              <1> 
  4049                              <1> DISK_RESET:
  4050 00002B64 FA                  <1> 	CLI
  4051 00002B65 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4052                              <1> 	;JMP	$+2
  4053                              <1> 	IODELAY
  4053 00002B67 EB00                <2>  jmp short $+2
  4053 00002B69 EB00                <2>  jmp short $+2
  4054                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4055 00002B6B 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4056 00002B6D E6A1                <1> 	OUT	INTB01,AL
  4057 00002B6F FB                  <1> 	STI				; START INTERRUPTS
  4058                              <1> 	; 14/02/2015
  4059 00002B70 6689D7              <1> 	mov	di, dx	
  4060                              <1> 	; 04/01/2015
  4061                              <1> 	;xor	di,di
  4062                              <1> drst0:
  4063 00002B73 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4064                              <1> 	;MOV	DX,HF_REG_PORT
  4065 00002B75 668B15[66C90000]    <1> 	MOV	DX,[HF_REG_PORT]
  4066 00002B7C EE                  <1> 	OUT	DX,AL			; RESET
  4067                              <1> ;	MOV	CX,10			; DELAY COUNT
  4068                              <1> ;DRD:	DEC	CX
  4069                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  4070                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  4071 00002B7D B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4072 00002B82 E871EDFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4073                              <1>                                         ; 40 micro seconds)
  4074 00002B87 A0[79CF0000]        <1> 	mov	al,[CONTROL_BYTE]
  4075 00002B8C 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4076 00002B8E EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4077 00002B8F E814040000          <1> 	CALL	NOT_BUSY
  4078 00002B94 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4079 00002B96 668B15[64C90000]    <1> 	MOV	DX,[HF_PORT]
  4080 00002B9D FEC2                <1> 	inc	dl  ; HF_PORT+1
  4081                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4082                              <1>         ;mov     cl, 10
  4083 00002B9F B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4084                              <1> drst1:
  4085 00002BA4 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4086 00002BA5 3C01                <1> 	CMP	AL,1
  4087                              <1> 	; 04/01/2015
  4088 00002BA7 740A                <1> 	jz	short drst2
  4089                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4090                              <1>         	; Drive/Head Register - bit 4
  4091 00002BA9 E2F9                <1> 	loop	drst1
  4092                              <1> DRERR:	
  4093 00002BAB C605[77CF0000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4094 00002BB2 C3                  <1> 	RETn
  4095                              <1> drst2:
  4096                              <1> 	; 14/02/2015
  4097 00002BB3 6689FA              <1> 	mov	dx,di
  4098                              <1> ;drst3:
  4099                              <1> ;	; 05/01/2015
  4100                              <1> ;	shl 	di,1
  4101                              <1> ;	; 04/01/2015
  4102                              <1> ;	mov	ax,[di+hd_cports]
  4103                              <1> ;	cmp	ax,[HF_REG_PORT]
  4104                              <1> ;	je	short drst4
  4105                              <1> ;	mov	[HF_REG_PORT], ax
  4106                              <1> ;	; 03/01/2015
  4107                              <1> ;	mov	ax,[di+hd_ports]
  4108                              <1> ;       mov     [HF_PORT], ax
  4109                              <1> ;	; 05/01/2014
  4110                              <1> ;	shr	di,1
  4111                              <1> ;	; 04/01/2015
  4112                              <1> ;	jmp	short drst0	; reset other controller
  4113                              <1> ;drst4:
  4114                              <1> ;	; 05/01/2015
  4115                              <1> ;	shr	di,1
  4116                              <1> ;	mov	al,[di+hd_dregs]
  4117                              <1> ;	and	al,10h ; bit 4 only
  4118                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  4119                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  4120                              <1> 	;
  4121 00002BB6 A0[68C90000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4122 00002BBB A801                <1> 	test	al,1
  4123                              <1> ;	jnz	short drst6
  4124 00002BBD 7516                <1>         jnz     short drst4
  4125 00002BBF 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4126                              <1> ;drst5:
  4127                              <1> drst3:
  4128 00002BC3 E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4129                              <1> 	;mov	dx,di
  4130 00002BC8 E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  4131                              <1> 	; 04/01/2014
  4132                              <1> ;	inc	di
  4133                              <1> ;	mov	dx,di
  4134                              <1> ;	cmp	dl,[HF_NUM]
  4135                              <1> ;	jb	short drst3
  4136                              <1> ;DRE:
  4137 00002BCD C605[77CF0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4138 00002BD4 C3                  <1> 	RETn
  4139                              <1> ;drst6:
  4140                              <1> drst4:		; Drive/Head Register - bit 4
  4141 00002BD5 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4142                              <1>         ;jmp    short drst5
  4143 00002BD9 EBE8                <1>         jmp     short drst3
  4144                              <1> 
  4145                              <1> ;----------------------------------------
  4146                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  4147                              <1> ;----------------------------------------
  4148                              <1> 
  4149                              <1> RETURN_STATUS:
  4150 00002BDB A0[77CF0000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4151 00002BE0 C605[77CF0000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4152 00002BE7 C3                  <1> 	RETn
  4153                              <1> 
  4154                              <1> ;----------------------------------------
  4155                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4156                              <1> ;----------------------------------------
  4157                              <1> 
  4158                              <1> DISK_READ:
  4159 00002BE8 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4160 00002BEC E930020000          <1>         JMP     COMMANDI
  4161                              <1> 
  4162                              <1> ;----------------------------------------
  4163                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4164                              <1> ;----------------------------------------
  4165                              <1> 
  4166                              <1> DISK_WRITE:
  4167 00002BF1 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4168 00002BF5 E982020000          <1>         JMP     COMMANDO
  4169                              <1> 
  4170                              <1> ;----------------------------------------
  4171                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4172                              <1> ;----------------------------------------
  4173                              <1> 
  4174                              <1> DISK_VERF:
  4175 00002BFA C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4176 00002BFE E8F0020000          <1> 	CALL	COMMAND
  4177 00002C03 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4178 00002C05 E862030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4179 00002C0A 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4180 00002C0C E8EF030000          <1> 	CALL	CHECK_STATUS
  4181                              <1> VERF_EXIT:
  4182 00002C11 C3                  <1> 	RETn
  4183                              <1> 
  4184                              <1> ;----------------------------------------
  4185                              <1> ;	FORMATTING	     (AH = 05H) :
  4186                              <1> ;----------------------------------------
  4187                              <1> 
  4188                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  4189 00002C12 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4190                              <1> 	;PUSH	ES
  4191                              <1> 	;PUSH	BX
  4192 00002C16 53                  <1> 	push	ebx
  4193 00002C17 E896040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4194                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4195 00002C1C 8A430E              <1> 	mov	al, [ebx+14]
  4196 00002C1F 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4197 00002C22 5B                  <1> 	pop	ebx
  4198                              <1> 	;POP	BX
  4199                              <1> 	;POP	ES
  4200 00002C23 E95B020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  4201                              <1> 
  4202                              <1> ;----------------------------------------
  4203                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  4204                              <1> ;----------------------------------------
  4205                              <1> 
  4206                              <1> READ_DASD_TYPE:
  4207                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  4208 00002C28 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4209                              <1> 	;PUSH	ES
  4210 00002C29 53                  <1> 	PUSH	eBX
  4211                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4212                              <1> 	;push	cs
  4213                              <1> 	;pop	ds
  4214 00002C2A 66BB1000            <1>         mov	bx, KDATA
  4215 00002C2E 8EDB                <1> 	mov	ds, bx
  4216                              <1> 	;mov	es, bx
  4217 00002C30 C605[77CF0000]00    <1> 	MOV     byte [DISK_STATUS1],0
  4218 00002C37 8A1D[78CF0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4219 00002C3D 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4220 00002C40 38D3                <1> 	CMP	BL,DL
  4221 00002C42 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4222 00002C44 E869040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  4223                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4224 00002C49 8A4302              <1> 	mov	al, [ebx+2]
  4225                              <1> 	;MOV	CL,[ES:BX+14]
  4226 00002C4C 8A4B0E              <1> 	mov	cl, [ebx+14]
  4227 00002C4F F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4228                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4229 00002C51 668B0B              <1> 	mov	cx ,[ebx]
  4230                              <1> 	;
  4231                              <1> 	; 02/01/2015 
  4232                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  4233                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  4234 00002C54 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4235                              <1> 	;
  4236 00002C56 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4237 00002C59 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4238 00002C5C 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4239                              <1> 	;SUB	AX,AX
  4240 00002C5F 28C0                <1> 	sub	al, al
  4241 00002C61 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4242 00002C63 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  4243                              <1> 	;POP	ES
  4244 00002C64 1F                  <1> 	POP	DS
  4245 00002C65 F8                  <1> 	CLC				; CLEAR CARRY
  4246                              <1> 	;RETf	2
  4247 00002C66 CA0400              <1> 	retf	4
  4248                              <1> RDT_NOT_PRESENT:
  4249 00002C69 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4250 00002C6C 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4251 00002C6F 6689C2              <1> 	MOV	DX,AX
  4252 00002C72 EBEF                <1> 	JMP	short RDT2
  4253                              <1> 
  4254                              <1> ;----------------------------------------
  4255                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  4256                              <1> ;----------------------------------------
  4257                              <1> 
  4258                              <1> GET_PARM_N:
  4259                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  4260 00002C74 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4261                              <1> 	;PUSH	ES
  4262 00002C75 53                  <1> 	PUSH	eBX
  4263                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  4264                              <1> 	;MOV	DS,AX
  4265                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  4266                              <1> 	;JZ	short G0
  4267                              <1> 	;LES	BX,@HF1_TBL_VEC
  4268                              <1> 	;JMP	SHORT G1
  4269                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  4270                              <1> ;G1:
  4271                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  4272                              <1> 	; 22/12/2014
  4273                              <1> 	;push	cs
  4274                              <1> 	;pop	ds
  4275 00002C76 66BB1000            <1> 	mov	bx, KDATA
  4276 00002C7A 8EDB                <1> 	mov	ds, bx
  4277                              <1> 	;mov	es, bx
  4278                              <1> 	;
  4279 00002C7C 80EA80              <1> 	SUB	DL,80H
  4280 00002C7F 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4281 00002C82 7341                <1> 	JAE	short G4
  4282                              <1> 	;
  4283 00002C84 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4284                              <1> 	; 22/12/2014
  4285 00002C86 88D3                <1> 	mov	bl, dl
  4286                              <1> 	;xor	bh, bh  
  4287 00002C88 C0E302              <1> 	shl	bl, 2			; convert index to offset
  4288                              <1> 	;add	bx, HF_TBL_VEC
  4289 00002C8B 81C3[7CCF0000]      <1> 	add	ebx, HF_TBL_VEC
  4290                              <1> 	;mov	ax, [bx+2]
  4291                              <1> 	;mov	es, ax			; dpt segment
  4292                              <1> 	;mov	bx, [bx]		; dpt offset
  4293 00002C91 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4294                              <1> 
  4295 00002C93 C605[77CF0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4296                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  4297 00002C9A 668B03              <1> 	mov	ax, [ebx]
  4298                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4299 00002C9D 6648                <1> 	dec	ax			; max. cylinder number
  4300 00002C9F 88C5                <1> 	MOV	CH,AL
  4301 00002CA1 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4302 00002CA5 66D1E8              <1> 	SHR	AX,1
  4303 00002CA8 66D1E8              <1> 	SHR	AX,1
  4304                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4305 00002CAB 0A430E              <1> 	or	al, [ebx+14]
  4306 00002CAE 88C1                <1> 	MOV	CL,AL
  4307                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4308 00002CB0 8A7302              <1> 	mov	dh, [ebx+2]
  4309 00002CB3 FECE                <1> 	DEC	DH			; 0-N RANGE
  4310 00002CB5 8A15[78CF0000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4311 00002CBB 6629C0              <1> 	SUB	AX,AX
  4312                              <1>         ;27/12/2014 
  4313                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  4314                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  4315                              <1> 	;mov	di, bx			; HDPT offset
  4316 00002CBE 89DF                <1> 	mov	edi, ebx
  4317                              <1> G5:
  4318 00002CC0 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  4319                              <1> 	;POP	ES
  4320 00002CC1 1F                  <1> 	POP	DS
  4321                              <1> 	;RETf	2
  4322 00002CC2 CA0400              <1> 	retf	4
  4323                              <1> G4:
  4324 00002CC5 C605[77CF0000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4325 00002CCC B407                <1> 	MOV	AH,INIT_FAIL
  4326 00002CCE 28C0                <1> 	SUB	AL,AL
  4327 00002CD0 6629D2              <1> 	SUB	DX,DX
  4328 00002CD3 6629C9              <1> 	SUB	CX,CX
  4329 00002CD6 F9                  <1> 	STC				; SET ERROR FLAG
  4330 00002CD7 EBE7                <1> 	JMP	short G5
  4331                              <1> 
  4332                              <1> ;----------------------------------------
  4333                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  4334                              <1> ;----------------------------------------
  4335                              <1> 	; 03/01/2015
  4336                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  4337                              <1> 	; logical sector per logical track
  4338                              <1> 	; and logical heads - 1 would be set but
  4339                              <1> 	; it is seen as it will be good
  4340                              <1> 	; if physical parameters will be set here
  4341                              <1> 	; because, number of heads <= 16.
  4342                              <1> 	; (logical heads usually more than 16)
  4343                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  4344                              <1> 	;	== INT 13h physical parameters
  4345                              <1> 
  4346                              <1> ;INIT_DRV:
  4347                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  4348                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  4349                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  4350                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  4351                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  4352                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  4353                              <1> ;	OR	AH,AL			; TO MAX HEAD
  4354                              <1> ;	MOV	[CMD_BLOCK+5],AH
  4355                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  4356                              <1> ;	MOV	[CMD_BLOCK+1],AL
  4357                              <1> ;	SUB	AX,AX
  4358                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  4359                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  4360                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  4361                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  4362                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  4363                              <1> ;	CALL	CHECK_STATUS
  4364                              <1> ;INIT_EXIT:
  4365                              <1> ;	RETn
  4366                              <1> 
  4367                              <1> ; 04/01/2015
  4368                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  4369                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  4370                              <1> INIT_DRV:
  4371                              <1> 	;xor	ah,ah
  4372 00002CD9 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4373 00002CDB B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4374 00002CDD 3825[8CCF0000]      <1>         cmp     [LBAMode], ah   ; 0
  4375 00002CE3 7702                <1> 	ja	short idrv0
  4376 00002CE5 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4377                              <1> idrv0:
  4378                              <1> 	; DL = drive number (0 based)
  4379 00002CE7 E8C6030000          <1> 	call	GET_VEC
  4380                              <1> 	;push	bx
  4381 00002CEC 53                  <1> 	push	ebx ; 21/02/2015
  4382                              <1> 	;add	bx,ax
  4383 00002CED 01C3                <1> 	add	ebx, eax
  4384                              <1> 	;; 05/01/2015
  4385 00002CEF 8A25[68C90000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4386                              <1> 	;;and 	ah,1 
  4387 00002CF5 C0E404              <1> 	shl	ah,4
  4388 00002CF8 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4389                              <1> 	;mov	al,[es:bx]
  4390 00002CFB 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4391 00002CFD FEC8                <1> 	dec	al	 ; last head number 
  4392                              <1> 	;and	al,0Fh
  4393 00002CFF 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4394                              <1> 	;
  4395 00002D01 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4396 00002D05 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4397                              <1> 	;pop	bx
  4398 00002D08 5B                  <1> 	pop	ebx
  4399 00002D09 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4400 00002D0B B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4401 00002D0D 803D[8CCF0000]00    <1> 	cmp	byte [LBAMode], 0
  4402 00002D14 7702                <1> 	ja	short idrv1
  4403 00002D16 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  4404                              <1> idrv1:
  4405                              <1> 	;xor	ah,ah
  4406                              <1> 	;add	bx,ax
  4407 00002D18 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4408                              <1> 	;mov	al,[es:bx]
  4409                              <1> 			; sector number
  4410 00002D1A 8A03                <1> 	mov	al, [ebx]
  4411 00002D1C 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4412 00002D1F 28C0                <1> 	sub	al,al
  4413 00002D21 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4414 00002D24 E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4415 00002D29 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4416 00002D2B E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4417 00002D30 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4418 00002D32 E8C9020000          <1> 	call	CHECK_STATUS
  4419                              <1> INIT_EXIT:
  4420 00002D37 C3                  <1> 	RETn
  4421                              <1> 
  4422                              <1> ;----------------------------------------
  4423                              <1> ;	READ LONG	     (AH = 0AH) :
  4424                              <1> ;----------------------------------------
  4425                              <1> 
  4426                              <1> RD_LONG:
  4427                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  4428 00002D38 C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4429 00002D3C E9E0000000          <1>         JMP     COMMANDI
  4430                              <1> 
  4431                              <1> ;----------------------------------------
  4432                              <1> ;	WRITE LONG	     (AH = 0BH) :
  4433                              <1> ;----------------------------------------
  4434                              <1> 
  4435                              <1> WR_LONG:
  4436                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  4437 00002D41 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4438 00002D45 E932010000          <1>         JMP     COMMANDO
  4439                              <1> 
  4440                              <1> ;----------------------------------------
  4441                              <1> ;	SEEK		     (AH = 0CH) :
  4442                              <1> ;----------------------------------------
  4443                              <1> 
  4444                              <1> DISK_SEEK:
  4445 00002D4A C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4446 00002D4E E8A0010000          <1> 	CALL	COMMAND
  4447 00002D53 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4448 00002D55 E812020000          <1> 	CALL	_WAIT
  4449 00002D5A 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4450 00002D5C E89F020000          <1> 	CALL	CHECK_STATUS
  4451 00002D61 803D[77CF0000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4452 00002D68 7507                <1> 	JNE	short DS_EXIT
  4453 00002D6A C605[77CF0000]00    <1>         MOV     byte [DISK_STATUS1],0
  4454                              <1> DS_EXIT:
  4455 00002D71 C3                  <1> 	RETn
  4456                              <1> 
  4457                              <1> ;----------------------------------------
  4458                              <1> ;	TEST DISK READY      (AH = 10H) :
  4459                              <1> ;----------------------------------------
  4460                              <1> 
  4461                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  4462 00002D72 E831020000          <1> 	CALL	NOT_BUSY
  4463 00002D77 751C                <1> 	JNZ	short TR_EX
  4464 00002D79 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4465 00002D7C 668B15[64C90000]    <1> 	MOV	DX,[HF_PORT]
  4466 00002D83 80C206              <1> 	add	dl,6
  4467 00002D86 EE                  <1> 	OUT	DX,AL
  4468 00002D87 E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4469 00002D8C 7507                <1> 	JNZ	short TR_EX
  4470 00002D8E C605[77CF0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4471                              <1> TR_EX:	
  4472 00002D95 C3                  <1> 	RETn
  4473                              <1> 
  4474                              <1> ;----------------------------------------
  4475                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4476                              <1> ;----------------------------------------
  4477                              <1> 
  4478                              <1> HDISK_RECAL:
  4479 00002D96 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4480 00002D9A E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4481 00002D9F 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4482 00002DA1 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4483 00002DA6 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4484 00002DA8 E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4485 00002DAD 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4486                              <1> RECAL_X:
  4487 00002DAF E84C020000          <1> 	CALL	CHECK_STATUS
  4488 00002DB4 803D[77CF0000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4489 00002DBB 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4490 00002DBD C605[77CF0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4491                              <1> RECAL_EXIT:
  4492 00002DC4 803D[77CF0000]00    <1>         CMP     byte [DISK_STATUS1],0
  4493 00002DCB C3                  <1> 	RETn
  4494                              <1> 
  4495                              <1> ;----------------------------------------
  4496                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4497                              <1> ;----------------------------------------
  4498                              <1> 
  4499                              <1> CTLR_DIAGNOSTIC:
  4500 00002DCC FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4501 00002DCD E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4502                              <1> 	;AND	AL,0BFH
  4503 00002DCF 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4504                              <1> 	;JMP	$+2
  4505                              <1> 	IODELAY
  4505 00002DD1 EB00                <2>  jmp short $+2
  4505 00002DD3 EB00                <2>  jmp short $+2
  4506 00002DD5 E6A1                <1> 	OUT	INTB01,AL
  4507                              <1> 	IODELAY
  4507 00002DD7 EB00                <2>  jmp short $+2
  4507 00002DD9 EB00                <2>  jmp short $+2
  4508 00002DDB E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4509 00002DDD 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4510                              <1> 	;JMP	$+2
  4511                              <1> 	IODELAY
  4511 00002DDF EB00                <2>  jmp short $+2
  4511 00002DE1 EB00                <2>  jmp short $+2
  4512 00002DE3 E621                <1> 	OUT	INTA01,AL
  4513 00002DE5 FB                  <1> 	STI
  4514 00002DE6 E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4515 00002DEB 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4516                              <1> 	;MOV	DX, HF_PORT+7
  4517 00002DED 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4518 00002DF4 80C207              <1> 	add	dl, 7
  4519 00002DF7 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4520 00002DF9 EE                  <1> 	OUT	DX,AL
  4521 00002DFA E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4522 00002DFF B480                <1> 	MOV	AH,TIME_OUT
  4523 00002E01 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4524                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4525 00002E03 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4526 00002E0A FEC2                <1> 	inc	dl
  4527 00002E0C EC                  <1> 	IN	AL,DX
  4528 00002E0D A2[6ECF0000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4529 00002E12 B400                <1> 	MOV	AH,0
  4530 00002E14 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4531 00002E16 7402                <1> 	JE	SHORT CD_EXIT
  4532 00002E18 B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4533                              <1> CD_EXIT:
  4534 00002E1A 8825[77CF0000]      <1> 	MOV	[DISK_STATUS1],AH
  4535 00002E20 C3                  <1> 	RETn
  4536                              <1> 
  4537                              <1> ;----------------------------------------
  4538                              <1> ; COMMANDI				:
  4539                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  4540                              <1> ;	NSECTOR RETURNS ZERO		:
  4541                              <1> ;----------------------------------------
  4542                              <1> COMMANDI:
  4543 00002E21 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4544 00002E26 7253                <1> 	JC	short CMD_ABORT
  4545                              <1> 	;MOV	DI,BX
  4546 00002E28 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4547 00002E2A E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4548 00002E2F 754A                <1> 	JNZ	short CMD_ABORT
  4549                              <1> CMD_I1:
  4550 00002E31 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4551 00002E36 7543                <1> 	JNZ	short TM_OUT		; TIME OUT
  4552                              <1> cmd_i1x: ; 18/02/2016
  4553                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  4554 00002E38 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4555                              <1> 	;MOV	DX,HF_PORT
  4556 00002E3D 668B15[64C90000]    <1> 	mov	dx,[HF_PORT]
  4557 00002E44 FA                  <1> 	CLI
  4558 00002E45 FC                  <1> 	CLD
  4559 00002E46 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4560 00002E49 FB                  <1> 	STI
  4561 00002E4A F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4562 00002E4E 7419                <1> 	JZ	short CMD_I3
  4563 00002E50 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4564 00002E55 7224                <1> 	JC	short TM_OUT
  4565                              <1> 	;MOV	DX,HF_PORT
  4566 00002E57 668B15[64C90000]    <1> 	mov	dx,[HF_PORT]
  4567                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4568 00002E5E B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4569 00002E63 EC                  <1> CMD_I2: IN	AL,DX
  4570                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4571 00002E64 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4572 00002E66 47                  <1> 	INC	eDI
  4573 00002E67 E2FA                <1> 	LOOP	CMD_I2
  4574                              <1> CMD_I3: 
  4575                              <1> 	; wait for 400 ns
  4576 00002E69 80C207              <1> 	add 	dl, 7
  4577 00002E6C EC                  <1> 	in	al, dx
  4578 00002E6D EC                  <1> 	in	al, dx
  4579 00002E6E EC                  <1> 	in	al, dx
  4580                              <1> 	;
  4581 00002E6F E88C010000          <1> 	CALL	CHECK_STATUS
  4582 00002E74 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4583 00002E76 FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4584                              <1> 	;JNZ	SHORT CMD_I1
  4585 00002E79 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4586                              <1> CMD_ABORT:
  4587 00002E7B C3                  <1> TM_OUT: RETn
  4588                              <1> 
  4589                              <1> ;----------------------------------------
  4590                              <1> ; COMMANDO				:
  4591                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  4592                              <1> ;	NSECTOR RETURNS ZERO		:
  4593                              <1> ;----------------------------------------
  4594                              <1> COMMANDO:
  4595 00002E7C E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4596 00002E81 72F8                <1> 	JC	short CMD_ABORT
  4597 00002E83 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4598 00002E85 E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4599 00002E8A 75EF                <1> 	JNZ	short CMD_ABORT
  4600 00002E8C E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4601 00002E91 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  4602                              <1> CMD_O1: ;PUSH	DS
  4603                              <1> 	;PUSH	ES			; MOVE ES TO DS
  4604                              <1> 	;POP	DS
  4605                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  4606                              <1> 	;MOV	DX,HF_PORT
  4607                              <1> 	; 01/02/2015
  4608 00002E93 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4609                              <1> 	;push	es
  4610                              <1> 	;pop	ds
  4611                              <1> 	;mov	cx, 256
  4612 00002E9A B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4613 00002E9F FA                  <1> 	CLI
  4614 00002EA0 FC                  <1> 	CLD
  4615 00002EA1 F3666F              <1> 	REP	OUTSW
  4616 00002EA4 FB                  <1> 	STI
  4617                              <1> 	;POP	DS			; RESTORE DS
  4618 00002EA5 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4619 00002EA9 7419                <1> 	JZ	short CMD_O3
  4620 00002EAB E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4621 00002EB0 72C9                <1> 	JC	short TM_OUT
  4622                              <1> 	;MOV	DX,HF_PORT
  4623 00002EB2 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4624                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4625 00002EB9 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4626                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  4627 00002EBE 8A06                <1> 	mov	al, [esi]
  4628 00002EC0 EE                  <1> 	OUT	DX,AL
  4629 00002EC1 46                  <1> 	INC	eSI
  4630 00002EC2 E2FA                <1> 	LOOP	CMD_O2
  4631                              <1> CMD_O3:
  4632 00002EC4 E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  4633 00002EC9 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  4634 00002ECB E830010000          <1> 	CALL	CHECK_STATUS
  4635 00002ED0 75A9                <1> 	JNZ	short CMD_ABORT
  4636 00002ED2 F605[6DCF0000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  4637 00002ED9 75B8                <1> 	JNZ	SHORT CMD_O1
  4638                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  4639 00002EDB 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4640                              <1> 	;add	dl, 2
  4641 00002EE2 FEC2                <1> 	inc	dl
  4642 00002EE4 FEC2                <1> 	inc	dl
  4643 00002EE6 EC                  <1> 	IN	AL,DX			;
  4644 00002EE7 A8FF                <1> 	TEST	AL,0FFH 		;
  4645 00002EE9 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  4646 00002EEB C605[77CF0000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  4647                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  4648                              <1> CMD_O4:
  4649 00002EF2 C3                  <1> 	RETn
  4650                              <1> 
  4651                              <1> ;--------------------------------------------------------
  4652                              <1> ; COMMAND						:
  4653                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  4654                              <1> ; OUTPUT						:
  4655                              <1> ;	BL = STATUS					:
  4656                              <1> ;	BH = ERROR REGISTER				:
  4657                              <1> ;--------------------------------------------------------
  4658                              <1> 
  4659                              <1> COMMAND:
  4660 00002EF3 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  4661                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  4662                              <1> COMMAND1:
  4663                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  4664 00002EF4 E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  4665                              <1> 	;;POP	CX
  4666 00002EF9 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  4667 00002EFB 803D[77CF0000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  4668                              <1> 	;JZ	short CMD_TIMEOUT
  4669                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  4670                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  4671 00002F02 7507                <1> 	jne	short COMMAND4
  4672                              <1> CMD_TIMEOUT:
  4673 00002F04 C605[77CF0000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4674                              <1> COMMAND4:
  4675 00002F0B 5B                  <1> 	POP	eBX
  4676 00002F0C 803D[77CF0000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  4677 00002F13 C3                  <1> 	RETn
  4678                              <1> COMMAND2:
  4679 00002F14 5B                  <1> 	POP	eBX
  4680 00002F15 57                  <1> 	PUSH	eDI
  4681 00002F16 C605[6FCF0000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  4682 00002F1D FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  4683 00002F1E E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4684                              <1> 	;AND	AL,0BFH
  4685 00002F20 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  4686                              <1> 	;JMP	$+2
  4687                              <1> 	IODELAY
  4687 00002F22 EB00                <2>  jmp short $+2
  4687 00002F24 EB00                <2>  jmp short $+2
  4688 00002F26 E6A1                <1> 	OUT	INTB01,AL
  4689 00002F28 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4690 00002F2A 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4691                              <1> 	;JMP	$+2
  4692                              <1> 	IODELAY
  4692 00002F2C EB00                <2>  jmp short $+2
  4692 00002F2E EB00                <2>  jmp short $+2
  4693 00002F30 E621                <1> 	OUT	INTA01,AL
  4694 00002F32 FB                  <1> 	STI
  4695 00002F33 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  4696                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  4697 00002F35 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4698 00002F3C FEC2                <1> 	inc	dl
  4699 00002F3E F605[79CF0000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  4700 00002F45 7411                <1> 	JZ	short COMMAND3
  4701 00002F47 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  4702 00002F4A 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  4703 00002F4C 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  4704 00002F4E 7208                <1> 	JB	short COMMAND3
  4705 00002F50 3C40                <1> 	CMP	AL,40H
  4706 00002F52 7704                <1> 	JA	short COMMAND3
  4707 00002F54 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  4708                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  4709                              <1> COMMAND3:
  4710 00002F58 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  4711 00002F5C EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  4712                              <1> 	IODELAY
  4712 00002F5D EB00                <2>  jmp short $+2
  4712 00002F5F EB00                <2>  jmp short $+2
  4713 00002F61 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  4714 00002F62 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  4715 00002F64 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  4716 00002F68 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  4717 00002F6A 5F                  <1> 	POP	eDI
  4718 00002F6B C3                  <1> 	RETn				; ZERO FLAG IS SET
  4719                              <1> 
  4720                              <1> ;CMD_TIMEOUT:
  4721                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4722                              <1> ;COMMAND4:
  4723                              <1> ;	POP	BX
  4724                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4725                              <1> ;	RETn
  4726                              <1> 
  4727                              <1> ;----------------------------------------
  4728                              <1> ;	WAIT FOR INTERRUPT		:
  4729                              <1> ;----------------------------------------
  4730                              <1> ;WAIT:
  4731                              <1> _WAIT:
  4732 00002F6C FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4733                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4734                              <1> 	;CLC
  4735                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  4736                              <1> 	;INT	15H
  4737                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  4738                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  4739                              <1> 
  4740                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  4741                              <1> 	;; 21/02/2015
  4742                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  4743                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  4744 00002F6D B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  4745                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  4746                              <1> ;-----	WAIT LOOP
  4747                              <1> 
  4748                              <1> WT1:	
  4749                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  4750 00002F72 F605[6FCF0000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  4751                              <1> 	;LOOPZ	WT1
  4752 00002F79 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  4753                              <1> 	;DEC	BL
  4754                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  4755                              <1> 
  4756                              <1> WT1_hi:
  4757 00002F7B E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  4758 00002F7D A810                <1> 	test	al, 10h			; transition on memory
  4759 00002F7F 75FA                <1> 	jnz	short WT1_hi		; refresh.
  4760                              <1> WT1_lo:
  4761 00002F81 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  4762 00002F83 A810                <1> 	test	al, 10h			
  4763 00002F85 74FA                <1> 	jz	short WT1_lo
  4764 00002F87 E2E9                <1> 	loop	WT1
  4765                              <1> 	;;or	bl, bl
  4766                              <1> 	;;jz	short WT2	
  4767                              <1> 	;;dec	bl
  4768                              <1> 	;;jmp	short WT1
  4769                              <1> 	;dec	bl
  4770                              <1> 	;jnz	short WT1	
  4771                              <1> 
  4772 00002F89 C605[77CF0000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  4773 00002F90 EB0E                <1> 	JMP	SHORT WT4
  4774 00002F92 C605[77CF0000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  4775 00002F99 C605[6FCF0000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  4776 00002FA0 803D[77CF0000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4777 00002FA7 C3                  <1> 	RETn
  4778                              <1> 
  4779                              <1> ;----------------------------------------
  4780                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  4781                              <1> ;----------------------------------------
  4782                              <1> NOT_BUSY:
  4783 00002FA8 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4784                              <1> 	;PUSH	eBX
  4785                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4786 00002FA9 668B15[64C90000]    <1> 	mov	DX, [HF_PORT]
  4787 00002FB0 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  4788                              <1> 	;MOV	BL,DELAY_1
  4789                              <1> 					; wait for 10 seconds
  4790                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  4791                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  4792                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  4793 00002FB3 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  4794                              <1> 	;
  4795                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  4796                              <1> NB1:	
  4797 00002FB8 EC                  <1> 	IN	AL,DX			; CHECK STATUS
  4798                              <1> 	;TEST	AL,ST_BUSY
  4799 00002FB9 2480                <1> 	and	al, ST_BUSY
  4800                              <1> 	;LOOPNZ	NB1
  4801 00002FBB 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  4802                              <1> 	;DEC	BL			
  4803                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  4804                              <1> 
  4805 00002FBD E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  4806 00002FBF A810                <1> 	TEST	AL,010H			; transition on memory
  4807 00002FC1 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  4808 00002FC3 E461                <1> NB1_lo: IN	AL,SYS1
  4809 00002FC5 A810                <1> 	TEST	AL,010H
  4810 00002FC7 74FA                <1> 	JZ	short NB1_lo
  4811 00002FC9 E2ED                <1> 	LOOP	NB1
  4812                              <1> 	;dec	bl
  4813                              <1> 	;jnz	short NB1
  4814                              <1> 	;
  4815                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  4816                              <1> ;;	jb	short NB1
  4817                              <1> 	;
  4818                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  4819                              <1> 	;JMP	SHORT NB3
  4820 00002FCB B080                <1> 	mov	al, TIME_OUT
  4821                              <1> NB2:	
  4822                              <1> 	;MOV	byte [DISK_STATUS1],0
  4823                              <1> ;NB3:	
  4824                              <1> 	;POP	eBX
  4825 00002FCD A2[77CF0000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  4826                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4827 00002FD2 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  4828 00002FD4 C3                  <1> 	RETn
  4829                              <1> 
  4830                              <1> ;----------------------------------------
  4831                              <1> ;	WAIT FOR DATA REQUEST		:
  4832                              <1> ;----------------------------------------
  4833                              <1> WAIT_DRQ:
  4834                              <1> 	;MOV	CX,DELAY_3
  4835                              <1> 	;MOV	DX,HF_PORT+7
  4836 00002FD5 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4837 00002FDC 80C207              <1> 	add	dl, 7
  4838                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  4839                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  4840                              <1> 					; (but it is written as 2000
  4841                              <1> 					; micro seconds in ATORGS.ASM file
  4842                              <1> 					; of Award Bios - 1999, D1A0622)
  4843 00002FDF B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  4844 00002FE4 EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  4845 00002FE5 A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  4846 00002FE7 7516                <1> 	JNZ	short WQ_OK
  4847                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  4848                              <1> WQ_hi:	
  4849 00002FE9 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  4850 00002FEB A810                <1> 	TEST	AL,010H			; transition on memory
  4851 00002FED 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  4852 00002FEF E461                <1> WQ_lo:  IN      AL,SYS1
  4853 00002FF1 A810                <1> 	TEST	AL,010H
  4854 00002FF3 74FA                <1> 	JZ	SHORT WQ_lo
  4855 00002FF5 E2ED                <1> 	LOOP	WQ_1
  4856                              <1> 
  4857 00002FF7 C605[77CF0000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  4858 00002FFE F9                  <1> 	STC
  4859                              <1> WQ_OK:
  4860 00002FFF C3                  <1> 	RETn
  4861                              <1> ;WQ_OK:	;CLC
  4862                              <1> ;	RETn
  4863                              <1> 
  4864                              <1> ;----------------------------------------
  4865                              <1> ;	CHECK FIXED DISK STATUS 	:
  4866                              <1> ;----------------------------------------
  4867                              <1> CHECK_STATUS:
  4868 00003000 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  4869 00003005 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  4870 00003007 A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  4871 00003009 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  4872 0000300B E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  4873                              <1> CHECK_S1:
  4874 00003010 803D[77CF0000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  4875 00003017 C3                  <1> 	RETn
  4876                              <1> 
  4877                              <1> ;----------------------------------------
  4878                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  4879                              <1> ;----------------------------------------
  4880                              <1> CHECK_ST:
  4881                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  4882 00003018 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]
  4883 0000301F 80C207              <1> 	add	dl, 7
  4884                              <1> 	
  4885                              <1> 	; 17/02/2016
  4886                              <1> 	;(http://wiki.osdev.org/ATA_PIO_Mode)
  4887                              <1> 	;"delay 400ns to allow drive to set new values of BSY and DRQ"
  4888 00003022 EC                  <1> 	IN	AL,DX
  4889                              <1> 	;in	al, dx ; 100ns
  4890                              <1> 	;in	al, dx ; 100ns
  4891                              <1>  	;in	al, dx ; 100ns
  4892                              <1> 	NEWIODELAY ; 18/02/2016 (AWARD BIOS - 1999, 'CKST' in AHSDK.ASM)
  4892 00003023 E6EB                <2>  out 0ebh,al
  4893                              <1> 	;
  4894 00003025 A2[6DCF0000]        <1> 	MOV	[HF_STATUS],AL
  4895 0000302A B400                <1> 	MOV	AH,0
  4896 0000302C A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  4897 0000302E 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  4898 00003030 B4CC                <1> 	MOV	AH,WRITE_FAULT
  4899 00003032 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  4900 00003034 7514                <1> 	JNZ	short CKST_EXIT
  4901 00003036 B4AA                <1> 	MOV	AH,NOT_RDY
  4902 00003038 A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  4903 0000303A 740E                <1> 	JZ	short CKST_EXIT
  4904 0000303C B440                <1> 	MOV	AH,BAD_SEEK
  4905 0000303E A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  4906 00003040 7408                <1> 	JZ	short CKST_EXIT
  4907 00003042 B411                <1> 	MOV	AH,DATA_CORRECTED
  4908 00003044 A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  4909 00003046 7502                <1> 	JNZ	short CKST_EXIT
  4910 00003048 B400                <1> 	MOV	AH,0
  4911                              <1> CKST_EXIT:
  4912 0000304A 8825[77CF0000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  4913 00003050 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  4914 00003053 7403                <1> 	JZ	short CKST_EX1
  4915 00003055 80FC00              <1> 	CMP	AH,0
  4916                              <1> CKST_EX1:
  4917 00003058 C3                  <1> 	RETn
  4918                              <1> 
  4919                              <1> ;----------------------------------------
  4920                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  4921                              <1> ;----------------------------------------
  4922                              <1> CHECK_ER:
  4923                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  4924 00003059 668B15[64C90000]    <1> 	mov	dx, [HF_PORT]		;
  4925 00003060 FEC2                <1> 	inc	dl
  4926 00003062 EC                  <1> 	IN	AL,DX
  4927 00003063 A2[6ECF0000]        <1> 	MOV	[HF_ERROR],AL
  4928 00003068 53                  <1> 	PUSH	eBX ; 21/02/2015
  4929 00003069 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  4930 0000306E D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  4931 00003070 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  4932 00003072 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  4933 00003074 BB[58C90000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  4934 00003079 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  4935                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  4936                              <1> 	;mov	ah, [bx]
  4937 0000307B 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  4938 0000307D 8825[77CF0000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  4939 00003083 5B                  <1> 	POP	eBX
  4940 00003084 80FC00              <1> 	CMP	AH,0
  4941 00003087 C3                  <1> 	RETn
  4942                              <1> 
  4943                              <1> ;--------------------------------------------------------
  4944                              <1> ; CHECK_DMA						:
  4945                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  4946                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  4947                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  4948                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  4949                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  4950                              <1> ;  -ERROR OTHERWISE					:
  4951                              <1> ;--------------------------------------------------------
  4952                              <1> CHECK_DMA:
  4953 00003088 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  4954 0000308A 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  4955 0000308E F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  4956 00003092 7404                <1> 	JZ	short CKD1
  4957 00003094 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  4958 00003098 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  4959 0000309B 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  4960 0000309D 7208                <1> 	JB	short CKDERR		; TOO MANY
  4961 0000309F 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  4962 000030A1 7204                <1> 	JB	short CKDERR		; ERROR
  4963 000030A3 F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  4964 000030A4 6658                <1> 	POP	AX
  4965 000030A6 C3                  <1> 	RETn				; NORMAL RETURN
  4966 000030A7 F9                  <1> CKDERR: STC				; INDICATE ERROR
  4967 000030A8 C605[77CF0000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  4968 000030AF 6658                <1> 	POP	AX
  4969 000030B1 C3                  <1> 	RETn
  4970                              <1> 
  4971                              <1> ;----------------------------------------
  4972                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  4973                              <1> ;----------------------------------------
  4974                              <1> 					
  4975                              <1> ; INPUT -> DL = 0 based drive number
  4976                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  4977                              <1> 
  4978                              <1> GET_VEC:
  4979                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  4980                              <1> 	;MOV	ES,AX
  4981                              <1> 	;TEST	DL,1
  4982                              <1> 	;JZ	short GV_0
  4983                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  4984                              <1> ;	JMP	SHORT GV_EXIT
  4985                              <1> ;GV_0:
  4986                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  4987                              <1> ;
  4988                              <1> 	;xor	bh, bh
  4989 000030B2 31DB                <1> 	xor	ebx, ebx
  4990 000030B4 88D3                <1> 	mov	bl, dl
  4991                              <1> 	;;02/01/2015
  4992                              <1> 	;;shl	bl, 1			; port address offset
  4993                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  4994                              <1> 	;;shl	bl, 1			; dpt pointer offset
  4995 000030B6 C0E302              <1> 	shl	bl, 2	;;
  4996                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  4997 000030B9 81C3[7CCF0000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  4998                              <1> 	;push	word [bx+2]		; dpt segment
  4999                              <1> 	;pop	es
  5000                              <1> 	;mov	bx, [bx]		; dpt offset
  5001 000030BF 8B1B                <1> 	mov	ebx, [ebx]		
  5002                              <1> ;GV_EXIT:
  5003 000030C1 C3                  <1> 	RETn
  5004                              <1> 
  5005                              <1> hdc1_int: ; 21/02/2015
  5006                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  5007                              <1> ;								:
  5008                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5009                              <1> ;								:
  5010                              <1> ;----------------------------------------------------------------
  5011                              <1> 
  5012                              <1> ; 22/12/2014
  5013                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  5014                              <1> ;	 '11/15/85'
  5015                              <1> ; AWARD BIOS 1999 (D1A0622) 
  5016                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  5017                              <1> 
  5018                              <1> ;int_76h:
  5019                              <1> HD_INT:
  5020 000030C2 6650                <1> 	PUSH	AX
  5021 000030C4 1E                  <1> 	PUSH	DS
  5022                              <1> 	;CALL	DDS
  5023                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5024 000030C5 66B81000            <1> 	mov	ax, KDATA
  5025 000030C9 8ED8                <1> 	mov 	ds, ax
  5026                              <1> 	;
  5027                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5028                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  5029 000030CB C605[6FCF0000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5030                              <1> 	;
  5031 000030D2 6652                <1> 	push	dx
  5032 000030D4 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5033                              <1> 					; Clear Controller
  5034                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5035 000030D8 EC                  <1> 	in	al, dx			;
  5036 000030D9 665A                <1> 	pop	dx
  5037                              <1> 	NEWIODELAY
  5037 000030DB E6EB                <2>  out 0ebh,al
  5038                              <1> 	;
  5039 000030DD B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5040 000030DF E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5041                              <1> 	;JMP	$+2			; WAIT
  5042                              <1> 	NEWIODELAY
  5042 000030E1 E6EB                <2>  out 0ebh,al
  5043 000030E3 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5044 000030E5 1F                  <1> 	POP	DS
  5045                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  5046                              <1> 	;MOV	AX,9100H		; DEVICE POST
  5047                              <1> 	;INT	15H			;  INTERRUPT
  5048                              <1> irq15_iret: ; 25/02/2015
  5049 000030E6 6658                <1> 	POP	AX
  5050 000030E8 CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  5051                              <1> 
  5052                              <1> hdc2_int: ; 21/02/2015
  5053                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  5054                              <1> ;								:
  5055                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5056                              <1> ;								:
  5057                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5058                              <1> 
  5059                              <1> ;int_77h:
  5060                              <1> HD1_INT:
  5061 000030E9 6650                <1> 	PUSH	AX
  5062                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  5063                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  5064 000030EB B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5065 000030ED E6A0                <1> 	out	0A0h, al
  5066 000030EF EB00                <1>         jmp short $+2
  5067 000030F1 EB00                <1> 	jmp short $+2
  5068 000030F3 E4A0                <1> 	in	al, 0A0h
  5069 000030F5 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5070 000030F7 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5071                              <1> 	;
  5072 000030F9 1E                  <1> 	PUSH	DS
  5073                              <1> 	;CALL	DDS
  5074                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5075 000030FA 66B81000            <1> 	mov	ax, KDATA
  5076 000030FE 8ED8                <1> 	mov 	ds, ax
  5077                              <1> 	;
  5078                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5079                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  5080 00003100 800D[6FCF0000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5081                              <1> 	;
  5082 00003107 6652                <1> 	push	dx
  5083 00003109 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5084                              <1> 					; Clear Controller (Award BIOS 1999)
  5085 0000310D EBC9                <1> 	jmp	short Clear_IRQ1415
  5086                              <1> 
  5087                              <1> 
  5088                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  5089                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  5090                              <1> 
  5091                              <1> 
  5092                              <1> ;////////////////////////////////////////////////////////////////////
  5093                              <1> ;; END OF DISK I/O SYTEM ///
  1920                                  %include 'memory.s'  ; 09/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - memory.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 03/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; memory.inc (18/10/2015)
    15                              <1> ; ****************************************************************************
    16                              <1> 
    17                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
    18                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
    19                              <1> ; Last Modification: 18/10/2015
    20                              <1> 
    21                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
    22                              <1> 
    23                              <1> ;;04/11/2014 (unix386.s)	
    24                              <1> ;PDE_A_PRESENT	equ	1		; Present flag for PDE
    25                              <1> ;PDE_A_WRITE	equ 	2		; Writable (write permission) flag
    26                              <1> ;PDE_A_USER	equ	4		; User (non-system/kernel) page flag
    27                              <1> ;;
    28                              <1> ;PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
    29                              <1> ;PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
    30                              <1> ;PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
    31                              <1> ;PTE_A_ACCESS   equ	32		; Accessed flag (bit 5) ; 09/03/2015
    32                              <1> 
    33                              <1> ; 27/04/2015
    34                              <1> ; 09/03/2015
    35                              <1> PAGE_SIZE 	equ 4096		; page size in bytes
    36                              <1> PAGE_SHIFT 	equ 12			; page table shift count
    37                              <1> PAGE_D_SHIFT 	equ 22	; 12 + 10	; page directory shift count
    38                              <1> PAGE_OFF	equ 0FFFh		; 12 bit byte offset in page frame
    39                              <1> PTE_MASK 	equ 03FFh		; page table entry mask
    40                              <1> PTE_DUPLICATED  equ 200h		; duplicated page sign (AVL bit 0)
    41                              <1> PDE_A_CLEAR	equ 0F000h		; to clear PDE attribute bits
    42                              <1> PTE_A_CLEAR	equ 0F000h		; to clear PTE attribute bits
    43                              <1> LOGIC_SECT_SIZE equ 512			; logical sector size
    44                              <1> ERR_MAJOR_PF	equ 0E0h		; major error: page fault
    45                              <1> ERR_MINOR_IM	equ 1			; insufficient (out of) memory
    46                              <1> ERR_MINOR_DSK	equ 2			; disk read/write error
    47                              <1> ERR_MINOR_PV	equ 3			; protection violation
    48                              <1> SWP_DISK_READ_ERR equ 4
    49                              <1> SWP_DISK_NOT_PRESENT_ERR equ 5
    50                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 6
    51                              <1> SWP_NO_FREE_SPACE_ERR equ 7
    52                              <1> SWP_DISK_WRITE_ERR equ 8
    53                              <1> SWP_NO_PAGE_TO_SWAP_ERR equ 9
    54                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
    55                              <1> SECTOR_SHIFT    equ 3   ; sector shift (to convert page block number)
    56                              <1> 
    57                              <1> ;
    58                              <1> ;; Retro Unix 386 v1 - paging method/principles
    59                              <1> ;;
    60                              <1> ;; 10/10/2014
    61                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
    62                              <1> ;;
    63                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
    64                              <1> ;;	(virtual address = physical address)
    65                              <1> ;; KERNEL PAGE TABLES:
    66                              <1> ;;	Kernel page directory and all page tables are
    67                              <1> ;;	on memory as initialized, as equal to physical memory
    68                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
    69                              <1> ;;
    70                              <1> ;;	what for: User pages may be swapped out, when accessing
    71                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
    72                              <1> ;;	kernel would have to swap it in! But it is also may be
    73                              <1> ;;	in use by a user process. (In system/kernel mode
    74                              <1> ;;	kernel can access all memory pages even if they are
    75                              <1> ;;	reserved/allocated for user processes. Swap out/in would
    76                              <1> ;;	cause conflicts.) 
    77                              <1> ;;	
    78                              <1> ;;	As result of these conditions,
    79                              <1> ;;	all kernel pages must be initialized as equal to 
    80                              <1> ;;	physical layout for preventing page faults. 
    81                              <1> ;;	Also, calling "allocate page" procedure after
    82                              <1> ;;	a page fault can cause another page fault (double fault)
    83                              <1> ;;	if all kernel page tables would not be initialized.
    84                              <1> ;;
    85                              <1> ;;	[first_page] = Beginning of users space, as offset to 
    86                              <1> ;;	memory allocation table. (double word aligned)
    87                              <1> ;;
    88                              <1> ;;	[next_page] = first/next free space to be searched
    89                              <1> ;;	as offset to memory allocation table. (dw aligned)
    90                              <1> ;;
    91                              <1> ;;	[last_page] = End of memory (users space), as offset
    92                              <1> ;;	to memory allocation table. (double word aligned)
    93                              <1> ;;
    94                              <1> ;; USER PAGE TABLES:
    95                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
    96                              <1> ;;		'ready only' marked copies of the 
    97                              <1> ;;		parent process's page table entries (for
    98                              <1> ;;		same physical memory).
    99                              <1> ;;		(A page will be copied to a new page after
   100                              <1> ;;		 if it causes R/W page fault.)
   101                              <1> ;;
   102                              <1> ;;	Every user process has own (different)
   103                              <1> ;;	page directory and page tables.	
   104                              <1> ;;
   105                              <1> ;;	Code starts at virtual address 0, always.
   106                              <1> ;;	(Initial value of EIP is 0 in user mode.)
   107                              <1> ;;	(Programs can be written/developed as simple
   108                              <1> ;;	 flat memory programs.)
   109                              <1> ;;
   110                              <1> ;; MEMORY ALLOCATION STRATEGY:
   111                              <1> ;;	Memory page will be allocated by kernel only 
   112                              <1> ;;		(in kernel/system mode only).
   113                              <1> ;;	* After a
   114                              <1> ;;	  - 'not present' page fault
   115                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
   116                              <1> ;;	* For loading (opening, reading) a file or disk/drive
   117                              <1> ;;	* As responce to 'allocate additional memory blocks' 
   118                              <1> ;;	  request by running process.
   119                              <1> ;;	* While creating a process, allocating a new buffer,
   120                              <1> ;;	  new page tables etc.
   121                              <1> ;;
   122                              <1> ;;	At first,
   123                              <1> ;;	- 'allocate page' procedure will be called;
   124                              <1> ;,	   if it will return with a valid (>0) physical address
   125                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
   126                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
   127                              <1> ;;	- 'allocate page' will be called for allocating page
   128                              <1> ;;	   directory, page table and running space (data/code).
   129                              <1> ;;	- every successful 'allocate page' call will decrease
   130                              <1> ;;	  'free_pages' count (pointer).
   131                              <1> ;;	- 'out of (insufficient) memory error' will be returned
   132                              <1> ;;	  if 'free_pages' points to a ZERO.
   133                              <1> ;;	- swapping out and swapping in (if it is not a new page)
   134                              <1> ;;	  procedures will be called as responce to 'out of memory'
   135                              <1> ;;	  error except errors caused by attribute conflicts.
   136                              <1> ;;	 (swapper functions)	 
   137                              <1> ;;					
   138                              <1> ;;	At second,
   139                              <1> ;;	- page directory entry will be updated then page table
   140                              <1> ;;	  entry will be updated.		
   141                              <1> ;;
   142                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
   143                              <1> ;;	- M.A.T. has a size according to available memory as
   144                              <1> ;;	  follows:
   145                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
   146                              <1> ;;		  - a bit with value of 0 means allocated page
   147                              <1> ;;		  - a bit with value of 1 means a free page
   148                              <1> ;,	- 'free_pages' pointer holds count of free pages
   149                              <1> ;;	  depending on M.A.T.
   150                              <1> ;;		(NOTE: Free page count will not be checked
   151                              <1> ;;		again -on M.A.T.- after initialization. 
   152                              <1> ;;		Kernel will trust on initial count.)
   153                              <1> ;,	- 'free_pages' count will be decreased by allocation
   154                              <1> ;;	  and it will be increased by deallocation procedures.
   155                              <1> ;;	
   156                              <1> ;;	- Available memory will be calculated during
   157                              <1> ;;	  the kernel's initialization stage (in real mode).
   158                              <1> ;;	  Memory allocation table and kernel page tables 
   159                              <1> ;;	  will be formatted/sized as result of available
   160                              <1> ;;	  memory calculation before paging is enabled.
   161                              <1> ;;
   162                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
   163                              <1> ;;	- Memory Allocation Table size will be 128 KB.
   164                              <1> ;;	- Memory allocation for kernel page directory size 
   165                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   166                              <1> ;;	  for page tables)
   167                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
   168                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
   169                              <1> ;;	- User (available) space will be started 
   170                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
   171                              <1> ;;	- The first 640 KB is for kernel's itself plus
   172                              <1> ;;	  memory allocation table and kernel's page directory
   173                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   174                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   175                              <1> ;; 	  for buffers.
   176                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   177                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   178                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
   179                              <1> ;;
   180                              <1> ;; For 1GB Available Memory:
   181                              <1> ;;	- Memory Allocation Table size will be 32 KB.
   182                              <1> ;;	- Memory allocation for kernel page directory size 
   183                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   184                              <1> ;;	  for page tables)
   185                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
   186                              <1> ;;	  is 1 MB (256*4*1024 bytes).
   187                              <1> ;;	- User (available) space will be started 
   188                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
   189                              <1> ;;	- The first 640 KB is for kernel's itself plus
   190                              <1> ;;	  memory allocation table and kernel's page directory
   191                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   192                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   193                              <1> ;; 	  for buffers.
   194                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   195                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   196                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
   197                              <1> ;;
   198                              <1> ;;
   199                              <1> 
   200                              <1> 
   201                              <1> ;;************************************************************************************
   202                              <1> ;; 
   203                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
   204                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
   205                              <1> 
   206                              <1> ;; Main factor: "sys fork" system call 
   207                              <1> ;;	
   208                              <1> ;; 		FORK
   209                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
   210                              <1> ;;  writable pages ---->|
   211                              <1> ;;                      |----> child - duplicated PTEs, read only pages
   212                              <1> ;; 
   213                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
   214                              <1> ;; 
   215                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
   216                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
   217                              <1> ;;       -while R/W bit is 0-. 
   218                              <1> ;; 
   219                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
   220                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
   221                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
   222                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
   223                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
   224                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
   225                              <1> ;; 
   226                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
   227                              <1> ;; # Parent's read only pages are copied to new child pages. 
   228                              <1> ;;   Parent's PTE attributes are not changed.
   229                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
   230                              <1> ;;    destroy/mix previous fork result).
   231                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
   232                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
   233                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
   234                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
   235                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
   236                              <1> ;;   as Child's Page Table Entries without copying actual page.
   237                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
   238                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
   239                              <1> ;; 
   240                              <1> ;; !? WHAT FOR (duplication after duplication):
   241                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
   242                              <1> ;; program/executable code continues from specified location as child process, 
   243                              <1> ;; returns back previous code location as parent process, every child after 
   244                              <1> ;; every sys fork uses last image of code and data just prior the fork.
   245                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
   246                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
   247                              <1> ;; was copied to child's process segment (all of code and data) according to
   248                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
   249                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
   250                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
   251                              <1> ;; (complete running image of parent process) to the child process; 
   252                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
   253                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
   254                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
   255                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
   256                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
   257                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
   258                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
   259                              <1> ;; new/fresh pages will be used to load and run new executable/program.
   260                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
   261                              <1> ;; for sharing same read only pages between parent and child processes.
   262                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
   263                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
   264                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
   265                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
   266                              <1> ;; -deallocation problem-.
   267                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
   268                              <1> ;; 
   269                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   270                              <1> ;; # Page fault handler will do those:
   271                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   272                              <1> ;;   - If it is reset/clear, there is a child uses same page.
   273                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
   274                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
   275                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
   276                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
   277                              <1> ;;     read only page will be converted to writable and unique page which belongs
   278                              <1> ;;     to child process.)	
   279                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   280                              <1> ;; # Page fault handler will do those:
   281                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   282                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
   283                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
   284                              <1> ;;     address or not. 
   285                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
   286                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
   287                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
   288                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
   289                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
   290                              <1> ;; 
   291                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
   292                              <1> ;;       will be set as writable (and unique) in case of child process was using 
   293                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
   294                              <1> ;;       duplication method details, it is not possible multiple child processes
   295                              <1> ;;       were using same page with duplicated PTEs.
   296                              <1> ;; 
   297                              <1> ;;************************************************************************************   
   298                              <1> 
   299                              <1> ;; 08/10/2014
   300                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
   301                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
   302                              <1> 
   303                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
   304                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
   305                              <1> ;; (25/08/2014, Revision: 5057) file 
   306                              <1> ;; by KolibriOS Team (2004-2012)
   307                              <1> 
   308                              <1> allocate_page:
   309                              <1> 	; 01/07/2015
   310                              <1> 	; 05/05/2015
   311                              <1> 	; 30/04/2015
   312                              <1> 	; 16/10/2014
   313                              <1> 	; 08/10/2014
   314                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
   315                              <1> 	;
   316                              <1> 	; INPUT -> none
   317                              <1> 	;
   318                              <1> 	; OUTPUT ->
   319                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   320                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
   321                              <1> 	;
   322                              <1> 	;	CF = 1 and EAX = 0 
   323                              <1> 	; 		   if there is not a free page to be allocated	
   324                              <1> 	;
   325                              <1> 	; Modified Registers -> none (except EAX)
   326                              <1> 	;
   327 0000310F A1[E0CE0000]        <1> 	mov	eax, [free_pages]
   328 00003114 21C0                <1> 	and	eax, eax
   329 00003116 7438                <1> 	jz	short out_of_memory
   330                              <1> 	;
   331 00003118 53                  <1> 	push	ebx
   332 00003119 51                  <1> 	push	ecx
   333                              <1> 	;
   334 0000311A BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   335 0000311F 89D9                <1> 	mov	ecx, ebx
   336                              <1>  				     ; NOTE: 32 (first_page) is initial
   337                              <1> 				     ; value of [next_page].
   338                              <1> 				     ; It points to the first available
   339                              <1> 				     ; page block for users (ring 3) ...	
   340                              <1> 				     ; (MAT offset 32 = 1024/32)	
   341                              <1> 				     ; (at the of the first 4 MB)		
   342 00003121 031D[E4CE0000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   343                              <1> 				 ; next_free_page >> 5
   344 00003127 030D[E8CE0000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   345                              <1> 				 ; (total_pages - 1) >> 5
   346                              <1> al_p_scan:
   347 0000312D 39CB                <1> 	cmp	ebx, ecx
   348 0000312F 770A                <1> 	ja	short al_p_notfound
   349                              <1> 	;
   350                              <1> 	; 01/07/2015
   351                              <1> 	; AMD64 Architecture Programmers Manual
   352                              <1> 	; Volume 3:
   353                              <1> 	; General-Purpose and System Instructions
   354                              <1> 	;
   355                              <1> 	; BSF - Bit Scan Forward
   356                              <1> 	;
   357                              <1> 	;   Searches the value in a register or a memory location
   358                              <1> 	;   (second operand) for the least-significant set bit. 
   359                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
   360                              <1> 	;   and stores the index of the least-significant set bit in a destination
   361                              <1> 	;   register (first operand). If the second operand contains 0, 
   362                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
   363                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
   364                              <1> 	;   of the searched value
   365                              <1> 	;
   366 00003131 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
   367                              <1> 			   ; Clear ZF if a bit is found set (1) and 
   368                              <1> 			   ; loads the destination with an index to
   369                              <1> 			   ; first set bit. (0 -> 31) 
   370                              <1> 			   ; Sets ZF to 1 if no bits are found set.
   371 00003134 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
   372                              <1> 			 ;
   373                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
   374                              <1> 			 ;	  with value of 1 means 
   375                              <1> 			 ;	  the corresponding page is free 
   376                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
   377 00003136 83C304              <1> 	add	ebx, 4
   378                              <1> 			 ; We return back for searching next page block
   379                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
   380                              <1> 			 ;	 we always will find at least 1 free page here.
   381 00003139 EBF2                <1>         jmp     short al_p_scan
   382                              <1> 	;
   383                              <1> al_p_notfound:
   384 0000313B 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   385 00003141 890D[E4CE0000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   386                              <1> 				 ; (deallocate_page procedure will change it)
   387 00003147 31C0                <1> 	xor	eax, eax
   388 00003149 A3[E0CE0000]        <1> 	mov	[free_pages], eax ; 0
   389 0000314E 59                  <1> 	pop	ecx
   390 0000314F 5B                  <1> 	pop	ebx
   391                              <1> 	;
   392                              <1> out_of_memory:
   393 00003150 E857040000          <1> 	call	swap_out
   394 00003155 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   395                              <1> 	;
   396 00003157 29C0                <1> 	sub 	eax, eax ; 0
   397 00003159 F9                  <1> 	stc
   398 0000315A C3                  <1> 	retn
   399                              <1> 
   400                              <1> al_p_found:
   401 0000315B 89D9                <1> 	mov	ecx, ebx
   402 0000315D 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   403 00003163 890D[E4CE0000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   404                              <1> 				 ; address/offset (to the next)
   405 00003169 FF0D[E0CE0000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   406                              <1> 	;
   407 0000316F 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
   408                              <1> 				 ; is copied into the Carry Flag and then cleared
   409                              <1> 				 ; in the destination.
   410                              <1> 				 ;
   411                              <1> 				 ; Reset the bit which is corresponding to the 
   412                              <1> 				 ; (just) allocated page.
   413                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
   414 00003172 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   415 00003175 01C8                <1> 	add	eax, ecx	 ; = page number
   416 00003177 C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
   417                              <1> 	; EAX = physical address of memory page
   418                              <1> 	;
   419                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
   420                              <1> 	;       according to this EAX value...
   421 0000317A 59                  <1> 	pop	ecx
   422 0000317B 5B                  <1> 	pop	ebx
   423                              <1> al_p_ok:
   424 0000317C C3                  <1> 	retn
   425                              <1> 
   426                              <1> 
   427                              <1> make_page_dir:
   428                              <1> 	; 18/04/2015
   429                              <1> 	; 12/04/2015
   430                              <1> 	; 23/10/2014
   431                              <1> 	; 16/10/2014
   432                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   433                              <1> 	;
   434                              <1> 	; INPUT ->
   435                              <1> 	;	none
   436                              <1> 	; OUTPUT ->
   437                              <1> 	;	(EAX = 0)
   438                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   439                              <1> 	;	cf = 0 ->
   440                              <1> 	;	u.pgdir = page directory (physical) address of the current
   441                              <1> 	;		  process/user.
   442                              <1> 	;
   443                              <1> 	; Modified Registers -> EAX
   444                              <1> 	;
   445 0000317D E88DFFFFFF          <1> 	call	allocate_page
   446 00003182 7216                <1> 	jc	short mkpd_error
   447                              <1> 	;
   448 00003184 A3[D9DF0000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
   449                              <1> 				  ; (Physical address)
   450                              <1> clear_page:
   451                              <1> 	; 18/04/2015
   452                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   453                              <1> 	;
   454                              <1> 	; INPUT ->
   455                              <1> 	;	EAX = physical address of the page
   456                              <1> 	; OUTPUT ->
   457                              <1> 	;	all bytes of the page will be cleared
   458                              <1> 	;
   459                              <1> 	; Modified Registers -> none
   460                              <1> 	;
   461 00003189 57                  <1> 	push	edi
   462 0000318A 51                  <1> 	push	ecx
   463 0000318B 50                  <1> 	push	eax
   464 0000318C B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   465 00003191 89C7                <1> 	mov	edi, eax
   466 00003193 31C0                <1> 	xor	eax, eax
   467 00003195 F3AB                <1> 	rep	stosd
   468 00003197 58                  <1> 	pop	eax
   469 00003198 59                  <1> 	pop	ecx
   470 00003199 5F                  <1> 	pop	edi
   471                              <1> mkpd_error:
   472                              <1> mkpt_error:
   473 0000319A C3                  <1> 	retn
   474                              <1> 
   475                              <1> make_page_table:
   476                              <1> 	; 23/06/2015
   477                              <1> 	; 18/04/2015
   478                              <1> 	; 12/04/2015
   479                              <1> 	; 16/10/2014
   480                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   481                              <1> 	;
   482                              <1> 	; INPUT ->
   483                              <1> 	;	EBX = virtual (linear) address
   484                              <1> 	;	ECX = page table attributes (lower 12 bits)
   485                              <1> 	;	      (higher 20 bits must be ZERO)
   486                              <1> 	;	      (bit 0 must be 1)	 
   487                              <1> 	;	u.pgdir = page directory (physical) address
   488                              <1> 	; OUTPUT ->
   489                              <1> 	;	EDX = Page directory entry address
   490                              <1> 	;	EAX = Page table address
   491                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   492                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
   493                              <1> 	;
   494                              <1> 	; Modified Registers -> EAX, EDX
   495                              <1> 	;
   496 0000319B E86FFFFFFF          <1> 	call	allocate_page
   497 000031A0 72F8                <1> 	jc	short mkpt_error
   498 000031A2 E811000000          <1> 	call	set_pde	
   499 000031A7 EBE0                <1> 	jmp	short clear_page
   500                              <1> 
   501                              <1> make_page:
   502                              <1> 	; 24/07/2015
   503                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
   504                              <1> 	;
   505                              <1> 	; INPUT ->
   506                              <1> 	;	EBX = virtual (linear) address
   507                              <1> 	;	ECX = page attributes (lower 12 bits)
   508                              <1> 	;	      (higher 20 bits must be ZERO)
   509                              <1> 	;	      (bit 0 must be 1)	 
   510                              <1> 	;	u.pgdir = page directory (physical) address
   511                              <1> 	; OUTPUT ->
   512                              <1> 	;	EBX = Virtual address
   513                              <1> 	;	(EDX = PTE value)
   514                              <1> 	;	EAX = Physical address
   515                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   516                              <1> 	;
   517                              <1> 	; Modified Registers -> EAX, EDX
   518                              <1> 	;
   519 000031A9 E861FFFFFF          <1> 	call	allocate_page
   520 000031AE 7207                <1> 	jc	short mkp_err
   521 000031B0 E821000000          <1> 	call	set_pte	
   522 000031B5 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   523                              <1> mkp_err:
   524 000031B7 C3                  <1> 	retn
   525                              <1> 
   526                              <1> 
   527                              <1> set_pde:	; Set page directory entry (PDE)
   528                              <1> 	; 20/07/2015
   529                              <1> 	; 18/04/2015
   530                              <1> 	; 12/04/2015
   531                              <1> 	; 23/10/2014
   532                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   533                              <1> 	;
   534                              <1> 	; INPUT ->
   535                              <1> 	;	EAX = physical address
   536                              <1> 	;	      (use present value if EAX = 0)
   537                              <1> 	;	EBX = virtual (linear) address
   538                              <1> 	;	ECX = page table attributes (lower 12 bits)
   539                              <1> 	;	      (higher 20 bits must be ZERO)
   540                              <1> 	;	      (bit 0 must be 1)	 
   541                              <1> 	;	u.pgdir = page directory (physical) address
   542                              <1> 	; OUTPUT ->
   543                              <1> 	;	EDX = PDE address
   544                              <1> 	;	EAX = page table address (physical)
   545                              <1> 	;	;(CF=1 -> Invalid page address)
   546                              <1> 	;
   547                              <1> 	; Modified Registers -> EDX
   548                              <1> 	;
   549 000031B8 89DA                <1> 	mov	edx, ebx
   550 000031BA C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   551 000031BD C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   552 000031C0 0315[D9DF0000]      <1> 	add	edx, [u.pgdir]
   553                              <1> 	;
   554 000031C6 21C0                <1> 	and	eax, eax
   555 000031C8 7506                <1> 	jnz	short spde_1
   556                              <1> 	;
   557 000031CA 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   558                              <1> 	;test	al, 1
   559                              <1> 	;jz	short spde_2
   560 000031CC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   561                              <1> spde_1:
   562                              <1> 	;and	cx, 0FFFh
   563 000031D0 8902                <1> 	mov	[edx], eax
   564 000031D2 66090A              <1> 	or	[edx], cx
   565 000031D5 C3                  <1> 	retn
   566                              <1> ;spde_2: ; error
   567                              <1> ;	stc
   568                              <1> ;	retn
   569                              <1> 
   570                              <1> set_pte:	; Set page table entry (PTE)
   571                              <1> 	; 24/07/2015
   572                              <1> 	; 20/07/2015
   573                              <1> 	; 23/06/2015
   574                              <1> 	; 18/04/2015
   575                              <1> 	; 12/04/2015
   576                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   577                              <1> 	;
   578                              <1> 	; INPUT ->
   579                              <1> 	;	EAX = physical page address
   580                              <1> 	;	      (use present value if EAX = 0)
   581                              <1> 	;	EBX = virtual (linear) address
   582                              <1> 	;	ECX = page attributes (lower 12 bits)
   583                              <1> 	;	      (higher 20 bits must be ZERO)
   584                              <1> 	;	      (bit 0 must be 1)	 
   585                              <1> 	;	u.pgdir = page directory (physical) address
   586                              <1> 	; OUTPUT ->
   587                              <1> 	;	EAX = physical page address
   588                              <1> 	;	(EDX = PTE value)
   589                              <1> 	;	EBX = virtual address
   590                              <1> 	;
   591                              <1> 	;	CF = 1 -> error
   592                              <1> 	;
   593                              <1> 	; Modified Registers -> EAX, EDX
   594                              <1> 	;
   595 000031D6 50                  <1> 	push	eax
   596 000031D7 A1[D9DF0000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   597 000031DC E837000000          <1> 	call 	get_pde
   598                              <1> 		; EDX = PDE address
   599                              <1> 		; EAX = PDE value
   600 000031E1 5A                  <1> 	pop	edx ; physical page address
   601 000031E2 722A                <1> 	jc	short spte_err ; PDE not present
   602                              <1> 	;
   603 000031E4 53                  <1> 	push	ebx ; 24/07/2015
   604 000031E5 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   605                              <1> 			    ; EDX = PT address (physical)	
   606 000031E9 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   607 000031EC 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   608                              <1> 			 ; clear higher 10 bits (PD bits)
   609 000031F2 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   610 000031F5 01C3                <1> 	add	ebx, eax
   611                              <1> 	;
   612 000031F7 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   613 000031F9 A801                <1> 	test	al, 1
   614 000031FB 740C                <1> 	jz	short spte_0
   615 000031FD 09D2                <1> 	or	edx, edx
   616 000031FF 750F                <1> 	jnz	short spte_1
   617 00003201 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   618 00003205 89C2                <1> 	mov	edx, eax
   619 00003207 EB09                <1> 	jmp	short spte_2	
   620                              <1> spte_0:
   621                              <1> 	; If this PTE contains a swap (disk) address,
   622                              <1> 	; it can be updated by using 'swap_in' procedure
   623                              <1> 	; only!
   624 00003209 21C0                <1> 	and	eax, eax
   625 0000320B 7403                <1> 	jz	short spte_1
   626                              <1> 	; 24/07/2015
   627                              <1> 	; swapped page ! (on disk)
   628 0000320D 5B                  <1> 	pop	ebx
   629                              <1> spte_err:
   630 0000320E F9                  <1> 	stc
   631 0000320F C3                  <1> 	retn
   632                              <1> spte_1: 
   633 00003210 89D0                <1> 	mov	eax, edx
   634                              <1> spte_2:
   635 00003212 09CA                <1> 	or	edx, ecx
   636                              <1> 	; 23/06/2015
   637 00003214 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   638                              <1> 	; 24/07/2015
   639 00003216 5B                  <1> 	pop	ebx
   640 00003217 C3                  <1> 	retn
   641                              <1> 
   642                              <1> get_pde:	; Get present value of the relevant PDE
   643                              <1> 	; 20/07/2015
   644                              <1> 	; 18/04/2015
   645                              <1> 	; 12/04/2015
   646                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   647                              <1> 	;
   648                              <1> 	; INPUT ->
   649                              <1> 	;	EBX = virtual (linear) address
   650                              <1> 	;	EAX = page directory (physical) address
   651                              <1> 	; OUTPUT ->
   652                              <1> 	;	EDX = Page directory entry address
   653                              <1> 	;	EAX = Page directory entry value
   654                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   655                              <1> 	; Modified Registers -> EDX, EAX
   656                              <1> 	;
   657 00003218 89DA                <1> 	mov	edx, ebx
   658 0000321A C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   659 0000321D C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   660 00003220 01C2                <1> 	add	edx, eax ; page directory address (physical)
   661 00003222 8B02                <1> 	mov	eax, [edx]
   662 00003224 A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   663 00003226 751F                <1> 	jnz	short gpte_retn
   664 00003228 F9                  <1> 	stc
   665                              <1> gpde_retn:	
   666 00003229 C3                  <1> 	retn
   667                              <1> 
   668                              <1> get_pte:
   669                              <1> 		; Get present value of the relevant PTE
   670                              <1> 	; 29/07/2015
   671                              <1> 	; 20/07/2015
   672                              <1> 	; 18/04/2015
   673                              <1> 	; 12/04/2015
   674                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   675                              <1> 	;
   676                              <1> 	; INPUT ->
   677                              <1> 	;	EBX = virtual (linear) address
   678                              <1> 	;	EAX = page directory (physical) address
   679                              <1> 	; OUTPUT ->
   680                              <1> 	;	EDX = Page table entry address (if CF=0)
   681                              <1> 	;	      Page directory entry address (if CF=1)
   682                              <1> 	;            (Bit 0 value is 0 if PT is not present)
   683                              <1> 	;	EAX = Page table entry value (page address)
   684                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   685                              <1> 	; Modified Registers -> EAX, EDX
   686                              <1> 	;
   687 0000322A E8E9FFFFFF          <1> 	call 	get_pde
   688 0000322F 72F8                <1> 	jc	short gpde_retn	; page table is not present
   689                              <1> 	;jnc	short gpte_1
   690                              <1> 	;retn
   691                              <1> ;gpte_1:
   692 00003231 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   693 00003235 89DA                <1> 	mov	edx, ebx
   694 00003237 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   695 0000323A 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   696                              <1> 			 ; clear higher 10 bits (PD bits)
   697 00003240 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   698 00003243 01C2                <1> 	add	edx, eax
   699 00003245 8B02                <1> 	mov	eax, [edx]
   700                              <1> gpte_retn:
   701 00003247 C3                  <1> 	retn
   702                              <1> 
   703                              <1> deallocate_page_dir:
   704                              <1> 	; 15/09/2015
   705                              <1> 	; 05/08/2015
   706                              <1> 	; 30/04/2015
   707                              <1> 	; 28/04/2015
   708                              <1> 	; 17/10/2014
   709                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   710                              <1> 	;
   711                              <1> 	; INPUT ->
   712                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
   713                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   714                              <1> 	; OUTPUT ->
   715                              <1> 	;	All of page tables in the page directory
   716                              <1> 	;	and page dir's itself will be deallocated
   717                              <1> 	;	except 'read only' duplicated pages (will be converted
   718                              <1> 	;	to writable pages).
   719                              <1> 	;
   720                              <1> 	; Modified Registers -> EAX
   721                              <1> 	;
   722                              <1> 	;
   723 00003248 56                  <1> 	push	esi
   724 00003249 51                  <1> 	push	ecx
   725 0000324A 50                  <1> 	push	eax
   726 0000324B 89C6                <1> 	mov	esi, eax 
   727 0000324D 31C9                <1> 	xor	ecx, ecx
   728                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
   729                              <1> 	; it must not be deallocated
   730 0000324F 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   731                              <1> dapd_0:
   732 00003251 AD                  <1> 	lodsd
   733 00003252 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   734 00003254 7409                <1> 	jz	short dapd_1	
   735 00003256 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   736 0000325A E812000000          <1> 	call	deallocate_page_table			
   737                              <1> dapd_1:
   738 0000325F 41                  <1> 	inc	ecx ; page directory entry index
   739 00003260 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   740 00003266 72E9                <1> 	jb	short dapd_0
   741                              <1> dapd_2:
   742 00003268 58                  <1> 	pop	eax
   743 00003269 E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   744 0000326E 59                  <1> 	pop	ecx
   745 0000326F 5E                  <1> 	pop	esi
   746 00003270 C3                  <1> 	retn
   747                              <1> 
   748                              <1> deallocate_page_table:
   749                              <1> 	; 19/09/2015
   750                              <1> 	; 15/09/2015
   751                              <1> 	; 05/08/2015
   752                              <1> 	; 30/04/2015
   753                              <1> 	; 28/04/2015
   754                              <1> 	; 24/10/2014
   755                              <1> 	; 23/10/2014
   756                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   757                              <1> 	;
   758                              <1> 	; INPUT ->
   759                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
   760                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   761                              <1> 	;	(ECX = page directory entry index)
   762                              <1> 	; OUTPUT ->
   763                              <1> 	;	All of pages in the page table and page table's itself
   764                              <1> 	;	will be deallocated except 'read only' duplicated pages
   765                              <1> 	;	(will be converted to writable pages).
   766                              <1> 	;
   767                              <1> 	; Modified Registers -> EAX
   768                              <1> 	;
   769 00003271 56                  <1> 	push	esi
   770 00003272 57                  <1> 	push	edi
   771 00003273 52                  <1> 	push	edx
   772 00003274 50                  <1> 	push	eax ; *
   773 00003275 89C6                <1> 	mov	esi, eax 
   774 00003277 31FF                <1> 	xor	edi, edi ; 0
   775                              <1> dapt_0:
   776 00003279 AD                  <1> 	lodsd
   777 0000327A A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   778 0000327C 7441                <1> 	jz	short dapt_1
   779                              <1> 	;
   780 0000327E A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   781                              <1> 				  ; (must be 1)
   782 00003280 754C                <1> 	jnz	short dapt_3
   783                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   784 00003282 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   785                              <1> 				   ; as child's page ?
   786 00003286 744B                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
   787                              <1> 	; check the parent's PTE value is read only & same page or not.. 
   788                              <1> 	; ECX = page directory entry index (0-1023)
   789 00003288 53                  <1> 	push	ebx
   790 00003289 51                  <1> 	push	ecx
   791 0000328A 66C1E102            <1> 	shl	cx, 2 ; *4 
   792 0000328E 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   793 00003290 8B0B                <1> 	mov	ecx, [ebx]
   794 00003292 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   795 00003295 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   796 00003297 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   797                              <1> 	; EDI = page table entry index (0-1023)
   798 0000329C 89FA                <1> 	mov	edx, edi 
   799 0000329E 66C1E202            <1> 	shl	dx, 2 ; *4 
   800 000032A2 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   801 000032A4 8B1A                <1> 	mov	ebx, [edx]
   802 000032A6 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   803 000032A9 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   804 000032AB 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   805 000032AF 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   806 000032B4 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   807 000032B6 7514                <1> 	jne	short dapt_2	; not same page
   808                              <1> 				; deallocate the child's page
   809 000032B8 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   810 000032BB 59                  <1> 	pop	ecx
   811 000032BC 5B                  <1> 	pop	ebx
   812 000032BD EB14                <1> 	jmp	short dapt_4
   813                              <1> dapt_1:
   814 000032BF 09C0                <1> 	or	eax, eax	; swapped page ?
   815 000032C1 7417                <1> 	jz	short dapt_5	; no
   816                              <1> 				; yes
   817 000032C3 D1E8                <1> 	shr	eax, 1
   818 000032C5 E848040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   819                              <1> 				  ; on the swap disk (or in file)
   820 000032CA EB0E                <1> 	jmp	short dapt_5
   821                              <1> dapt_2:
   822 000032CC 59                  <1> 	pop	ecx
   823 000032CD 5B                  <1> 	pop	ebx
   824                              <1> dapt_3:	
   825                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   826 000032CE E814000000          <1> 	call	deallocate_page
   827                              <1> dapt_4:
   828 000032D3 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   829                              <1> dapt_5:
   830 000032DA 47                  <1> 	inc	edi ; page table entry index
   831 000032DB 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   832 000032E1 7296                <1> 	jb	short dapt_0
   833                              <1> 	;
   834 000032E3 58                  <1> 	pop	eax ; *
   835 000032E4 5A                  <1> 	pop	edx
   836 000032E5 5F                  <1> 	pop	edi	
   837 000032E6 5E                  <1> 	pop	esi
   838                              <1> 	;
   839                              <1> 	;call	deallocate_page	; deallocate the page table's itself
   840                              <1> 	;retn
   841                              <1> 
   842                              <1> deallocate_page:
   843                              <1> 	; 15/09/2015
   844                              <1> 	; 28/04/2015
   845                              <1> 	; 10/03/2015
   846                              <1> 	; 17/10/2014
   847                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   848                              <1> 	;
   849                              <1> 	; INPUT -> 
   850                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   851                              <1> 	; OUTPUT ->
   852                              <1> 	;	[free_pages] is increased
   853                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
   854                              <1> 	;	CF = 1 if the page is already deallocated
   855                              <1> 	; 	       (or not allocated) before.  
   856                              <1> 	;
   857                              <1> 	; Modified Registers -> EAX
   858                              <1> 	;
   859 000032E7 53                  <1> 	push	ebx
   860 000032E8 52                  <1> 	push	edx
   861                              <1> 	;
   862 000032E9 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   863                              <1> 				     ; 12 bits right
   864                              <1> 				     ; to get page number
   865 000032EC 89C2                <1> 	mov	edx, eax
   866                              <1> 	; 15/09/2015
   867 000032EE C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
   868                              <1> 				     ; (1 allocation bit = 1 page)
   869                              <1> 				     ; (1 allocation bytes = 8 pages)
   870 000032F1 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   871                              <1> 				     ; (to get 32 bit position)			
   872                              <1> 	;
   873 000032F4 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   874 000032F9 01D3                <1> 	add	ebx, edx
   875 000032FB 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   876                              <1> 				     ; (allocation bit position)	 
   877 000032FE 3B15[E4CE0000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
   878                              <1> 				     ; than the address in 'next_page' ?
   879                              <1> 				     ; (next/first free page value)		
   880 00003304 7306                <1> 	jnb	short dap_1	     ; no	
   881 00003306 8915[E4CE0000]      <1> 	mov	[next_page], edx     ; yes
   882                              <1> dap_1:
   883 0000330C 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
   884                              <1> 				     ; set relevant bit to 1.
   885                              <1> 				     ; set CF to the previous bit value	
   886                              <1> 	;cmc			     ; complement carry flag	
   887                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
   888                              <1> 				     ; if the page is already deallocated
   889                              <1> 				     ; before.	
   890 0000330F FF05[E0CE0000]      <1>         inc     dword [free_pages]
   891                              <1> dap_2:
   892 00003315 5A                  <1> 	pop	edx
   893 00003316 5B                  <1> 	pop	ebx
   894 00003317 C3                  <1> 	retn
   895                              <1> 
   896                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   897                              <1> ;;                                                              ;;
   898                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
   899                              <1> ;; Distributed under terms of the GNU General Public License    ;;
   900                              <1> ;;                                                              ;;
   901                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   902                              <1> 
   903                              <1> ;;$Revision: 5057 $
   904                              <1> 
   905                              <1> 
   906                              <1> ;;align 4
   907                              <1> ;;proc alloc_page
   908                              <1> 
   909                              <1> ;;        pushfd
   910                              <1> ;;        cli
   911                              <1> ;;        push    ebx
   912                              <1> ;;;//-
   913                              <1> ;;        cmp     [pg_data.pages_free], 1
   914                              <1> ;;        jle     .out_of_memory
   915                              <1> ;;;//-
   916                              <1> ;;
   917                              <1> ;;        mov     ebx, [page_start]
   918                              <1> ;;        mov     ecx, [page_end]
   919                              <1> ;;.l1:
   920                              <1> ;;        bsf     eax, [ebx];
   921                              <1> ;;        jnz     .found
   922                              <1> ;;        add     ebx, 4
   923                              <1> ;;        cmp     ebx, ecx
   924                              <1> ;;        jb      .l1
   925                              <1> ;;        pop     ebx
   926                              <1> ;;        popfd
   927                              <1> ;;        xor     eax, eax
   928                              <1> ;;        ret
   929                              <1> ;;.found:
   930                              <1> ;;;//-
   931                              <1> ;;        dec     [pg_data.pages_free]
   932                              <1> ;;        jz      .out_of_memory
   933                              <1> ;;;//-
   934                              <1> ;;        btr     [ebx], eax
   935                              <1> ;;        mov     [page_start], ebx
   936                              <1> ;;        sub     ebx, sys_pgmap
   937                              <1> ;;        lea     eax, [eax+ebx*8]
   938                              <1> ;;        shl     eax, 12
   939                              <1> ;;;//-       dec [pg_data.pages_free]
   940                              <1> ;;        pop     ebx
   941                              <1> ;;        popfd
   942                              <1> ;;        ret
   943                              <1> ;;;//-
   944                              <1> ;;.out_of_memory:
   945                              <1> ;;        mov     [pg_data.pages_free], 1
   946                              <1> ;;        xor     eax, eax
   947                              <1> ;;        pop     ebx
   948                              <1> ;;        popfd
   949                              <1> ;;        ret
   950                              <1> ;;;//-
   951                              <1> ;;endp
   952                              <1> 
   953                              <1> duplicate_page_dir:
   954                              <1> 	; 21/09/2015
   955                              <1> 	; 31/08/2015
   956                              <1> 	; 20/07/2015
   957                              <1> 	; 28/04/2015
   958                              <1> 	; 27/04/2015
   959                              <1> 	; 18/04/2015
   960                              <1> 	; 12/04/2015
   961                              <1> 	; 18/10/2014
   962                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
   963                              <1> 	;
   964                              <1> 	; INPUT -> 
   965                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
   966                              <1> 	;		    page directory.
   967                              <1> 	; OUTPUT ->
   968                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
   969                              <1> 	;	       page directory.
   970                              <1> 	;	(New page directory with new page table entries.)
   971                              <1> 	;	(New page tables with read only copies of the parent's
   972                              <1> 	;	pages.)
   973                              <1> 	;	EAX = 0 -> Error (CF = 1)
   974                              <1> 	;
   975                              <1> 	; Modified Registers -> none (except EAX)
   976                              <1> 	;
   977 00003318 E8F2FDFFFF          <1> 	call	allocate_page
   978 0000331D 723E                <1> 	jc	short dpd_err
   979                              <1> 	;
   980 0000331F 55                  <1> 	push	ebp ; 20/07/2015
   981 00003320 56                  <1> 	push	esi
   982 00003321 57                  <1> 	push	edi
   983 00003322 53                  <1> 	push	ebx
   984 00003323 51                  <1> 	push	ecx
   985 00003324 8B35[D9DF0000]      <1> 	mov	esi, [u.pgdir]
   986 0000332A 89C7                <1> 	mov	edi, eax
   987 0000332C 50                  <1> 	push	eax ; save child's page directory address
   988                              <1> 	; 31/08/2015
   989                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
   990                              <1> 	; (use same system space for all user page tables) 
   991 0000332D A5                  <1> 	movsd
   992 0000332E BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
   993 00003333 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
   994                              <1> dpd_0:	
   995 00003338 AD                  <1> 	lodsd
   996                              <1> 	;or	eax, eax
   997                              <1>         ;jnz     short dpd_1
   998 00003339 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
   999 0000333B 7508                <1> 	jnz	short dpd_1
  1000                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1001 0000333D 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1002 00003343 EB0F                <1> 	jmp	short dpd_2
  1003                              <1> dpd_1:	
  1004 00003345 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1005 00003349 89C3                <1> 	mov	ebx, eax
  1006                              <1> 	; EBX = Parent's page table address
  1007 0000334B E81F000000          <1> 	call	duplicate_page_table
  1008 00003350 720C                <1> 	jc	short dpd_p_err
  1009                              <1> 	; EAX = Child's page table address
  1010 00003352 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  1011                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  1012                              <1> 			 ; (present, writable, user)
  1013                              <1> dpd_2:
  1014 00003354 AB                  <1> 	stosd
  1015 00003355 E2E1                <1> 	loop	dpd_0
  1016                              <1> 	;
  1017 00003357 58                  <1> 	pop	eax  ; restore child's page directory address
  1018                              <1> dpd_3:
  1019 00003358 59                  <1> 	pop	ecx
  1020 00003359 5B                  <1> 	pop	ebx
  1021 0000335A 5F                  <1> 	pop	edi
  1022 0000335B 5E                  <1> 	pop	esi
  1023 0000335C 5D                  <1> 	pop	ebp ; 20/07/2015
  1024                              <1> dpd_err:
  1025 0000335D C3                  <1> 	retn
  1026                              <1> dpd_p_err:
  1027                              <1> 	; release the allocated pages missing (recover free space)
  1028 0000335E 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1029 0000335F 8B1D[D9DF0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1030 00003365 E8DEFEFFFF          <1> 	call 	deallocate_page_dir
  1031 0000336A 29C0                <1> 	sub	eax, eax ; 0
  1032 0000336C F9                  <1> 	stc
  1033 0000336D EBE9                <1> 	jmp	short dpd_3	
  1034                              <1> 
  1035                              <1> duplicate_page_table:
  1036                              <1> 	; 21/09/2015
  1037                              <1> 	; 20/07/2015
  1038                              <1> 	; 05/05/2015
  1039                              <1> 	; 28/04/2015
  1040                              <1> 	; 27/04/2015
  1041                              <1> 	; 18/04/2015
  1042                              <1> 	; 18/10/2014
  1043                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
  1044                              <1> 	;
  1045                              <1> 	; INPUT -> 
  1046                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  1047                              <1> 	;	EBP = page table entry index (from 'duplicate_page_dir')
  1048                              <1> 	; OUTPUT ->
  1049                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  1050                              <1> 	;	      (with 'read only' attribute of page table entries)
  1051                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  1052                              <1> 	;	CF = 1 -> error 
  1053                              <1> 	;
  1054                              <1> 	; Modified Registers -> EBP (except EAX)
  1055                              <1> 	;
  1056 0000336F E89BFDFFFF          <1> 	call	allocate_page
  1057 00003374 726A                <1> 	jc	short dpt_err
  1058                              <1> 	;
  1059 00003376 50                  <1> 	push	eax ; *
  1060 00003377 56                  <1> 	push	esi
  1061 00003378 57                  <1> 	push	edi
  1062 00003379 52                  <1> 	push	edx
  1063 0000337A 51                  <1> 	push	ecx
  1064                              <1> 	;
  1065 0000337B 89DE                <1> 	mov	esi, ebx
  1066 0000337D 89C7                <1> 	mov	edi, eax
  1067 0000337F 89C2                <1> 	mov	edx, eax
  1068 00003381 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1069                              <1> dpt_0:
  1070 00003387 AD                  <1> 	lodsd
  1071 00003388 21C0                <1> 	and	eax, eax
  1072 0000338A 7444                <1> 	jz	short dpt_3
  1073 0000338C A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1074 0000338E 7507                <1> 	jnz	short dpt_1
  1075                              <1> 	; 20/07/2015
  1076                              <1> 	; ebp = virtual (linear) address of the memory page
  1077 00003390 E887040000          <1> 	call	reload_page ; 28/04/2015
  1078 00003395 7244                <1> 	jc	short dpt_p_err
  1079                              <1> dpt_1:
  1080                              <1> 	; 21/09/2015
  1081 00003397 89C1                <1> 	mov	ecx, eax
  1082 00003399 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1083 0000339D F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1084 000033A0 7525                <1> 	jnz	short dpt_2
  1085                              <1> 	; Read only (parent) page
  1086                              <1> 	; 	- there is a third process which uses this page -
  1087                              <1> 	; Allocate a new page for the child process
  1088 000033A2 E868FDFFFF          <1> 	call	allocate_page
  1089 000033A7 7232                <1> 	jc	short dpt_p_err
  1090 000033A9 57                  <1> 	push	edi
  1091 000033AA 56                  <1> 	push	esi
  1092 000033AB 89CE                <1> 	mov	esi, ecx
  1093 000033AD 89C7                <1> 	mov	edi, eax
  1094 000033AF B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1095 000033B4 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1096 000033B6 5E                  <1> 	pop	esi
  1097 000033B7 5F                  <1> 	pop	edi
  1098                              <1> 	; 
  1099 000033B8 53                  <1> 	push	ebx
  1100 000033B9 50                  <1> 	push	eax
  1101                              <1> 	; 20/07/2015
  1102 000033BA 89EB                <1> 	mov	ebx, ebp
  1103                              <1> 	; ebx = virtual address of the memory page
  1104 000033BC E80B030000          <1> 	call	add_to_swap_queue
  1105 000033C1 58                  <1> 	pop	eax
  1106 000033C2 5B                  <1> 	pop	ebx
  1107                              <1> 	; 21/09/2015
  1108 000033C3 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1109                              <1> 		; user + writable + present page
  1110 000033C5 EB09                <1> 	jmp	short dpt_3
  1111                              <1> dpt_2:
  1112                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1113 000033C7 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1114                              <1> 		    ; (read only page!)
  1115 000033C9 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1116 000033CC 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1117                              <1> dpt_3:
  1118 000033D0 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1119                              <1> 	;
  1120 000033D1 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1121                              <1> 	;
  1122 000033D7 39D7                <1> 	cmp	edi, edx
  1123 000033D9 72AC                <1> 	jb	short dpt_0
  1124                              <1> dpt_p_err:
  1125 000033DB 59                  <1> 	pop	ecx
  1126 000033DC 5A                  <1> 	pop	edx
  1127 000033DD 5F                  <1> 	pop	edi
  1128 000033DE 5E                  <1> 	pop	esi
  1129 000033DF 58                  <1> 	pop	eax ; *
  1130                              <1> dpt_err:
  1131 000033E0 C3                  <1> 	retn
  1132                              <1> 
  1133                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
  1134                              <1> 	; 21/09/2015
  1135                              <1> 	; 19/09/2015
  1136                              <1> 	; 17/09/2015
  1137                              <1> 	; 28/08/2015
  1138                              <1> 	; 20/07/2015
  1139                              <1> 	; 28/06/2015
  1140                              <1> 	; 03/05/2015
  1141                              <1> 	; 30/04/2015
  1142                              <1> 	; 18/04/2015
  1143                              <1> 	; 12/04/2015
  1144                              <1> 	; 30/10/2014
  1145                              <1> 	; 11/09/2014
  1146                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
  1147                              <1> 	;
  1148                              <1> 	; Note: This is not an interrupt/exception handler.
  1149                              <1> 	;	This is a 'page fault remedy' subroutine 
  1150                              <1> 	;	which will be called by standard/uniform
  1151                              <1> 	;	exception handler.
  1152                              <1> 	;
  1153                              <1> 	; INPUT -> 
  1154                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
  1155                              <1> 	;
  1156                              <1> 	;	cr2 = the virtual (linear) address 
  1157                              <1> 	;	      which has caused to page fault (19/09/2015)
  1158                              <1> 	;
  1159                              <1> 	; OUTPUT ->
  1160                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1161                              <1> 	;	EAX = 0 -> no error
  1162                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
  1163                              <1> 	;
  1164                              <1> 	; Modified Registers -> none (except EAX)
  1165                              <1> 	;	
  1166                              <1>         ;
  1167                              <1>         ; ERROR CODE:
  1168                              <1> 	;	 31  .....	4   3	2   1	0
  1169                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1170                              <1> 	;	|   Reserved  | I | R | U | W | P |
  1171                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1172                              <1> 	;
  1173                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
  1174                              <1>     	;		a page-protection violation. When not set,
  1175                              <1> 	;		it was caused by a non-present page.
  1176                              <1> 	; W : WRITE   -	When set, the page fault was caused by
  1177                              <1> 	;		a page write. When not set, it was caused
  1178                              <1> 	;		by a page read.
  1179                              <1> 	; U : USER    -	When set, the page fault was caused 
  1180                              <1> 	;		while CPL = 3. 
  1181                              <1> 	;		This does not necessarily mean that
  1182                              <1> 	;		the page fault was a privilege violation.
  1183                              <1> 	; R : RESERVD -	When set, the page fault was caused by
  1184                              <1> 	;     WRITE	reading a 1 in a reserved field.
  1185                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
  1186                              <1> 	;     FETCH	an instruction fetch
  1187                              <1> 	;
  1188                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
  1189                              <1> 	;  31               22                  12 11                    0
  1190                              <1> 	; +-------------------+-------------------+-----------------------+
  1191                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
  1192                              <1>        	; +-------------------+-------------------+-----------------------+
  1193                              <1> 	;
  1194                              <1> 
  1195                              <1> 	;; CR3 REGISTER (Control Register 3)
  1196                              <1> 	;  31                                   12             5 4 3 2   0
  1197                              <1> 	; +---------------------------------------+-------------+---+-----+
  1198                              <1>       	; |                                       |  		|P|P|     |
  1199                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
  1200                              <1>       	; |                                       | 		|D|T|     |
  1201                              <1>    	; +---------------------------------------+-------------+---+-----+
  1202                              <1> 	;
  1203                              <1> 	;	PWT    - WRITE THROUGH
  1204                              <1> 	;	PCD    - CACHE DISABLE		
  1205                              <1> 	;
  1206                              <1> 	;
  1207                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
  1208                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1209                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1210                              <1>       	; |                                       |     | | | | |P|P|U|R| |
  1211                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
  1212                              <1>       	; |                                       |     | | | | |D|T|S|W| |
  1213                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1214                              <1> 	;
  1215                              <1>         ;       P      - PRESENT
  1216                              <1>         ;       R/W    - READ/WRITE
  1217                              <1>         ;       U/S    - USER/SUPERVISOR
  1218                              <1> 	;	PWT    - WRITE THROUGH
  1219                              <1> 	;	PCD    - CACHE DISABLE	
  1220                              <1> 	;	A      - ACCESSED	
  1221                              <1>         ;       D      - DIRTY (IGNORED)
  1222                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1223                              <1> 	;	G      - GLOBAL	(IGNORED) 
  1224                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1225                              <1> 	;
  1226                              <1> 	;
  1227                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
  1228                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1229                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1230                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
  1231                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
  1232                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
  1233                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1234                              <1> 	;
  1235                              <1>         ;       P      - PRESENT
  1236                              <1>         ;       R/W    - READ/WRITE
  1237                              <1>         ;       U/S    - USER/SUPERVISOR
  1238                              <1> 	;	PWT    - WRITE THROUGH
  1239                              <1> 	;	PCD    - CACHE DISABLE	
  1240                              <1> 	;	A      - ACCESSED	
  1241                              <1>         ;       D      - DIRTY
  1242                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1243                              <1> 	;	G      - GLOBAL	 
  1244                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1245                              <1> 	;
  1246                              <1> 	;
  1247                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
  1248                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1249                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1250                              <1>       	; |                                       |     | | | | | | |U|R| |
  1251                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
  1252                              <1>       	; |                                       |     | | | | | | |S|W| |
  1253                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1254                              <1> 	;
  1255                              <1>         ;       P      - PRESENT
  1256                              <1>         ;       R/W    - READ/WRITE
  1257                              <1>         ;       U/S    - USER/SUPERVISOR
  1258                              <1>         ;       D      - DIRTY
  1259                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1260                              <1> 	;
  1261                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
  1262                              <1> 	;
  1263                              <1> 	;
  1264                              <1> 	;; Invalid Page Table Entry
  1265                              <1> 	; 31                                                           1 0
  1266                              <1>       	; +-------------------------------------------------------------+-+
  1267                              <1>       	; |                                                             | |
  1268                              <1>       	; |                          AVAILABLE                          |0|
  1269                              <1>       	; |                                                             | |
  1270                              <1>       	; +-------------------------------------------------------------+-+
  1271                              <1> 	;
  1272                              <1> 
  1273 000033E1 53                  <1> 	push	ebx
  1274 000033E2 52                  <1> 	push	edx
  1275 000033E3 51                  <1> 	push	ecx
  1276                              <1> 	;
  1277                              <1> 	; 21/09/2015 (debugging)
  1278 000033E4 FF05[E9DF0000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1279 000033EA FF05[5CEC0000]      <1> 	inc	dword [PF_Count] ; total page fault count	
  1280                              <1> 	; 28/06/2015
  1281                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
  1282 000033F0 8A15[54EC0000]      <1> 	mov	dl, [error_code]
  1283                              <1> 	;
  1284 000033F6 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1285                              <1> 			; sign
  1286 000033F9 7422                <1> 	jz	short pfh_alloc_np
  1287                              <1> 	; 
  1288                              <1> 	; If it is not a 'write on read only page' type page fault
  1289                              <1> 	; major page fault error with minor reason must be returned without 
  1290                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
  1291                              <1> 	; after return here!
  1292                              <1> 	; Page fault will be remedied, by copying page contents
  1293                              <1> 	; to newly allocated page with write permission;
  1294                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
  1295                              <1> 	; used for working with minimum possible memory usage. 
  1296                              <1> 	; sys_fork will duplicate page directory and tables of parent  
  1297                              <1> 	; process with 'read only' flag. If the child process attempts to
  1298                              <1> 	; write on these read only pages, page fault will be directed here
  1299                              <1> 	; for allocating a new page with same data/content. 
  1300                              <1> 	;
  1301                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
  1302                              <1> 	; will not force to separate CODE and DATA space 
  1303                              <1> 	; in a process/program... 
  1304                              <1> 	; CODE segment/section may contain DATA!
  1305                              <1> 	; It is flat, smoth and simplest programming method already as in 
  1306                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
  1307                              <1> 	;	
  1308 000033FB F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1309                              <1> 			; sign
  1310 000033FE 0F84AB000000        <1>         jz      pfh_p_err
  1311                              <1> 	; 31/08/2015
  1312 00003404 F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
  1313                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
  1314 00003407 0F84A2000000        <1>         jz	pfh_pv_err
  1315                              <1> 	;
  1316                              <1> 	; make a new page and copy the parent's page content
  1317                              <1> 	; as the child's new page content
  1318                              <1> 	;
  1319 0000340D 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1320                              <1> 			 ; which has caused to page fault
  1321 00003410 E8A2000000          <1> 	call 	copy_page
  1322 00003415 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1323                              <1> 	;
  1324 0000341B EB7D                <1>         jmp     pfh_cpp_ok
  1325                              <1> 	;
  1326                              <1> pfh_alloc_np:
  1327 0000341D E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1328 00003422 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
  1329                              <1> pfh_chk_cpl:
  1330                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1331                              <1> 		; (Lower 12 bits are ZERO, because 
  1332                              <1> 		;	the address is on a page boundary)
  1333 00003428 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1334 0000342B 7505                <1> 	jnz	short pfh_um
  1335                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1336 0000342D 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
  1337                              <1> 			 ; of the current/active page directory
  1338                              <1> 			 ; (Always kernel/system mode page directory, here!)
  1339                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
  1340 00003430 EB06                <1> 	jmp	short pfh_get_pde
  1341                              <1> 	;
  1342                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1343 00003432 8B1D[D9DF0000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
  1344                              <1> 			; Physical address of the USER's page directory
  1345                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
  1346                              <1> pfh_get_pde:
  1347 00003438 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1348 0000343B 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1349                              <1> 			 ; which has been caused to page fault
  1350                              <1> 			 ;
  1351 0000343E C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1352 00003441 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1353                              <1> 	;
  1354 00003444 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1355 00003446 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1356 00003448 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1357 0000344B 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1358                              <1> 			  	  ; set/validate page directory entry
  1359 0000344D 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1360 00003452 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1361 00003454 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1362 00003456 EB16                <1> 	jmp	short pfh_get_pte
  1363                              <1> pfh_set_pde:
  1364                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
  1365                              <1> 	;;	 (So, we know this PDE is empty or invalid)
  1366                              <1> 	;
  1367 00003458 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1368 0000345A 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1369 0000345C 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1370 0000345E 89C3                <1> 	mov	ebx, eax
  1371 00003460 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1372 00003465 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
  1373                              <1> pfh_spde_1:
  1374                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1375 00003467 89C1                <1> 	mov	ecx, eax
  1376 00003469 E81BFDFFFF          <1> 	call	clear_page ; Clear page content
  1377                              <1> pfh_get_pte:
  1378 0000346E 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1379                              <1> 			 ; which has been caused to page fault
  1380 00003471 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1381 00003473 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1382                              <1> 			 ; higher 20 bits of the page fault address 
  1383 00003476 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1384 0000347B C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1385 0000347E 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1386 00003480 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
  1387                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
  1388 00003482 21C0                <1> 	and	eax, eax
  1389 00003484 7410                <1> 	jz	short pfh_gpte_1
  1390                              <1> 	; 20/07/2015
  1391 00003486 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1392 00003488 55                  <1> 	push	ebp ; 20/07/2015
  1393 00003489 0F20D5              <1> 	mov	ebp, cr2
  1394                              <1> 		; ECX = physical address of the page table entry
  1395                              <1> 		; EBX = Memory page address (physical!)
  1396                              <1> 		; EAX = Swap disk (offset) address
  1397                              <1> 		; EBP = virtual address (page fault address)
  1398 0000348C E8B7000000          <1> 	call	swap_in
  1399 00003491 5D                  <1> 	pop	ebp
  1400 00003492 7210                <1> 	jc      short pfh_err_retn
  1401 00003494 87CB                <1> 	xchg	ecx, ebx
  1402                              <1> 		; EBX = physical address of the page table entry
  1403                              <1> 		; ECX = new page
  1404                              <1> pfh_gpte_1:
  1405 00003496 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1406 00003498 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
  1407                              <1> pfh_cpp_ok:
  1408                              <1> 	; 20/07/2015
  1409 0000349A 0F20D3              <1> 	mov	ebx, cr2
  1410 0000349D E82A020000          <1> 	call 	add_to_swap_queue
  1411                              <1> 	;
  1412                              <1> 	; The new PTE (which contains the new page) will be added to 
  1413                              <1> 	; the swap queue, here. 
  1414                              <1> 	; (Later, if memory will become insufficient, 
  1415                              <1> 	; one page will be swapped out which is at the head of 
  1416                              <1> 	; the swap queue by using FIFO and access check methods.)
  1417                              <1> 	;
  1418 000034A2 31C0                <1> 	xor	eax, eax  ; 0
  1419                              <1> 	;
  1420                              <1> pfh_err_retn:
  1421 000034A4 59                  <1> 	pop	ecx
  1422 000034A5 5A                  <1> 	pop	edx
  1423 000034A6 5B                  <1> 	pop	ebx
  1424 000034A7 C3                  <1> 	retn 
  1425                              <1> 	
  1426                              <1> pfh_im_err:
  1427 000034A8 B8E1000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
  1428                              <1> 			; Major (Primary) Error: Page Fault
  1429                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
  1430 000034AD EBF5                <1> 	jmp	short pfh_err_retn
  1431                              <1> 
  1432                              <1> 
  1433                              <1> pfh_p_err: ; 09/03/2015
  1434                              <1> pfh_pv_err:
  1435                              <1> 	; Page fault was caused by a protection-violation
  1436 000034AF B8E3000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
  1437                              <1> 			; Major (Primary) Error: Page Fault
  1438                              <1> 			; Minor (Secondary) Error: Protection violation !
  1439 000034B4 F9                  <1> 	stc
  1440 000034B5 EBED                <1> 	jmp	short pfh_err_retn
  1441                              <1> 
  1442                              <1> copy_page:
  1443                              <1> 	; 22/09/2015
  1444                              <1> 	; 21/09/2015
  1445                              <1> 	; 19/09/2015
  1446                              <1> 	; 07/09/2015
  1447                              <1> 	; 31/08/2015
  1448                              <1> 	; 20/07/2015
  1449                              <1> 	; 05/05/2015
  1450                              <1> 	; 03/05/2015
  1451                              <1> 	; 18/04/2015
  1452                              <1> 	; 12/04/2015
  1453                              <1> 	; 30/10/2014
  1454                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
  1455                              <1> 	;
  1456                              <1> 	; INPUT -> 
  1457                              <1> 	;	EBX = Virtual (linear) address of source page
  1458                              <1> 	;	     (Page fault address)
  1459                              <1> 	; OUTPUT ->
  1460                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  1461                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1462                              <1> 	;	EAX = 0 (CF = 1) 
  1463                              <1> 	;		if there is not a free page to be allocated
  1464                              <1> 	;	(page content of the source page will be copied
  1465                              <1> 	;	onto the target/new page) 	
  1466                              <1> 	;
  1467                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
  1468                              <1> 	;	
  1469 000034B7 56                  <1> 	push	esi
  1470 000034B8 57                  <1> 	push	edi
  1471                              <1> 	;push	ebx
  1472                              <1> 	;push	ecx
  1473 000034B9 31F6                <1> 	xor 	esi, esi
  1474 000034BB C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1475 000034BE 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1476 000034C0 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1477 000034C3 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1478 000034C6 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1479 000034C8 031D[D9DF0000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1480 000034CE 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1481 000034D0 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1482 000034D4 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1483 000034D6 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1484 000034DC 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1485 000034E0 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1486                              <1> 	; 07/09/2015
  1487 000034E2 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1488                              <1> 				     ; read only page as a child process?)	
  1489 000034E7 7509                <1> 	jnz	short cpp_0 ; yes
  1490 000034E9 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1491 000034EB 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1492 000034F0 EB32                <1> 	jmp	short cpp_1
  1493                              <1> cpp_0:
  1494 000034F2 89FE                <1> 	mov	esi, edi
  1495 000034F4 0335[DDDF0000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1496 000034FA 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1497 000034FC 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1498 00003500 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1499 00003502 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1500 00003508 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1501 0000350C 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1502 0000350E 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1503                              <1> 	; 21/09/2015
  1504 00003510 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1505 00003512 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1506                              <1> 	;
  1507 00003516 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1508 00003519 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1509                              <1> 	;
  1510 0000351B 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1511 00003520 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1512 00003522 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
  1513                              <1> 			    ; Convert child's page to writable page
  1514                              <1> cpp_1:
  1515 00003524 E8E6FBFFFF          <1> 	call	allocate_page
  1516 00003529 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1517 0000352B 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1518 0000352D 7405                <1> 	jz	short cpp_2
  1519                              <1> 		; Convert read only page to writable page 
  1520                              <1> 		;(for the parent of the current process)
  1521                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
  1522                              <1> 	; 22/09/2015
  1523 0000352F 890E                <1> 	mov	[esi], ecx
  1524 00003531 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
  1525                              <1> 				 ; 1+2+4 = 7
  1526                              <1> cpp_2:
  1527 00003534 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1528                              <1> 	; 07/09/2015
  1529 00003536 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1530 00003538 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1531 0000353D F3A5                <1> 	rep	movsd ; 31/08/2015
  1532                              <1> cpp_3:		
  1533 0000353F 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1534 00003541 8903                <1> 	mov	[ebx], eax ; Update PTE
  1535 00003543 28C0                <1> 	sub	al, al ; clear attributes
  1536                              <1> cpp_4:
  1537                              <1> 	;pop	ecx
  1538                              <1> 	;pop	ebx
  1539 00003545 5F                  <1> 	pop	edi
  1540 00003546 5E                  <1> 	pop	esi
  1541 00003547 C3                  <1> 	retn
  1542                              <1> 
  1543                              <1> ;; 28/04/2015
  1544                              <1> ;; 24/10/2014
  1545                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
  1546                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
  1547                              <1> ;;
  1548                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
  1549                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
  1550                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
  1551                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
  1552                              <1> ;;
  1553                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
  1554                              <1> ;;
  1555                              <1> ;; Method:
  1556                              <1> ;;	Swap page queue is a list of allocated pages with physical
  1557                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
  1558                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
  1559                              <1> ;;	When a new page is being allocated, swap queue is updated
  1560                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
  1561                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
  1562                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
  1563                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
  1564                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
  1565                              <1> ;;	offset value becomes it's previous offset value - 4.
  1566                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
  1567                              <1> ;;	the queue/list is not shifted.
  1568                              <1> ;;	After the queue/list shift, newly allocated page is added
  1569                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
  1570                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
  1571                              <1> ;;	will not be added to the tail of swap page queue.  		 
  1572                              <1> ;;	
  1573                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
  1574                              <1> ;;	the first non-accessed, writable page in the list, 
  1575                              <1> ;;	from the head to the tail. The list is shifted to left 
  1576                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
  1577                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
  1578                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
  1579                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
  1580                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
  1581                              <1> ;;	procedure will be failed)...
  1582                              <1> ;;
  1583                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
  1584                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
  1585                              <1> ;;	(PTE) will be added to the tail of the queue after
  1586                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
  1587                              <1> ;;	the queue will be rotated and the PTE in the head will be
  1588                              <1> ;;	added to the tail after resetting 'accessed' bit. 
  1589                              <1> ;;
  1590                              <1> ;;
  1591                              <1> ;;	
  1592                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
  1593                              <1> ;;
  1594                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
  1595                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
  1596                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
  1597                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
  1598                              <1> ;;
  1599                              <1> ;; [swpd_next] = the first free block address in swapped page records
  1600                              <1> ;;    		 for next free block search by 'swap_out' procedure.
  1601                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
  1602                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
  1603                              <1> ;; 		 (entire swap space must be accessed by using
  1604                              <1> ;;		 31 bit offset address) 
  1605                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
  1606                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
  1607                              <1> ;;		  0 for file, or beginning sector of the swap partition
  1608                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
  1609                              <1> ;;
  1610                              <1> ;; 					
  1611                              <1> ;; Method:
  1612                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
  1613                              <1> ;;	procedure swaps out a page from memory to the swap disk 
  1614                              <1> ;;	(partition) or swap file to get a new free page at the memory.
  1615                              <1> ;;	Swapping out is performed by using swap page queue.
  1616                              <1> ;;
  1617                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
  1618                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
  1619                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
  1620                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
  1621                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
  1622                              <1> ;;	Absolute physical (logical) address of the swapped page is 
  1623                              <1> ;;	calculated by adding offset value to the swap partition's 
  1624                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
  1625                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
  1626                              <1> ;;	and offset value is equal to absolute (physical or logical)
  1627                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
  1628                              <1> ;;	is in a partitioned virtual hard disk.) 
  1629                              <1> ;;
  1630                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
  1631                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
  1632                              <1> ;;
  1633                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
  1634                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
  1635                              <1> ;;
  1636                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
  1637                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
  1638                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
  1639                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
  1640                              <1> ;;	it means relevant (respective) block is in use, and, 
  1641                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
  1642                              <1> ;;      swap disk/file block is free.
  1643                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
  1644                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
  1645                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
  1646                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
  1647                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
  1648                              <1> ;;	------------------------------------------------------------
  1649                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
  1650                              <1> ;;	------------------------------------------------------------
  1651                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
  1652                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
  1653                              <1> ;;
  1654                              <1> ;;	..............................................................
  1655                              <1> ;;
  1656                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
  1657                              <1> ;;	then it searches Swap Allocation Table if free count is not
  1658                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
  1659                              <1> ;;	position with value of 1 on the table is converted to swap
  1660                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
  1661                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
  1662                              <1> ;;	number of physical swap disk or virtual swap disk)
  1663                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
  1664                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
  1665                              <1> ;;	(memory page). That will be a direct disk write procedure.
  1666                              <1> ;;	(for preventing late memory allocation, significant waiting). 
  1667                              <1> ;;	If disk write procedure returns with error or free count of 
  1668                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
  1669                              <1> ;;	'insufficient memory error' (cf=1). 
  1670                              <1> ;;
  1671                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
  1672                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
  1673                              <1> ;;	in other words, 'swap_out' will not check the table for other
  1674                              <1> ;;	free blocks after a disk write error. It will return to 
  1675                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
  1676                              <1> ;;
  1677                              <1> ;;	After writing the page on to swap disk/file address/sector,
  1678                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
  1679                              <1> ;;	address (cf=0). 
  1680                              <1> ;;
  1681                              <1> ;;	..............................................................
  1682                              <1> ;;
  1683                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
  1684                              <1> ;;	file sectors at specified memory page. Then page allocation
  1685                              <1> ;;	procedure updates relevant page table entry with 'present' 
  1686                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
  1687                              <1> ;;	to do, except to terminate the process which is the owner of
  1688                              <1> ;;	the swapped page.
  1689                              <1> ;;
  1690                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
  1691                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
  1692                              <1> ;;	updates [swpd_first] pointer if it is required.
  1693                              <1> ;;
  1694                              <1> ;;	..............................................................	 
  1695                              <1> ;;
  1696                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
  1697                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
  1698                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
  1699                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
  1700                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
  1701                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
  1702                              <1> ;;
  1703                              <1> 
  1704                              <1> swap_in:
  1705                              <1> 	; 31/08/2015
  1706                              <1> 	; 20/07/2015
  1707                              <1> 	; 28/04/2015
  1708                              <1> 	; 18/04/2015
  1709                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  1710                              <1> 	;
  1711                              <1> 	; INPUT -> 
  1712                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
  1713                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
  1714                              <1> 	;	EAX = Offset Address for the swapped page on the
  1715                              <1> 	;	      swap disk or in the swap file.
  1716                              <1> 	;
  1717                              <1> 	; OUTPUT ->
  1718                              <1> 	;	EAX = 0 if loading at memory has been successful
  1719                              <1> 	;
  1720                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
  1721                              <1> 	;		  or sector not present or drive not ready
  1722                              <1> 	;	     EAX = Error code
  1723                              <1> 	;	     [u.error] = EAX 
  1724                              <1> 	;		       = The last error code for the process
  1725                              <1> 	;		         (will be reset after returning to user)	  
  1726                              <1> 	;
  1727                              <1> 	; Modified Registers -> EAX
  1728                              <1> 	;
  1729                              <1> 
  1730 00003548 833D[3FEC0000]00    <1>         cmp     dword [swp_drv], 0
  1731 0000354F 7648                <1> 	jna	short swpin_dnp_err
  1732                              <1> 
  1733 00003551 3B05[43EC0000]      <1> 	cmp	eax, [swpd_size]
  1734 00003557 734C                <1> 	jnb	short swpin_snp_err
  1735                              <1> 
  1736 00003559 56                  <1> 	push	esi
  1737 0000355A 53                  <1> 	push	ebx
  1738 0000355B 51                  <1> 	push	ecx
  1739 0000355C 8B35[3FEC0000]      <1> 	mov	esi, [swp_drv]	
  1740 00003562 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1741                              <1> 		; Note: Even if corresponding physical disk's sector 
  1742                              <1> 		; size different than 512 bytes, logical disk sector
  1743                              <1> 		; size is 512 bytes and disk reading procedure
  1744                              <1> 		; will be performed for reading 4096 bytes
  1745                              <1> 		; (2*2048, 8*512). 
  1746                              <1> 	; ESI = Logical disk description table address
  1747                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1748                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1749                              <1> 	; ECX = Sector count ; 8 sectors
  1750 00003567 50                  <1> 	push	eax
  1751 00003568 E833020000          <1> 	call	logical_disk_read
  1752 0000356D 58                  <1> 	pop	eax
  1753 0000356E 730C                <1> 	jnc	short swpin_read_ok
  1754                              <1> 	;
  1755 00003570 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1756 00003575 A3[D5DF0000]        <1> 	mov	[u.error], eax
  1757 0000357A EB19                <1> 	jmp	short swpin_retn
  1758                              <1> 	;
  1759                              <1> swpin_read_ok:
  1760                              <1> 	; EAX = Offset address (logical sector number)
  1761 0000357C E891010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
  1762                              <1> 	;
  1763                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1764                              <1> 	; 20/07/2015
  1765 00003581 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1766 00003583 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1767 00003588 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno] ; current process number
  1768                              <1> 	; EBX = Virtual address & process number combination
  1769 0000358E E89E000000          <1> 	call	swap_queue_shift
  1770 00003593 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  1771                              <1> 	;
  1772                              <1> swpin_retn:
  1773 00003595 59                  <1> 	pop	ecx
  1774 00003596 5B                  <1> 	pop	ebx
  1775 00003597 5E                  <1> 	pop	esi
  1776 00003598 C3                  <1> 	retn
  1777                              <1> 
  1778                              <1> swpin_dnp_err:
  1779 00003599 B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1780                              <1> swpin_err_retn:
  1781 0000359E A3[D5DF0000]        <1> 	mov	[u.error], eax
  1782 000035A3 F9                  <1> 	stc
  1783 000035A4 C3                  <1> 	retn
  1784                              <1> 
  1785                              <1> swpin_snp_err:
  1786 000035A5 B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1787 000035AA EBF2                <1> 	jmp	short swpin_err_retn
  1788                              <1> 
  1789                              <1> swap_out:
  1790                              <1> 	; 31/08/2015
  1791                              <1> 	; 05/05/2015
  1792                              <1> 	; 30/04/2015
  1793                              <1> 	; 28/04/2015
  1794                              <1> 	; 18/04/2015
  1795                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  1796                              <1> 	;
  1797                              <1> 	; INPUT -> 
  1798                              <1> 	;	none
  1799                              <1> 	;
  1800                              <1> 	; OUTPUT ->
  1801                              <1> 	;	EAX = Physical page address (which is swapped out
  1802                              <1> 	;	      for allocating a new page)
  1803                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  1804                              <1> 	;		  or sector not present or drive not ready
  1805                              <1> 	;	     EAX = Error code
  1806                              <1> 	;	     [u.error] = EAX 
  1807                              <1> 	;		       = The last error code for the process
  1808                              <1> 	;		         (will be reset after returning to user)	  
  1809                              <1> 	;
  1810                              <1> 	; Modified Registers -> non (except EAX)
  1811                              <1> 	;
  1812 000035AC 66833D[3DEC0000]01  <1> 	cmp 	word [swpq_count], 1
  1813 000035B4 7274                <1>         jc      short swpout_im_err ; 'insufficient memory'
  1814                              <1> 
  1815                              <1>         ;cmp     dword [swp_drv], 1
  1816                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  1817                              <1> 
  1818 000035B6 833D[47EC0000]01    <1>         cmp     dword [swpd_free], 1
  1819 000035BD 7258                <1> 	jc	short swpout_nfspc_err ; 'no free space on swap disk'
  1820                              <1> 
  1821 000035BF 53                  <1> 	push	ebx
  1822                              <1> swpout_1:
  1823 000035C0 31DB                <1> 	xor	ebx, ebx
  1824 000035C2 E86A000000          <1> 	call	swap_queue_shift
  1825 000035C7 21C0                <1> 	and	eax, eax	; entry count (before shifting)
  1826 000035C9 7457                <1> 	jz	short swpout_npts_err  ; There is no any PTE in
  1827                              <1> 				       ; the swap queue
  1828 000035CB BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
  1829                              <1> 				       ; the swap queue		
  1830 000035D0 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
  1831                              <1> 
  1832                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
  1833                              <1> 	;jz	short swpout_1	       ; non-present page already
  1834                              <1> 				       ; must not be in the queue
  1835                              <1> 
  1836                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
  1837                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
  1838                              <1> 				       ; swapped out)
  1839                              <1> 	
  1840 000035D2 A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
  1841 000035D4 75EA                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
  1842                              <1> 				       ; swapped out, at this stage)
  1843                              <1> 	;
  1844 000035D6 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1845                              <1> 	;
  1846 000035DA 52                  <1> 	push	edx
  1847 000035DB 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1848 000035DD 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1849                              <1> 	;
  1850 000035DF E861010000          <1> 	call	link_swap_block
  1851 000035E4 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
  1852 000035E6 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
  1853 000035E7 5B                  <1> 	pop	ebx
  1854 000035E8 EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
  1855                              <1> swpout_2:	
  1856 000035EA 56                  <1> 	push	esi
  1857 000035EB 51                  <1> 	push	ecx
  1858 000035EC 50                  <1> 	push	eax ; sector address
  1859 000035ED 8B35[3FEC0000]      <1> 	mov	esi, [swp_drv]	
  1860 000035F3 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1861                              <1> 		; Note: Even if corresponding physical disk's sector 
  1862                              <1> 		; size different than 512 bytes, logical disk sector
  1863                              <1> 		; size is 512 bytes and disk writing procedure
  1864                              <1> 		; will be performed for writing 4096 bytes
  1865                              <1> 		; (2*2048, 8*512). 
  1866                              <1> 	; ESI = Logical disk description table address
  1867                              <1> 	; EBX = Buffer address
  1868                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1869                              <1> 	; ECX = Sector count ; 8 sectors
  1870 000035F8 E8A4010000          <1> 	call	logical_disk_write
  1871 000035FD 59                  <1> 	pop	ecx ; sector address	
  1872 000035FE 730C                <1> 	jnc	short swpout_write_ok
  1873                              <1> 	;
  1874                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
  1875                              <1> swpout_dw_err:
  1876 00003600 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1877 00003605 A3[D5DF0000]        <1> 	mov	[u.error], eax
  1878 0000360A EB06                <1> 	jmp	short swpout_retn
  1879                              <1> 	;
  1880                              <1> swpout_write_ok:
  1881                              <1> 	; EBX = Buffer (page) address
  1882                              <1> 	; EDX = Page Table entry address
  1883                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
  1884 0000360C D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1885 0000360E 890A                <1> 	mov 	[edx], ecx 
  1886                              <1> 		; bit 0 = 0 (swapped page)
  1887 00003610 89D8                <1> 	mov	eax, ebx
  1888                              <1> swpout_retn:
  1889 00003612 59                  <1> 	pop	ecx
  1890 00003613 5E                  <1> 	pop	esi
  1891 00003614 5A                  <1> 	pop	edx
  1892 00003615 5B                  <1> 	pop	ebx
  1893 00003616 C3                  <1> 	retn
  1894                              <1> 
  1895                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
  1896                              <1> ;	after the page is swapped out. (the PTE at the queue head
  1897                              <1> ;	-with 'non-present' attribute- will be dropped from the
  1898                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
  1899                              <1> 	
  1900                              <1> ;swpout_dnp_err:
  1901                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  1902                              <1> ;	jmp	short swpout_err_retn
  1903                              <1> swpout_nfspc_err:
  1904 00003617 B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1905                              <1> swpout_err_retn:
  1906 0000361C A3[D5DF0000]        <1> 	mov	[u.error], eax
  1907                              <1> 	;stc
  1908 00003621 C3                  <1> 	retn
  1909                              <1> swpout_npts_err:
  1910 00003622 B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1911 00003627 5B                  <1> 	pop	ebx
  1912 00003628 EBF2                <1> 	jmp	short swpout_err_retn
  1913                              <1> swpout_im_err:
  1914 0000362A B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1915 0000362F EBEB                <1> 	jmp	short swpout_err_retn
  1916                              <1> 
  1917                              <1> swap_queue_shift:
  1918                              <1> 	; 20/07/2015
  1919                              <1> 	; 28/04/2015
  1920                              <1> 	; 18/04/2015
  1921                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
  1922                              <1> 	;
  1923                              <1> 	; INPUT ->
  1924                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  1925                              <1> 	;	      and process number combination (bit 0 to 11)
  1926                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  1927                              <1> 	; OUTPUT ->
  1928                              <1> 	;	If EBX input > 0 
  1929                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1930                              <1> 	; 	    from the tail to the head, up to entry offset
  1931                              <1> 	; 	    which points to EBX input value or nothing
  1932                              <1> 	;	    to do if EBX value is not found in the queue.
  1933                              <1> 	;	    (The entry -with EBX value- will be removed
  1934                              <1> 	;	     from the queue if it is found.)	
  1935                              <1> 	;	If EBX input = 0
  1936                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1937                              <1> 	; 	    from the tail to the head, if the PTE address
  1938                              <1> 	;	    in head of the queue is marked as "accessed"
  1939                              <1> 	;	    or it is marked as "non present".
  1940                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
  1941                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
  1942                              <1> 	;	    the queue will be rotated -without dropping
  1943                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
  1944                              <1> 	; 	    to tail direction. The PTE in the head will be
  1945                              <1> 	;	    moved in the tail, other PTEs will be shifted on
  1946                              <1> 	;	    head direction.)	
  1947                              <1> 	;
  1948                              <1> 	;	EAX = [swpq_count] (before the shifting)
  1949                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
  1950                              <1> 	; 	     is not applicable)	
  1951                              <1> 	;
  1952                              <1> 	; Modified Registers -> EAX
  1953                              <1> 	;
  1954 00003631 0FB705[3DEC0000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  1955 00003638 6621C0              <1> 	and	ax, ax
  1956 0000363B 7433                <1> 	jz	short swpqs_retn
  1957 0000363D 57                  <1> 	push	edi
  1958 0000363E 56                  <1> 	push	esi
  1959 0000363F 53                  <1> 	push	ebx
  1960 00003640 51                  <1> 	push	ecx
  1961 00003641 50                  <1> 	push	eax
  1962 00003642 BE00E00800          <1> 	mov	esi, swap_queue
  1963 00003647 89C1                <1> 	mov	ecx, eax
  1964 00003649 09DB                <1> 	or	ebx, ebx
  1965 0000364B 7424                <1> 	jz	short swpqs_7
  1966                              <1> swpqs_1:
  1967 0000364D AD                  <1> 	lodsd
  1968 0000364E 39D8                <1> 	cmp	eax, ebx
  1969 00003650 7404                <1> 	je	short swpqs_2
  1970 00003652 E2F9                <1> 	loop	swpqs_1
  1971 00003654 EB15                <1> 	jmp	short swpqs_6
  1972                              <1> swpqs_2:
  1973 00003656 89F7                <1> 	mov	edi, esi
  1974 00003658 83EF04              <1> 	sub 	edi, 4
  1975                              <1> swpqs_3:
  1976 0000365B 66FF0D[3DEC0000]    <1> 	dec	word [swpq_count]
  1977 00003662 7403                <1> 	jz	short swpqs_5
  1978                              <1> swpqs_4:
  1979 00003664 49                  <1> 	dec 	ecx
  1980 00003665 F3A5                <1> 	rep	movsd	; shift up (to the head)
  1981                              <1> swpqs_5:
  1982 00003667 31C0                <1> 	xor	eax, eax
  1983 00003669 8907                <1> 	mov	[edi], eax
  1984                              <1> swpqs_6:
  1985 0000366B 58                  <1> 	pop	eax
  1986 0000366C 59                  <1> 	pop	ecx
  1987 0000366D 5B                  <1> 	pop	ebx
  1988 0000366E 5E                  <1> 	pop	esi
  1989 0000366F 5F                  <1> 	pop	edi
  1990                              <1> swpqs_retn:
  1991 00003670 C3                  <1> 	retn		
  1992                              <1> swpqs_7:
  1993 00003671 89F7                <1> 	mov	edi, esi ; head
  1994 00003673 AD                  <1> 	lodsd
  1995                              <1> 	; 20/07/2015
  1996 00003674 89C3                <1> 	mov	ebx, eax
  1997 00003676 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  1998                              <1> 		      ; ebx = virtual address (at page boundary)	
  1999 0000367C 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2000                              <1> 		      ; ax = process number (1 to 4095)
  2001 00003681 3A05[CFDF0000]      <1> 	cmp	al, [u.uno]
  2002                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2003 00003687 7507                <1> 	jne	short swpqs_8
  2004 00003689 A1[D9DF0000]        <1> 	mov	eax, [u.pgdir]
  2005 0000368E EB16                <1> 	jmp	short swpqs_9
  2006                              <1> swpqs_8:
  2007                              <1> 	;shl	ax, 2
  2008 00003690 C0E002              <1> 	shl	al, 2
  2009 00003693 8B80[14DD0000]      <1> 	mov 	eax, [eax+p.upage-4]
  2010 00003699 09C0                <1> 	or	eax, eax
  2011 0000369B 74BE                <1> 	jz	short swpqs_3 ; invalid upage
  2012 0000369D 83C061              <1> 	add	eax, u.pgdir - user
  2013                              <1> 			 ; u.pgdir value for the process
  2014                              <1> 			 ; is in [eax]
  2015 000036A0 8B00                <1> 	mov	eax, [eax]
  2016 000036A2 21C0                <1> 	and	eax, eax
  2017 000036A4 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
  2018                              <1> swpqs_9:
  2019 000036A6 52                  <1> 	push	edx
  2020                              <1> 	; eax = page directory
  2021                              <1> 	; ebx = virtual address
  2022 000036A7 E87EFBFFFF          <1> 	call	get_pte
  2023 000036AC 89D3                <1> 	mov	ebx, edx ; PTE address
  2024 000036AE 5A                  <1> 	pop	edx
  2025 000036AF 72AA                <1> 	jc	short swpqs_3 ; empty PDE
  2026                              <1> 	; EAX = PTE value
  2027 000036B1 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2028 000036B3 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
  2029                              <1> 			      ; from the queue (head)
  2030 000036B5 A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
  2031 000036B7 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
  2032                              <1> 			      ; from the queue (head) 	
  2033                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
  2034                              <1> 	;jz	short swpqs_6 ; present
  2035                              <1> 			      ; non-accessed page
  2036 000036B9 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2037 000036BD 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
  2038 000036BF 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2039                              <1> 	;
  2040                              <1> 	; Rotation (head -> tail)
  2041 000036C1 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2042 000036C2 74A7                <1> 	jz	short swpqs_6
  2043                              <1> 		; esi = head + 4
  2044                              <1> 		; edi = head
  2045 000036C4 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2046 000036C6 F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2047 000036C8 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
  2048 000036CA EB9F                <1> 	jmp	short swpqs_6
  2049                              <1> 
  2050                              <1> add_to_swap_queue:
  2051                              <1> ; temporary - 16/09/2015
  2052 000036CC C3                  <1> retn
  2053                              <1> 	; 20/07/2015
  2054                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2055                              <1> 	;
  2056                              <1> 	; Adds new page to swap queue
  2057                              <1> 	; (page directories and page tables must not be added
  2058                              <1> 	; to swap queue)	
  2059                              <1> 	;
  2060                              <1> 	; INPUT ->
  2061                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
  2062                              <1> 	;
  2063                              <1> 	; OUTPUT ->
  2064                              <1> 	;	EAX = [swpq_count]
  2065                              <1> 	;	      (after the PTE has been added)
  2066                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  2067                              <1> 	;	      the pte could not be added.
  2068                              <1> 	;
  2069                              <1> 	; Modified Registers -> EAX
  2070                              <1> 	;
  2071 000036CD 53                  <1> 	push	ebx
  2072 000036CE 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2073 000036D3 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno] ; current process number
  2074 000036D9 E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2075                              <1> 				 ; it is already in the queue
  2076                              <1> 		; Then add it to the tail of the queue
  2077 000036DE 0FB705[3DEC0000]    <1> 	movzx	eax, word [swpq_count]
  2078 000036E5 663D0004            <1> 	cmp	ax, 1024
  2079 000036E9 7205                <1> 	jb	short atsq_1
  2080 000036EB 6629C0              <1> 	sub	ax, ax
  2081 000036EE 5B                  <1> 	pop	ebx
  2082 000036EF C3                  <1> 	retn
  2083                              <1> atsq_1:
  2084 000036F0 56                  <1> 	push	esi
  2085 000036F1 BE00E00800          <1> 	mov	esi, swap_queue
  2086 000036F6 6621C0              <1> 	and	ax, ax
  2087 000036F9 740A                <1> 	jz	short atsq_2
  2088 000036FB 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2089 000036FF 01C6                <1> 	add	esi, eax
  2090 00003701 66C1E802            <1> 	shr	ax, 2
  2091                              <1> atsq_2:
  2092 00003705 6640                <1> 	inc	ax
  2093 00003707 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2094 00003709 66A3[3DEC0000]      <1> 	mov	[swpq_count], ax
  2095 0000370F 5E                  <1> 	pop	esi
  2096 00003710 5B                  <1> 	pop	ebx
  2097 00003711 C3                  <1> 	retn
  2098                              <1> 
  2099                              <1> unlink_swap_block:
  2100                              <1> 	; 15/09/2015
  2101                              <1> 	; 30/04/2015
  2102                              <1> 	; 18/04/2015
  2103                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2104                              <1> 	;
  2105                              <1> 	; INPUT -> 
  2106                              <1> 	;	EAX = swap disk/file offset address
  2107                              <1> 	;	      (bit 1 to bit 31)
  2108                              <1> 	; OUTPUT ->
  2109                              <1> 	;	[swpd_free] is increased
  2110                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  2111                              <1> 	;
  2112                              <1> 	; Modified Registers -> EAX
  2113                              <1> 	;
  2114 00003712 53                  <1> 	push	ebx
  2115 00003713 52                  <1> 	push	edx
  2116                              <1> 	;
  2117 00003714 C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  2118                              <1> 				     ; 3 bits right
  2119                              <1> 				     ; to get swap block/page number
  2120 00003717 89C2                <1> 	mov	edx, eax
  2121                              <1> 	; 15/09/2015
  2122 00003719 C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
  2123                              <1> 				     ; (1 allocation bit = 1 page)
  2124                              <1> 				     ; (1 allocation bytes = 8 pages)
  2125 0000371C 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2126                              <1> 				     ; (to get 32 bit position)			
  2127                              <1> 	;
  2128 0000371F BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2129 00003724 01D3                <1> 	add	ebx, edx
  2130 00003726 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2131                              <1> 				     ; (allocation bit position)	 
  2132 00003729 3B05[4BEC0000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  2133                              <1> 				     ; than the address in 'swpd_next' ?
  2134                              <1> 				     ; (next/first free block value)		
  2135 0000372F 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2136 00003731 A3[4BEC0000]        <1> 	mov	[swpd_next], eax     ; yes	
  2137                              <1> uswpbl_1:
  2138 00003736 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
  2139                              <1> 				     ; set relevant bit to 1.
  2140                              <1> 				     ; set CF to the previous bit value	
  2141 00003739 F5                  <1> 	cmc			     ; complement carry flag	
  2142 0000373A 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2143                              <1> 				     ; if the block is already deallocated
  2144                              <1> 				     ; before.	
  2145 0000373C FF05[47EC0000]      <1>         inc     dword [swpd_free]
  2146                              <1> uswpbl_2:
  2147 00003742 5A                  <1> 	pop	edx
  2148 00003743 5B                  <1> 	pop	ebx
  2149 00003744 C3                  <1> 	retn
  2150                              <1> 
  2151                              <1> link_swap_block:
  2152                              <1> 	; 01/07/2015
  2153                              <1> 	; 18/04/2015
  2154                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2155                              <1> 	;
  2156                              <1> 	; INPUT -> none
  2157                              <1> 	;
  2158                              <1> 	; OUTPUT ->
  2159                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  2160                              <1> 	;	      in sectors (corresponding 
  2161                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  2162                              <1> 	;
  2163                              <1> 	;	CF = 1 and EAX = 0 
  2164                              <1> 	; 		   if there is not a free block to be allocated	
  2165                              <1> 	;
  2166                              <1> 	; Modified Registers -> none (except EAX)
  2167                              <1> 	;
  2168                              <1> 
  2169                              <1> 	;mov	eax, [swpd_free]
  2170                              <1> 	;and	eax, eax
  2171                              <1> 	;jz	short out_of_swpspc
  2172                              <1> 	;
  2173 00003745 53                  <1> 	push	ebx
  2174 00003746 51                  <1> 	push	ecx
  2175                              <1> 	;
  2176 00003747 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2177 0000374C 89D9                <1> 	mov	ecx, ebx
  2178 0000374E 031D[4BEC0000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2179                              <1> 				 ; next_free_swap_block >> 5
  2180 00003754 030D[4FEC0000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2181                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2182                              <1> lswbl_scan:
  2183 0000375A 39CB                <1> 	cmp	ebx, ecx
  2184 0000375C 770A                <1> 	ja	short lswbl_notfound
  2185                              <1> 	;
  2186 0000375E 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2187                              <1> 			   ; Clears ZF if a bit is found set (1) and 
  2188                              <1> 			   ; loads the destination with an index to
  2189                              <1> 			   ; first set bit. (0 -> 31) 
  2190                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2191                              <1> 	; 01/07/2015
  2192 00003761 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  2193                              <1> 			 ;
  2194                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
  2195                              <1> 			 ;	  with value of 1 means 
  2196                              <1> 			 ;	  the corresponding page is free 
  2197                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
  2198 00003763 83C304              <1> 	add	ebx, 4
  2199                              <1> 			 ; We return back for searching next page block
  2200                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
  2201                              <1> 			 ;	 we always will find at least 1 free block here.
  2202 00003766 EBF2                <1> 	jmp    	short lswbl_scan
  2203                              <1> 	;
  2204                              <1> lswbl_notfound:	
  2205 00003768 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2206 0000376E 890D[4BEC0000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2207                              <1> 				 ; (unlink_swap_block procedure will change it)
  2208 00003774 31C0                <1> 	xor	eax, eax
  2209 00003776 A3[47EC0000]        <1> 	mov	[swpd_free], eax
  2210 0000377B F9                  <1> 	stc
  2211                              <1> lswbl_ok:
  2212 0000377C 59                  <1> 	pop	ecx
  2213 0000377D 5B                  <1> 	pop	ebx
  2214 0000377E C3                  <1> 	retn
  2215                              <1> 	;
  2216                              <1> ;out_of_swpspc:
  2217                              <1> ;	stc
  2218                              <1> ;	retn
  2219                              <1> 
  2220                              <1> lswbl_found:
  2221 0000377F 89D9                <1> 	mov	ecx, ebx
  2222 00003781 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2223 00003787 890D[4BEC0000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2224                              <1> 				 ; address/offset (to the next)
  2225 0000378D FF0D[47EC0000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2226                              <1> 	;
  2227 00003793 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2228                              <1> 				 ; is copied into the Carry Flag and then cleared
  2229                              <1> 				 ; in the destination.
  2230                              <1> 				 ;
  2231                              <1> 				 ; Reset the bit which is corresponding to the 
  2232                              <1> 				 ; (just) allocated block.
  2233 00003796 C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2234 00003799 01C8                <1> 	add	eax, ecx	 ; = block number
  2235 0000379B C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  2236                              <1> 				 ; 1 block =  8 sectors
  2237                              <1> 	;
  2238                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
  2239                              <1> 	;
  2240                              <1> 	; NOTE: The relevant page table entry will be updated
  2241                              <1> 	;       according to this EAX value...
  2242                              <1> 	;
  2243 0000379E EBDC                <1> 	jmp	short lswbl_ok
  2244                              <1> 
  2245                              <1> logical_disk_read:
  2246                              <1> 	; 20/07/2015
  2247                              <1> 	; 09/03/2015 (temporary code here)
  2248                              <1> 	;
  2249                              <1> 	; INPUT ->
  2250                              <1> 	; 	ESI = Logical disk description table address
  2251                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2252                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2253                              <1> 	; 	ECX = Sector count
  2254                              <1> 	;
  2255                              <1> 	;
  2256 000037A0 C3                  <1> 	retn
  2257                              <1> 
  2258                              <1> logical_disk_write:
  2259                              <1> 	; 20/07/2015
  2260                              <1> 	; 09/03/2015 (temporary code here)
  2261                              <1> 	;
  2262                              <1> 	; INPUT ->
  2263                              <1> 	; 	ESI = Logical disk description table address
  2264                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2265                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2266                              <1> 	; 	ECX = Sector count
  2267                              <1> 	;
  2268 000037A1 C3                  <1> 	retn
  2269                              <1> 
  2270                              <1> get_physical_addr:
  2271                              <1> 	; 18/10/2015
  2272                              <1> 	; 29/07/2015
  2273                              <1> 	; 20/07/2015
  2274                              <1> 	; 04/06/2015
  2275                              <1> 	; 20/05/2015
  2276                              <1> 	; 28/04/2015
  2277                              <1> 	; 18/04/2015
  2278                              <1> 	; Get physical address
  2279                              <1> 	;     (allocates a new page for user if it is not present)
  2280                              <1> 	;	
  2281                              <1> 	; (This subroutine is needed for mapping user's virtual 
  2282                              <1> 	; (buffer) address to physical address (of the buffer).)
  2283                              <1> 	; ('sys write', 'sys read' system calls...)
  2284                              <1> 	;
  2285                              <1> 	; INPUT ->
  2286                              <1> 	;	EBX = virtual address
  2287                              <1> 	;	u.pgdir = page directory (physical) address
  2288                              <1> 	;
  2289                              <1> 	; OUTPUT ->
  2290                              <1> 	;	EAX = physical address 
  2291                              <1> 	;	EBX = linear address	
  2292                              <1> 	;	EDX = physical address of the page frame
  2293                              <1> 	;	      (with attribute bits)
  2294                              <1> 	;	ECX = byte count within the page frame
  2295                              <1> 	;
  2296                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  2297                              <1> 	;
  2298 000037A2 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2299                              <1> 	;
  2300 000037A8 A1[D9DF0000]        <1> 	mov	eax, [u.pgdir]
  2301 000037AD E878FAFFFF          <1> 	call	get_pte
  2302                              <1> 		; EDX = Page table entry address (if CF=0)
  2303                              <1> 	        ;       Page directory entry address (if CF=1)
  2304                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  2305                              <1> 		; EAX = Page table entry value (page address)
  2306                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  2307 000037B2 731C                <1> 	jnc	short gpa_1
  2308                              <1> 	;
  2309 000037B4 E856F9FFFF          <1> 	call	allocate_page
  2310 000037B9 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2311                              <1> gpa_0:
  2312 000037BB E8C9F9FFFF          <1> 	call 	clear_page
  2313                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2314 000037C0 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  2315                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  2316                              <1> 			   ; (user, writable, present page)	
  2317 000037C2 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2318 000037C4 A1[D9DF0000]        <1> 	mov	eax, [u.pgdir]	
  2319 000037C9 E85CFAFFFF          <1> 	call	get_pte
  2320 000037CE 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2321                              <1> gpa_1:
  2322                              <1> 	; EAX = PTE value, EDX = PTE address
  2323 000037D0 A801                <1> 	test 	al, PTE_A_PRESENT
  2324 000037D2 751A                <1> 	jnz	short gpa_3
  2325 000037D4 09C0                <1> 	or	eax, eax
  2326 000037D6 7430                <1> 	jz	short gpa_4  ; Allocate a new page
  2327                              <1> 	; 20/07/2015
  2328 000037D8 55                  <1> 	push	ebp
  2329 000037D9 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2330                              <1> 	; reload swapped page
  2331 000037DB E83C000000          <1> 	call	reload_page ; 28/04/2015
  2332 000037E0 5D                  <1> 	pop	ebp
  2333 000037E1 7224                <1> 	jc	short gpa_retn
  2334                              <1> gpa_2:
  2335                              <1> 	; 20/07/2015
  2336                              <1> 	; 20/05/2015
  2337                              <1> 	; add this page to swap queue
  2338 000037E3 50                  <1> 	push	eax 
  2339                              <1> 	; EBX = virtual address
  2340 000037E4 E8E3FEFFFF          <1> 	call 	add_to_swap_queue
  2341 000037E9 58                  <1> 	pop	eax
  2342                              <1> 		; PTE address in EDX
  2343                              <1> 		; virtual address in EBX
  2344                              <1> 	; EAX = memory page address
  2345 000037EA 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  2346                              <1> 				  ; present flag, bit 0 = 1
  2347                              <1> 				  ; user flag, bit 2 = 1	
  2348                              <1> 				  ; writable flag, bit 1 = 1
  2349 000037EC 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2350                              <1> gpa_3:
  2351                              <1> 	; 18/10/2015
  2352 000037EE 89D9                <1> 	mov	ecx, ebx
  2353 000037F0 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2354 000037F6 89C2                <1> 	mov 	edx, eax
  2355 000037F8 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2356 000037FC 01C8                <1> 	add	eax, ecx
  2357 000037FE F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2358 00003800 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2359 00003806 F8                  <1> 	clc
  2360                              <1> gpa_retn:
  2361 00003807 C3                  <1> 	retn	
  2362                              <1> gpa_4:	
  2363 00003808 E802F9FFFF          <1> 	call	allocate_page
  2364 0000380D 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2365 0000380F E875F9FFFF          <1> 	call	clear_page
  2366 00003814 EBCD                <1> 	jmp	short gpa_2
  2367                              <1> 
  2368                              <1> gpa_im_err:	
  2369 00003816 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2370                              <1> 				  ; Major error = 0 (No protection fault)	
  2371 0000381B C3                  <1> 	retn
  2372                              <1> 
  2373                              <1> reload_page:
  2374                              <1> 	; 20/07/2015
  2375                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  2376                              <1> 	;
  2377                              <1> 	; Reload (Restore) swapped page at memory
  2378                              <1> 	;
  2379                              <1> 	; INPUT -> 
  2380                              <1> 	;	EBP = Virtual (linear) memory address
  2381                              <1> 	;	EAX = PTE value (swap disk sector address)
  2382                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  2383                              <1> 	; OUTPUT ->
  2384                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  2385                              <1> 	;
  2386                              <1> 	;	CF = 1 and EAX = error code
  2387                              <1> 	;
  2388                              <1> 	; Modified Registers -> none (except EAX)
  2389                              <1> 	;
  2390 0000381C D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2391 0000381E 53                  <1> 	push	ebx      ;
  2392 0000381F 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2393 00003821 E8E9F8FFFF          <1> 	call	allocate_page
  2394 00003826 720C                <1> 	jc	short rlp_im_err
  2395 00003828 93                  <1> 	xchg 	eax, ebx	
  2396                              <1> 	; EBX = Physical memory (page) address
  2397                              <1> 	; EAX = Swap disk (offset) address
  2398                              <1> 	; EBP = Virtual (linear) memory address
  2399 00003829 E81AFDFFFF          <1> 	call	swap_in
  2400 0000382E 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2401 00003830 89D8                <1> 	mov	eax, ebx	
  2402                              <1> rlp_retn:
  2403 00003832 5B                  <1> 	pop	ebx
  2404 00003833 C3                  <1> 	retn
  2405                              <1> 	
  2406                              <1> rlp_im_err:	
  2407 00003834 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2408                              <1> 				  ; Major error = 0 (No protection fault)	
  2409 00003839 EBF7                <1> 	jmp	short rlp_retn
  2410                              <1> 
  2411                              <1> rlp_swp_err:
  2412 0000383B B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2413 00003840 EBF0                <1> 	jmp	short rlp_retn
  2414                              <1> 
  2415                              <1> 
  2416                              <1> copy_page_dir:
  2417                              <1> 	; 19/09/2015
  2418                              <1> 	; temporary - 07/09/2015
  2419                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2420                              <1> 	;
  2421                              <1> 	; INPUT -> 
  2422                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  2423                              <1> 	;		    page directory.
  2424                              <1> 	; OUTPUT ->
  2425                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  2426                              <1> 	;	       page directory.
  2427                              <1> 	;	(New page directory with new page table entries.)
  2428                              <1> 	;	(New page tables with read only copies of the parent's
  2429                              <1> 	;	pages.)
  2430                              <1> 	;	EAX = 0 -> Error (CF = 1)
  2431                              <1> 	;
  2432                              <1> 	; Modified Registers -> none (except EAX)
  2433                              <1> 	;
  2434 00003842 E8C8F8FFFF          <1> 	call	allocate_page
  2435 00003847 723E                <1> 	jc	short cpd_err
  2436                              <1> 	;
  2437 00003849 55                  <1> 	push	ebp ; 20/07/2015
  2438 0000384A 56                  <1> 	push	esi
  2439 0000384B 57                  <1> 	push	edi
  2440 0000384C 53                  <1> 	push	ebx
  2441 0000384D 51                  <1> 	push	ecx
  2442 0000384E 8B35[D9DF0000]      <1> 	mov	esi, [u.pgdir]
  2443 00003854 89C7                <1> 	mov	edi, eax
  2444 00003856 50                  <1> 	push	eax ; save child's page directory address
  2445                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  2446                              <1> 	; (use same system space for all user page tables) 
  2447 00003857 A5                  <1> 	movsd
  2448 00003858 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2449 0000385D B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2450                              <1> cpd_0:	
  2451 00003862 AD                  <1> 	lodsd
  2452                              <1> 	;or	eax, eax
  2453                              <1>         ;jnz     short cpd_1
  2454 00003863 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2455 00003865 7508                <1> 	jnz	short cpd_1
  2456                              <1>  	; (virtual address at the end of the page table)	
  2457 00003867 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2458 0000386D EB0F                <1> 	jmp	short cpd_2
  2459                              <1> cpd_1:	
  2460 0000386F 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2461 00003873 89C3                <1> 	mov	ebx, eax
  2462                              <1> 	; EBX = Parent's page table address
  2463 00003875 E81F000000          <1> 	call	copy_page_table
  2464 0000387A 720C                <1> 	jc	short cpd_p_err
  2465                              <1> 	; EAX = Child's page table address
  2466 0000387C 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  2467                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  2468                              <1> 			 ; (present, writable, user)
  2469                              <1> cpd_2:
  2470 0000387E AB                  <1> 	stosd
  2471 0000387F E2E1                <1> 	loop	cpd_0
  2472                              <1> 	;
  2473 00003881 58                  <1> 	pop	eax  ; restore child's page directory address
  2474                              <1> cpd_3:
  2475 00003882 59                  <1> 	pop	ecx
  2476 00003883 5B                  <1> 	pop	ebx
  2477 00003884 5F                  <1> 	pop	edi
  2478 00003885 5E                  <1> 	pop	esi
  2479 00003886 5D                  <1> 	pop	ebp
  2480                              <1> cpd_err:
  2481 00003887 C3                  <1> 	retn
  2482                              <1> cpd_p_err:
  2483                              <1> 	; release the allocated pages missing (recover free space)
  2484 00003888 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2485 00003889 8B1D[D9DF0000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2486 0000388F E8B4F9FFFF          <1> 	call 	deallocate_page_dir
  2487 00003894 29C0                <1> 	sub	eax, eax ; 0
  2488 00003896 F9                  <1> 	stc
  2489 00003897 EBE9                <1> 	jmp	short cpd_3	
  2490                              <1> 
  2491                              <1> copy_page_table:
  2492                              <1> 	; 19/09/2015
  2493                              <1> 	; temporary - 07/09/2015
  2494                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2495                              <1> 	;
  2496                              <1> 	; INPUT -> 
  2497                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  2498                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  2499                              <1> 	; OUTPUT ->
  2500                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  2501                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  2502                              <1> 	;	CF = 1 -> error 
  2503                              <1> 	;
  2504                              <1> 	; Modified Registers -> EBP (except EAX)
  2505                              <1> 	;
  2506 00003899 E871F8FFFF          <1> 	call	allocate_page
  2507 0000389E 725A                <1> 	jc	short cpt_err
  2508                              <1> 	;
  2509 000038A0 50                  <1> 	push	eax ; *
  2510                              <1> 	;push 	ebx
  2511 000038A1 56                  <1> 	push	esi
  2512 000038A2 57                  <1> 	push	edi
  2513 000038A3 52                  <1> 	push	edx
  2514 000038A4 51                  <1> 	push	ecx
  2515                              <1> 	;
  2516 000038A5 89DE                <1> 	mov	esi, ebx
  2517 000038A7 89C7                <1> 	mov	edi, eax
  2518 000038A9 89C2                <1> 	mov	edx, eax
  2519 000038AB 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2520                              <1> cpt_0:
  2521 000038B1 AD                  <1> 	lodsd
  2522 000038B2 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2523 000038B4 750B                <1> 	jnz	short cpt_1
  2524 000038B6 21C0                <1> 	and	eax, eax
  2525 000038B8 7430                <1> 	jz	short cpt_2
  2526                              <1> 	; ebp = virtual (linear) address of the memory page
  2527 000038BA E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2528 000038BF 7234                <1> 	jc	short cpt_p_err
  2529                              <1> cpt_1:
  2530 000038C1 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2531 000038C5 89C1                <1> 	mov	ecx, eax
  2532                              <1> 	; Allocate a new page for the child process
  2533 000038C7 E843F8FFFF          <1> 	call	allocate_page
  2534 000038CC 7227                <1> 	jc	short cpt_p_err
  2535 000038CE 57                  <1> 	push	edi
  2536 000038CF 56                  <1> 	push	esi
  2537 000038D0 89CE                <1> 	mov	esi, ecx
  2538 000038D2 89C7                <1> 	mov	edi, eax
  2539 000038D4 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2540 000038D9 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2541 000038DB 5E                  <1> 	pop	esi
  2542 000038DC 5F                  <1> 	pop	edi
  2543                              <1> 	; 
  2544 000038DD 53                  <1> 	push	ebx
  2545 000038DE 50                  <1> 	push	eax
  2546 000038DF 89EB                <1> 	mov	ebx, ebp
  2547                              <1> 	; ebx = virtual address of the memory page
  2548 000038E1 E8E6FDFFFF          <1> 	call	add_to_swap_queue
  2549 000038E6 58                  <1> 	pop	eax
  2550 000038E7 5B                  <1> 	pop	ebx
  2551                              <1> 	;
  2552                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2553 000038E8 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2554                              <1> cpt_2:
  2555 000038EA AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2556                              <1> 	;
  2557 000038EB 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2558                              <1> 	;
  2559 000038F1 39D7                <1> 	cmp	edi, edx
  2560 000038F3 72BC                <1> 	jb	short cpt_0
  2561                              <1> cpt_p_err:
  2562 000038F5 59                  <1> 	pop	ecx
  2563 000038F6 5A                  <1> 	pop	edx
  2564 000038F7 5F                  <1> 	pop	edi
  2565 000038F8 5E                  <1> 	pop	esi
  2566                              <1> 	;pop	ebx
  2567 000038F9 58                  <1> 	pop	eax ; *
  2568                              <1> cpt_err:
  2569 000038FA C3                  <1> 	retn
  2570                              <1> 
  2571                              <1> 
  2572                              <1> allocate_memory_block:
  2573                              <1> 	; 03/04/2016
  2574                              <1> 	; 02/04/2016
  2575                              <1> 	; 01/04/2016
  2576                              <1> 	; 14/03/2016
  2577                              <1> 	; 13/03/2016
  2578                              <1> 	; 12/03/2016 (TRDOS 386 = TRDOS v2.0)
  2579                              <1> 	; Allocating contiguous memory pages (in the kernel's memory space)
  2580                              <1> 	;
  2581                              <1> 	; INPUT -> 
  2582                              <1> 	;	EAX = Beginning address (physical)
  2583                              <1> 	;	EAX = 0 -> Allocate memory block from the first proper aperture	
  2584                              <1> 	;	ECX = Number of bytes to be allocated
  2585                              <1> 	;
  2586                              <1> 	; OUTPUT ->
  2587                              <1> 	; 	1) cf = 0 -> successful
  2588                              <1> 	;	EAX = Beginning (physical) address of the allocated memory block
  2589                              <1> 	;	ECX = Number of allocated bytes (rounded up to page borders) 
  2590                              <1> 	;	2) cf = 1 -> unsuccessful
  2591                              <1> 	;	 2.1) If EAX > 0 -> 
  2592                              <1> 	;	      (Number of requested pages is more than # of free pages
  2593                              <1> 	;	       but contiguous free pages -the aperture- is not enough!)	   	
  2594                              <1> 	;	      EAX = Beginning address of available aperture
  2595                              <1> 	;		    (one of all aperture with max. aperture size/length)		
  2596                              <1> 	;	      ECX = Size of available aperture (memory block) in bytes
  2597                              <1> 	;	 2.2) If EAX = 0 -> Out of memory error 
  2598                              <1> 	;	            (number of free pages is less than requested number)
  2599                              <1> 	;	      ECX = Total number of free bytes (free pages * 4096) 
  2600                              <1> 	;		    (It is not number of contiguous free bytes)	
  2601                              <1> 	;
  2602                              <1> 	; (Modified Registers -> EAX, ECX)
  2603                              <1> 	;
  2604                              <1> 	; PURPOSE: Loading a file at memory for copying or running etc.
  2605                              <1> 	; If this procedure returns with cf is set, ECX contains maximum
  2606                              <1> 	; available space and EAX contains the beginning address of it.
  2607                              <1> 	; If EAX has zero, ECX contains total number of free bytes.
  2608                              <1> 	; If requested block has been successfully allocated (by rounding up to
  2609                              <1> 	; the last page border), it must be deallocated later by using
  2610                              <1> 	; 'dealloacate_memory_block' procedure.    
  2611                              <1> 
  2612 000038FB 52                  <1> 	push	edx ; *
  2613 000038FC BAFF0F0000          <1> 	mov	edx, PAGE_SIZE - 1   ; 4095
  2614 00003901 01D1                <1> 	add	ecx, edx
  2615 00003903 01D0                <1> 	add	eax, edx
  2616 00003905 C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2617                              <1> 
  2618                              <1> 	; ECX = number of contiguous pages to be allocated
  2619 00003908 8B15[E0CE0000]      <1> 	mov	edx, [free_pages]
  2620 0000390E 39D1                <1> 	cmp	ecx, edx
  2621 00003910 7775                <1> 	ja	short amb_6
  2622                              <1> 
  2623 00003912 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; 12
  2624                              <1> 
  2625 00003915 89C2                <1> 	mov	edx, eax 	     ; page number
  2626 00003917 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2627                              <1> 				     ; (1 allocation bit = 1 page)
  2628                              <1> 				     ; (1 allocation bytes = 8 pages)
  2629 0000391A 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2630                              <1> 				     ; (to get 32 bit position)	
  2631 0000391D 53                  <1> 	push	ebx ; **
  2632                              <1> amb_0:
  2633 0000391E 890D[98DB0000]      <1> 	mov	[mem_ipg_count], ecx ; initial (reset) value of page count
  2634 00003924 890D[9CDB0000]      <1> 	mov	[mem_pg_count], ecx
  2635 0000392A 31C9                <1> 	xor	ecx, ecx ; 0
  2636 0000392C 890D[A0DB0000]      <1> 	mov	[mem_aperture], ecx ; 0
  2637 00003932 890D[A4DB0000]      <1> 	mov	[mem_max_aperture], ecx ; 0
  2638                              <1> 	
  2639 00003938 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address.
  2640 0000393D 3B15[E4CE0000]      <1> 	cmp	edx, [next_page]     ; Is the beginning page address lower
  2641                              <1> 				     ; than the address in 'next_page' ?
  2642                              <1> 				     ; (the first/next free page of user space)		
  2643 00003943 7208                <1> 	jb	short amb_1
  2644 00003945 3B15[E8CE0000]      <1> 	cmp 	edx, [last_page]     ; is the beginning page address higher
  2645                              <1> 				     ; than the address in 'last_page' ?
  2646                              <1> 				     ; (end of the memory)		
  2647 0000394B 7606                <1> 	jna	short amb_2	     ; no	
  2648                              <1> amb_1:
  2649 0000394D 8B15[E4CE0000]      <1> 	mov	edx, [next_page]     ; yes (reset to the first page of user space)
  2650                              <1> amb_2:
  2651 00003953 01D3                <1> 	add	ebx, edx
  2652                              <1> 
  2653 00003955 A3[A8DB0000]        <1> 	mov	[mem_pg_pos], eax    ; beginning page no (for curr. mem. aperture)
  2654 0000395A A3[ACDB0000]        <1>  	mov	[mem_max_pg_pos], eax ; beginning page no for max. mem. aperture
  2655                              <1> 
  2656 0000395F 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only (0 to 31)
  2657                              <1> 				     ; (allocation bit position)	 
  2658 00003962 744B                <1> 	jz	short amb_10	     ; 0	
  2659                              <1> amb_3:
  2660 00003964 8B13                <1> 	mov	edx, [ebx]
  2661 00003966 88C1                <1> 	mov	cl, al ; 1 to 31
  2662 00003968 D3EA                <1> 	shr	edx, cl
  2663 0000396A 89D0                <1> 	mov	eax, edx
  2664                              <1> amb_4:
  2665 0000396C D1E8                <1> 	shr	eax, 1 ; (***)
  2666 0000396E 7321                <1> 	jnc	short amb_7
  2667 00003970 FF05[A0DB0000]      <1> 	inc	dword [mem_aperture]
  2668 00003976 FF0D[9CDB0000]      <1> 	dec	dword [mem_pg_count]
  2669 0000397C 747B                <1> 	jz	short amb_15
  2670                              <1> amb_5:
  2671 0000397E 80F91F              <1> 	cmp	cl, 31
  2672 00003981 7317                <1> 	jnb	short amb_8
  2673 00003983 FEC1                <1> 	inc	cl
  2674 00003985 EBE5                <1> 	jmp	short amb_4
  2675                              <1> 
  2676                              <1> amb_6:	; out_of_memory
  2677 00003987 31C0                <1> 	xor	eax, eax ; 0
  2678 00003989 89D1                <1> 	mov	ecx, edx ; free pages
  2679 0000398B C1E10C              <1> 	shl	ecx, PAGE_SHIFT
  2680 0000398E 5A                  <1> 	pop	edx ; *
  2681 0000398F F9                  <1> 	stc
  2682 00003990 C3                  <1> 	retn
  2683                              <1> amb_7:
  2684 00003991 50                  <1> 	push	eax ; (***) allocation bits (in shifted status)
  2685 00003992 E819010000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2686 00003997 58                  <1> 	pop	eax ; (***)
  2687 00003998 EBE4                <1> 	jmp	short amb_5
  2688                              <1> amb_8:
  2689 0000399A 28C9                <1> 	sub	cl, cl ; 0
  2690                              <1> amb_9:
  2691 0000399C 89DA                <1> 	mov	edx, ebx
  2692 0000399E 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL
  2693 000039A4 3B15[E8CE0000]      <1> 	cmp	edx, [last_page]
  2694 000039AA 7336                <1> 	jnb	short amb_14 ; contiguous pages not enough
  2695 000039AC 83C304              <1> 	add	ebx, 4
  2696                              <1> amb_10:
  2697 000039AF 8B03                <1> 	mov	eax, [ebx]
  2698 000039B1 21C0                <1> 	and 	eax, eax
  2699 000039B3 7406                <1>         jz      short amb_11 ; there is not a free page bit in this alloc dword
  2700 000039B5 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0
  2701 000039B6 740A                <1> 	jz	short amb_12 ; all of bits are set (32 free pages)
  2702 000039B8 48                  <1> 	dec	eax
  2703 000039B9 EBB1                <1> 	jmp	short amb_4
  2704                              <1> amb_11:
  2705 000039BB E8F0000000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2706 000039C0 EBDA                <1> 	jmp	short amb_9	
  2707                              <1> amb_12:
  2708 000039C2 B120                <1> 	mov	cl, 32
  2709 000039C4 390D[9CDB0000]      <1> 	cmp	[mem_pg_count], ecx ; 32
  2710 000039CA 7306                <1> 	jnb	short amb_13
  2711 000039CC 8B0D[9CDB0000]      <1> 	mov	ecx, [mem_pg_count]
  2712                              <1> amb_13:
  2713 000039D2 010D[A0DB0000]      <1> 	add	[mem_aperture], ecx
  2714 000039D8 290D[9CDB0000]      <1> 	sub	[mem_pg_count], ecx
  2715 000039DE 7619                <1> 	jna	short amb_15
  2716 000039E0 EBB8                <1> 	jmp	short amb_8
  2717                              <1> amb_14:
  2718 000039E2 A1[ACDB0000]        <1> 	mov	eax, [mem_max_pg_pos] ; begin address of max. mem aperture	
  2719 000039E7 8B0D[A4DB0000]      <1> 	mov	ecx, [mem_max_aperture] ; max. (largest) memory aperture
  2720 000039ED C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2721 000039F0 C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2722 000039F3 F9                  <1> 	stc
  2723 000039F4 E9AC000000          <1>         jmp     amb_25
  2724                              <1> 
  2725                              <1> amb_15: ; OK !
  2726 000039F9 A1[A8DB0000]        <1> 	mov	eax, [mem_pg_pos]    ; Beginning address as page number
  2727 000039FE 8B0D[A0DB0000]      <1> 	mov	ecx, [mem_aperture]  ; Free contiguous page count
  2728                              <1> amb_16:
  2729                              <1> 	; allocate contiguous memory pages (via memory allocation table bits)
  2730 00003A04 89C2                <1> 	mov	edx, eax
  2731 00003A06 C1EA05              <1> 	shr	edx, 5 ; 32 pages in one allocation dword (32 bits)
  2732 00003A09 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2733 00003A0E 01D3                <1> 	add	ebx, edx
  2734 00003A10 83E01F              <1> 	and	eax, 1Fh ; 31
  2735                              <1> 	; 03/04/2016
  2736 00003A13 BA20000000          <1> 	mov	edx, 32
  2737 00003A18 28C2                <1> 	sub	dl, al
  2738 00003A1A 39CA                <1> 	cmp	edx, ecx
  2739 00003A1C 7602                <1> 	jna	short amb_17
  2740 00003A1E 89CA                <1> 	mov	edx, ecx
  2741                              <1> amb_17:
  2742 00003A20 29D1                <1> 	sub	ecx, edx
  2743 00003A22 51                  <1> 	push	ecx ; ***
  2744 00003A23 89D1                <1> 	mov	ecx, edx
  2745                              <1> amb_18:		
  2746 00003A25 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2747                              <1> 				 ; is copied into the Carry Flag and then cleared
  2748                              <1> 				 ; in the destination.
  2749 00003A28 FF0D[E0CE0000]      <1> 	dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2750 00003A2E 49                  <1> 	dec	ecx
  2751 00003A2F 7404                <1> 	jz	short amb_19
  2752 00003A31 FEC0                <1> 	inc	al
  2753 00003A33 EBF0                <1> 	jmp	short amb_18
  2754                              <1> amb_19:	
  2755 00003A35 59                  <1> 	pop	ecx ; ***
  2756 00003A36 21C9                <1> 	and	ecx, ecx ; 0 ?
  2757 00003A38 741E                <1> 	jz	short amb_22	
  2758                              <1> 	; 01/04/2016
  2759 00003A3A B020                <1> 	mov	al, 32
  2760                              <1> amb_20:
  2761 00003A3C 83C304              <1> 	add	ebx, 4
  2762 00003A3F 39C1                <1> 	cmp	ecx, eax ; 32
  2763 00003A41 7305                <1> 	jnb	short amb_21
  2764                              <1> 	; ECX < 32
  2765 00003A43 28C0                <1> 	sub	al, al ; 0
  2766 00003A45 50                  <1> 	push	eax ; 0 ***
  2767 00003A46 EBDD                <1> 	jmp	short amb_18
  2768                              <1> amb_21:
  2769 00003A48 2905[E0CE0000]      <1> 	sub	[free_pages], eax ; [free_pages] = [free_pages] - 32
  2770 00003A4E C70300000000        <1> 	mov	dword [ebx], 0 ; reset 32 bits
  2771 00003A54 29C1                <1> 	sub	ecx, eax ; 32
  2772 00003A56 75E4                <1> 	jnz	short amb_20
  2773                              <1> amb_22:
  2774 00003A58 A1[A8DB0000]        <1> 	mov	eax, [mem_pg_pos]   ; Beginning address as page number
  2775 00003A5D 8B0D[A0DB0000]      <1> 	mov	ecx, [mem_aperture] ; Free contiguous page count
  2776                              <1> 	; [next_page] update
  2777 00003A63 89C2                <1> 	mov	edx, eax
  2778                              <1> 	; 03/04/2016
  2779 00003A65 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2780                              <1> 				     ; (1 allocation bit = 1 page)
  2781                              <1> 				     ; (1 allocation bytes = 8 pages)
  2782 00003A68 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2783                              <1> 				     ; (to get 32 bit position)	
  2784 00003A6B 3B15[E4CE0000]      <1> 	cmp	edx, [next_page] ; first free page pointer offset
  2785 00003A71 7732                <1> 	ja	short amb_25
  2786 00003A73 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2787 00003A78 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2788 00003A7C 7721                <1> 	ja	short amb_24
  2789 00003A7E 89C2                <1> 	mov	edx, eax
  2790 00003A80 01CA                <1> 	add	edx, ecx
  2791 00003A82 C1EA03              <1> 	shr	edx, 3
  2792 00003A85 80E2FC              <1> 	and	dl, 0FCh
  2793                              <1> amb_23:
  2794 00003A88 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2795 00003A8C 7711                <1> 	ja	short amb_24
  2796 00003A8E 83C204              <1> 	add	edx, 4
  2797 00003A91 3B15[E8CE0000]      <1> 	cmp	edx, [last_page]    ; last page pointer offset
  2798 00003A97 76EF                <1> 	jna	short amb_23
  2799 00003A99 8B15[ECCE0000]      <1> 	mov	edx, [first_page]   ; (for) beginning of user's space
  2800                              <1> amb_24:
  2801 00003A9F 8915[E4CE0000]      <1> 	mov	[next_page], edx
  2802                              <1> amb_25:
  2803 00003AA5 9C                  <1> 	pushf
  2804 00003AA6 C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2805 00003AA9 C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2806 00003AAC 9D                  <1> 	popf
  2807 00003AAD 5B                  <1> 	pop	ebx ; **
  2808 00003AAE 5A                  <1> 	pop	edx ; *
  2809 00003AAF C3                  <1> 	retn
  2810                              <1> 
  2811                              <1> amb_26:	; set maximum free memory aperture (free memory block size) 
  2812 00003AB0 89DA                <1> 	mov	edx, ebx ; current address
  2813 00003AB2 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL ; MAT beginning address
  2814                              <1> 	; 02/04/2016 
  2815 00003AB8 C1E203              <1> 	shl	edx, 3 ; MAT byte offset * 8 = page number base
  2816 00003ABB 01CA                <1> 	add	edx, ecx ; current page number (ecx =  0 to 31)
  2817                              <1> 	;
  2818 00003ABD A1[A0DB0000]        <1> 	mov	eax, [mem_aperture]
  2819 00003AC2 21C0                <1> 	and	eax, eax
  2820 00003AC4 7424                <1>         jz      short amb_27
  2821 00003AC6 C705[A0DB0000]0000- <1>         mov     dword [mem_aperture], 0
  2821 00003ACE 0000                <1>
  2822 00003AD0 3B05[A4DB0000]      <1> 	cmp	eax, [mem_max_aperture]
  2823 00003AD6 7612                <1> 	jna	short amb_27
  2824 00003AD8 A3[A4DB0000]        <1> 	mov	[mem_max_aperture], eax
  2825                              <1> 	;
  2826 00003ADD 89D0                <1> 	mov	eax, edx
  2827 00003ADF 2B05[A4DB0000]      <1> 	sub	eax, [mem_max_aperture] ; the last aperture size in pages
  2828                              <1> 	; EAX = Beginning page number of the max. aperture 
  2829 00003AE5 A3[ACDB0000]        <1> 	mov	[mem_max_pg_pos], eax
  2830                              <1> amb_27: 
  2831 00003AEA 42                  <1> 	inc	edx	
  2832 00003AEB 8915[A8DB0000]      <1> 	mov	[mem_pg_pos], edx ; next page
  2833                              <1> 
  2834 00003AF1 A1[98DB0000]        <1> 	mov	eax, [mem_ipg_count] ; initial (reset) value of page count
  2835 00003AF6 A3[9CDB0000]        <1> 	mov	[mem_pg_count], eax
  2836                              <1> 
  2837 00003AFB C3                  <1> 	retn
  2838                              <1> 
  2839                              <1> deallocate_memory_block:
  2840                              <1> 	; 03/04/2016
  2841                              <1> 	; 14/03/2016 (TRDOS 386 = TRDOS v2.0)
  2842                              <1> 	; Deallocating contiguous memory pages (in the kernel's memory space)
  2843                              <1> 	;
  2844                              <1> 	; INPUT -> 
  2845                              <1> 	;	EAX = Beginning address (physical)
  2846                              <1> 	;	ECX = Number of bytes to be deallocated
  2847                              <1> 	;
  2848                              <1> 	; OUTPUT ->
  2849                              <1> 	;	Mememory Allocation Table bits will be updated
  2850                              <1> 	;	[free_pages] will be changed (increased)
  2851                              <1> 	;
  2852                              <1> 	; (Modified Registers -> EAX, ECX)
  2853                              <1> 	;
  2854                              <1> 	; PURPOSE: Unloading/Freeing a file -or an allocated memory block- 
  2855                              <1> 	; at memory after copying, running, saving, reading, writing etc.
  2856                              <1> 	;
  2857                              <1> 
  2858 00003AFC 52                  <1> 	push	edx ; *
  2859 00003AFD 53                  <1> 	push	ebx ; **
  2860                              <1> 
  2861 00003AFE C1E80C              <1> 	shr	eax, PAGE_SHIFT	     ; 12
  2862 00003B01 C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2863                              <1> 
  2864                              <1> 	; EAX = Beginning page number
  2865                              <1> 	; ECX = Number of contiguous pages to be deallocated
  2866                              <1> damb_0:
  2867                              <1> 	; deallocate contiguous memory pages (via memory allocation table bits)
  2868 00003B04 89C2                <1> 	mov	edx, eax
  2869 00003B06 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2870                              <1> 				     ; (1 allocation bit = 1 page)
  2871                              <1> 				     ; (1 allocation bytes = 8 pages)
  2872 00003B09 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2873                              <1> 				     ; (to get 32 bit position)	
  2874 00003B0C 3B15[E4CE0000]      <1> 	cmp	edx, [next_page] ; next free page
  2875 00003B12 7306                <1> 	jnb	short damb_1
  2876 00003B14 8915[E4CE0000]      <1> 	mov	[next_page], edx
  2877                              <1> damb_1:
  2878 00003B1A BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2879 00003B1F 01D3                <1> 	add	ebx, edx
  2880 00003B21 83E01F              <1> 	and	eax, 1Fh ; 31
  2881                              <1> 
  2882                              <1> 	; 03/04/2016
  2883 00003B24 BA20000000          <1> 	mov	edx, 32
  2884 00003B29 28C2                <1> 	sub	dl, al
  2885 00003B2B 39CA                <1> 	cmp	edx, ecx
  2886 00003B2D 7602                <1> 	jna	short damb_2
  2887 00003B2F 89CA                <1> 	mov	edx, ecx
  2888                              <1> damb_2:
  2889 00003B31 29D1                <1> 	sub	ecx, edx
  2890 00003B33 51                  <1> 	push	ecx ; ***
  2891 00003B34 89D1                <1> 	mov	ecx, edx
  2892                              <1> damb_3:		
  2893 00003B36 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
  2894                              <1> 				     ; set relevant bit to 1.
  2895                              <1> 				     ; set CF to the previous bit value	
  2896 00003B39 FF05[E0CE0000]      <1> 	inc     dword [free_pages]   ; 1 page has been deallocated (X = X+1) 
  2897 00003B3F 49                  <1> 	dec	ecx
  2898 00003B40 7404                <1> 	jz	short damb_4
  2899 00003B42 FEC0                <1> 	inc	al
  2900 00003B44 EBF0                <1> 	jmp	short damb_3
  2901                              <1> damb_4:	
  2902 00003B46 59                  <1> 	pop	ecx ; ***
  2903 00003B47 21C9                <1> 	and	ecx, ecx ; 0 ?
  2904 00003B49 741E                <1> 	jz	short damb_7
  2905                              <1> 	; 03/04/2016
  2906 00003B4B B020                <1> 	mov	al, 32
  2907                              <1> damb_5:
  2908 00003B4D 83C304              <1> 	add	ebx, 4
  2909 00003B50 39C1                <1> 	cmp	ecx, eax ; 32
  2910 00003B52 7305                <1> 	jnb	short damb_6
  2911                              <1> 	; ECX < 32
  2912 00003B54 28C0                <1> 	sub	al, al ; 0
  2913 00003B56 50                  <1> 	push	eax ; 0 ***
  2914 00003B57 EBDD                <1> 	jmp	short damb_3
  2915                              <1> damb_6:
  2916 00003B59 0105[E0CE0000]      <1> 	add	[free_pages], eax ; [free_pages] = [free_pages] + 32
  2917 00003B5F C703FFFFFFFF        <1> 	mov	dword [ebx], 0FFFFFFFFh ; set 32 bits
  2918 00003B65 29C1                <1> 	sub	ecx, eax ; 32
  2919 00003B67 75E4                <1> 	jnz	short damb_5
  2920                              <1> damb_7:
  2921 00003B69 5B                  <1> 	pop	ebx ; **
  2922 00003B6A 5A                  <1> 	pop	edx ; *
  2923 00003B6B C3                  <1> 	retn
  2924                              <1> 
  2925                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  2926                              <1> 
  2927                              <1> ;; Data:
  2928                              <1> 
  2929                              <1> ; 09/03/2015
  2930                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  2931                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  2932                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2933                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2934                              <1> ;swpd_next:  dd 0 ; next free page block
  2935                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
  1921                                  %include 'timer.s'   ; 17/01/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - timer.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 17/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ;
    15                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
    16                              <1> ; ****************************************************************************
    17                              <1> 
    18                              <1> ; TRDOS 386  (TRDOS v2.0) Kernel - TIMER & REAL TIME CLOCK (BIOS) FUNCTIONS
    19                              <1> 
    20                              <1> ; IBM PC-AT BIOS Source Code ('BIOS2.ASM')
    21                              <1> ; TITLE BIOS2 ---- 06/10/85 BIOS INTERRUPT ROUTINES
    22                              <1> 
    23                              <1> ;
    24                              <1> ; ///////// TIMER (& REAL TIME CLOCK) FUNCTIONS ///////////////
    25                              <1> 
    26                              <1> int1Ah:
    27                              <1> 	; 29/01/2016
    28                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
    29 00003B6C 9C                  <1> 	pushfd
    30 00003B6D 0E                  <1> 	push 	cs
    31 00003B6E E801000000          <1> 	call 	TIME_OF_DAY_1
    32 00003B73 C3                  <1> 	retn
    33                              <1> 
    34                              <1> ;--- INT  1A H -- (TIME OF DAY) -------------------------------------------------
    35                              <1> ;       THIS BIOS ROUTINE ALLOWS THE CLOCKS TO BE SET OR READ			:
    36                              <1> ;										:
    37                              <1> ; PARAMETERS:									:
    38                              <1> ;     (AH) = 00H  READ THE CURRENT SETTING AND RETURN WITH,			:
    39                              <1> ;                      (CX) = HIGH PORTION OF COUNT				:
    40                              <1> ;                      (DX) = LOW PORTION OF COUNT				:
    41                              <1> ;                      (AL) = 0 TIMER HAS NOT PASSED 24 HOURS SINCE LAST READ	:
    42                              <1> ;                             1 IF ON ANOTHER DAY. (RESET TO ZERO AFTER READ)	:
    43                              <1> ;										:
    44                              <1> ;     (AH) = 01H  SET THE CURRENT CLOCK USING,					:
    45                              <1> ;		     (CX) = HIGH PORTION OF COUNT				:
    46                              <1> ;		     (DX) = LOW PORTION OF COUNT.				:
    47                              <1> ;										:
    48                              <1> ;               NOTE: COUNTS OCCUR AT THE RATE OF 1193180/65536 COUNTS/SECOND	:
    49                              <1> ;                            (OR ABOUT 18.2 PER SECOND -- SEE EQUATES)		:
    50                              <1> ;										:
    51                              <1> ;     (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,			:
    52                              <1> ;                      (CH) = HOURS IN BCD (00-23)				:
    53                              <1> ;                      (CL) = MINUTES IN BCD (00-59)				:
    54                              <1> ;                      (DH) = SECONDS IN BCD (00-59)				:
    55                              <1> ;                      (DL) = DAYLIGHT SAVINGS ENABLE (00-01)			:
    56                              <1> ;										:
    57                              <1> ;     (AH) = 03H  SET THE REAL TIME CLOCK USING,				:
    58                              <1> ;                     (CH) = HOURS IN BCD (00-23)				:
    59                              <1> ;                     (CL) = MINUTES IN BCD (00-59)				:
    60                              <1> ;                     (DH) = SECONDS IN BCD (00-59)				:
    61                              <1> ;                     (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.	:
    62                              <1> ;										:
    63                              <1> ;             NOTE: (DL) = 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED.	:
    64                              <1> ;                   (DL) = 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN	:
    65                              <1> ;	           APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN	:
    66                              <1> ;                   OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.		:
    67                              <1> ;										:
    68                              <1> ;     (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,	:
    69                              <1> ;                      (CH) = CENTURY IN BCD (19 OR 20)				:
    70                              <1> ;                      (CL) = YEAR IN BCD (00-99)				:
    71                              <1> ;                      (DH) = MONTH IN BCD (01-12)				:
    72                              <1> ;                      (DL) = DAY IN BCD (01-31).				:
    73                              <1> ;										:
    74                              <1> ;     (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING,			:
    75                              <1> ;                     (CH) = CENTURY IN BCD (19 OR 20)				:
    76                              <1> ;                     (CL) = YEAR IN BCD (00-99)				:
    77                              <1> ;                     (DH) = MONTH IN BCD (01-12)				:
    78                              <1> ;                     (DL) = DAY IN BCD (01-31).				:
    79                              <1> ;										:
    80                              <1> ;     (AH) = 06H  SET THE ALARM TO INTERRUPT AT SPECIFIED TIME,			:
    81                              <1> ;                     (CH) = HOURS IN BCD (00-23 (OR FFH))			:
    82                              <1> ;                     (CL) = MINUTES IN BCD (00-59 (OR FFH))			:
    83                              <1> ;                     (DH) = SECONDS IN BCD (00-59 (OR FFH))			:
    84                              <1> ;										:
    85                              <1> ;     (AH) = 07H  RESET THE ALARM INTERRUPT FUNCTION.				:
    86                              <1> ;										:
    87                              <1> ; NOTES: FOR ALL RETURNS CY= 0 FOR SUCCESSFUL OPERATION.			:
    88                              <1> ;        FOR (AH)= 2, 4, 6 - CARRY FLAG SET IF REAL TIME CLOCK NOT OPERATING.	:
    89                              <1> ;        FOR (AH)= 6 - CARRY FLAG SET IF ALARM ALREADY ENABLED. 		:
    90                              <1> ;        FOR THE ALARM FUNCTION (AH = 6) THE USER MUST SUPPLY A ROUTINE AND	:
    91                              <1> ;         INTERCEPT THE CORRECT ADDRESS IN THE VECTOR TABLE FOR INTERRUPT 4AH.	:
    92                              <1> ;         USE 0FFH FOR ANY "DO NOT CARE" POSITION FOR INTERVAL INTERRUPTS.	:
    93                              <1> ;        INTERRUPTS ARE DISABLED DURING DATA MODIFICATION. 			:
    94                              <1> ;        AH & AL ARE RETURNED MODIFIED AND NOT DEFINED EXCEPT WHERE INDICATED.	:
    95                              <1> ;--------------------------------------------------------------------------------
    96                              <1> 
    97                              <1> ; 29/01/2016
    98                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
    99                              <1> 
   100                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   101                              <1> int35h:  ; Date/Time functions
   102                              <1> 
   103                              <1> TIME_OF_DAY_1:
   104 00003B74 FB                  <1> 	sti				; INTERRUPTS BACK ON
   105 00003B75 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   106 00003B78 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   107 00003B79 721A                <1> 	jc	short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   108                              <1> 
   109 00003B7B 1E                  <1> 	push	ds
   110 00003B7C 56                  <1> 	push	esi
   111 00003B7D 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   112 00003B81 8EDE                <1> 	mov	ds, si
   113 00003B83 C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   114 00003B86 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   115 00003B89 FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   116 00003B8A FF96[983B0000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   117                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   118 00003B90 FB                  <1> 	sti				; INTERRUPTS BACK ON
   119 00003B91 B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   120 00003B93 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   121 00003B94 1F                  <1> 	pop	ds			; RECOVER USERS SEGMENT SELECTOR
   122                              <1> TIME_9:					; RETURN WITH CY= 0 IF NO ERROR
   123 00003B95 CA0400              <1> 	retf	4
   124                              <1> 					; ROUTINE VECTOR TABLE (AH)=
   125                              <1> RTC_TB:
   126 00003B98 [B83B0000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   127 00003B9C [CB3B0000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   128 00003BA0 [D93B0000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   129 00003BA4 [083C0000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   130 00003BA8 [4A3C0000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   131 00003BAC [773C0000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   132 00003BB0 [C43C0000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   133 00003BB4 [173D0000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   134                              <1> 
   135                              <1> RTC_TBE	equ	$
   136                              <1> 
   137                              <1> RTC_00:				; READ TIME COUNT
   138 00003BB8 A0[60CF0000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   139 00003BBD C605[60CF0000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   140 00003BC4 8B0D[5CCF0000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   141 00003BCA C3                  <1> 	retn
   142                              <1> 
   143                              <1> RTC_10:				; SET TIME COUNT
   144 00003BCB 890D[5CCF0000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   145 00003BD1 C605[60CF0000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   146 00003BD8 C3                  <1> 	retn				; RETURN WITH NO CARRY
   147                              <1> 
   148                              <1> RTC_20:				; GET RTC TIME
   149 00003BD9 E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   150 00003BDE 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   151                              <1> 
   152 00003BE0 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   153 00003BE2 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   154 00003BE7 88C6                <1> 	mov	dh, al			; SAVE
   155 00003BE9 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   156 00003BEB E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   157 00003BF0 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   158 00003BF2 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   159 00003BF4 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   160 00003BF6 E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   161 00003BFB 88C1                <1> 	mov	cl, al			; SAVE
   162 00003BFD B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   163 00003BFF E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   164 00003C04 88C5                <1> 	mov	ch, al			; SAVE
   165 00003C06 F8                  <1> 	clc				; SET CY= 0
   166                              <1> RTC_29:
   167 00003C07 C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   168                              <1> 
   169                              <1> RTC_30:				; SET RTC TIME
   170 00003C08 E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   171 00003C0D 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   172 00003C0F E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   173                              <1> RTC_35:
   174 00003C14 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   175 00003C16 B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   176 00003C18 E8DF010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   177 00003C1D 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   178 00003C1F B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   179 00003C21 E8D6010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   180 00003C26 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   181 00003C28 B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   182 00003C2A E8CD010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   183                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   184                              <1> 	;mov	ah, al
   185 00003C2F 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   186 00003C33 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   187 00003C38 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   188 00003C3A 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   189 00003C3C 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   190 00003C3F 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   191 00003C41 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   192 00003C43 E8B4010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   193 00003C48 F8                  <1> 	clc				; SET CY= 0
   194 00003C49 C3                  <1> 	retn				; RETURN WITH CY= 0
   195                              <1> 
   196                              <1> RTC_40:				; GET RTC DATE
   197 00003C4A E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   198 00003C4F 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   199                              <1> 
   200 00003C51 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   201 00003C53 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   202 00003C58 88C2                <1> 	mov	dl, al			; SAVE
   203 00003C5A B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   204 00003C5C E883010000          <1> 	call	CMOS_READ		; READ MONTH
   205 00003C61 88C6                <1> 	mov	dh, al			; SAVE
   206 00003C63 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   207 00003C65 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   208 00003C6A 88C1                <1> 	mov	cl, al			; SAVE
   209 00003C6C B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   210 00003C6E E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   211 00003C73 88C5                <1> 	mov	ch, al			; SAVE
   212 00003C75 F8                  <1> 	clc				; SET CY=0
   213                              <1> RTC_49:
   214 00003C76 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   215                              <1> 
   216                              <1> RTC_50:				; SET RTC DATE
   217 00003C77 E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   218 00003C7C 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   219 00003C7E E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   220                              <1> RTC_55:
   221 00003C83 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   222 00003C87 E870010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   223 00003C8C 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   224 00003C8E B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   225 00003C90 E867010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   226 00003C95 88F4                <1> 	mov	ah, dh			; GET MONTH
   227 00003C97 B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   228 00003C99 E85E010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   229 00003C9E 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   230 00003CA0 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   231 00003CA2 E855010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   232 00003CA7 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   233 00003CA9 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   234 00003CAB E84C010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   235                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   236                              <1> 	;mov	ah, al
   237 00003CB0 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   238 00003CB4 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   239 00003CB9 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   240 00003CBB 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   241 00003CBD E83A010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   242 00003CC2 F8                  <1> 	clc				; SET CY= 0
   243 00003CC3 C3                  <1> 	retn				; RETURN CY=0
   244                              <1> 
   245                              <1> RTC_60:				; SET RTC ALARM
   246 00003CC4 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   247 00003CC6 E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   248 00003CCB A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   249 00003CCD F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   250 00003CCE 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   251 00003CD0 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   252 00003CD5 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   253 00003CD7 E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   254                              <1> RTC_65:	
   255 00003CDC 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   256 00003CDE B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   257 00003CE0 E817010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   258 00003CE5 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   259 00003CE7 B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   260 00003CE9 E80E010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   261 00003CEE 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   262 00003CF0 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   263 00003CF2 E805010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   264 00003CF7 E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   265 00003CF9 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   266 00003CFB E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   267                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   268                              <1> 	;mov	ah, al
   269 00003CFD 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   270 00003D01 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   271 00003D06 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   272 00003D08 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   273 00003D0A 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   274 00003D0C E8EB000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   275 00003D11 F8                  <1> 	clc				; SET CY= 0
   276                              <1> RTC_69:
   277 00003D12 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   278 00003D16 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAC
   279                              <1> 
   280                              <1> RTC_70:				; RESET ALARM
   281                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   282                              <1> 	;mov	ah, al
   283 00003D17 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   284 00003D1B E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   285 00003D20 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   286 00003D22 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   287 00003D24 E8D3000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   288 00003D29 F8                  <1> 	clc				; SET CY= 0
   289 00003D2A C3                  <1> 	retn				; RETURN WITH NO CARRY
   290                              <1> 
   291                              <1> RTC_STA:			; INITIALIZE REAL TIME CLOCK
   292                              <1> 	;mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK		
   293                              <1> 	;mov	ah, 26h
   294 00003D2B 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   295 00003D2F E8C8000000          <1> 	call	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
   296                              <1> 	;mov	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION	
   297                              <1> 	;mov	ah, 82h
   298 00003D34 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   299 00003D38 E8BF000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   300 00003D3D B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   301 00003D3F E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   302 00003D44 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   303 00003D46 E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   304 00003D4B C3                  <1> 	retn
   305                              <1> 
   306                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   307                              <1> 
   308                              <1> ;--- HARDWARE INT  70 H -- ( IRQ LEVEL  8) --------------------------------------
   309                              <1> ; ALARM INTERRUPT HANDLER (RTC)							:
   310                              <1> ;       THIS ROUTINE HANDLES THE PERIODIC AND ALARM INTERRUPTS FROM THE CMOS	:
   311                              <1> ;       TIMER. INPUT FREQUENCY IS 1.024 KHZ OR APPROXIMATELY 1024 INTERRUPTS	:
   312                              <1> ;       EVERY SECOND FOR THE PERIODIC INTERRUPT. FOR THE ALARM FUNCTION,	:
   313                              <1> ;       THE INTERRUPT WILL OCCUR AT THE DESIGNATED TIME.			:
   314                              <1> ;										:
   315                              <1> ;       INTERRUPTS ARE ENABLED WHEN THE EVENT OR ALARM FUNCTION IS ACTIVATED.	:
   316                              <1> ;       FOR THE EVENT INTERRUPT, THE HANDLER WILL DECREMENT THE WAIT COUNTER	:
   317                              <1> ;       AND WHEN IT EXPIRES WILL SET THE DESIGNATED LOCATION TO 80H. FOR	:
   318                              <1> ;       THE ALARM INTERRUPT. THE USER MUST PROVIDE A ROUTINE TO INTERCEPT	:
   319                              <1> ;       THE CORRECT ADDRESS FROM THE VECTOR TABLE INVOKED BY INTERRUPT 4AH	:
   320                              <1> ;       PRIOR TO SETTING THE REAL TIME CLOCK ALARM (INT 1AH, AH= 06H).		:
   321                              <1> ;--------------------------------------------------------------------------------
   322                              <1> 
   323                              <1> RTC_INT:			; ALARM INTERRUPT
   324 00003D4C 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   325 00003D4D 50                  <1> 	push	eax			; SAVE REGISTERS
   326 00003D4E 57                  <1> 	push	edi
   327                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   328 00003D4F 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   329 00003D53 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   330 00003D55 90                  <1> 	nop				; I/O DELAY
   331 00003D56 EB00                <1> 	jmp	short $+2
   332 00003D58 E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   333 00003D5A A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   334 00003D5C 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   335                              <1> 
   336 00003D5E 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   337 00003D60 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   338 00003D62 90                  <1> 	nop				; I/O DELAY
   339 00003D63 EB00                <1> 	jmp	short $+2	
   340 00003D65 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   341 00003D67 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   342 00003D69 A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   343 00003D6B 743B                <1> 	jz	short RTC_I_5		; SKIP IF NOT A PERIODIC INTERRUPT
   344                              <1> 
   345                              <1> ;-----	DECREMENT WAIT COUNT BY INTERRUPT INTERVAL
   346                              <1> 
   347 00003D6D 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   348 00003D71 8EDF                <1> 	mov	ds, di
   349                              <1> 	
   350 00003D73 812D[56CF0000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   350 00003D7B 0000                <1>
   351 00003D7D 7329                <1> 	jnc	short RTC_I_5		; SKIP TILL 32 BIT WORD LESS THAN ZERO
   352                              <1> 
   353                              <1> ;-----	TURN OFF PERIODIC INTERRUPT ENABLE
   354                              <1> 
   355 00003D7F 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   356 00003D81 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   357 00003D85 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   358 00003D87 90                  <1> 	nop				; I/O DELAY
   359 00003D88 EB00                <1> 	jmp	short $+2
   360 00003D8A E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   361 00003D8C 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   362 00003D8E 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   363 00003D90 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   364 00003D92 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   365 00003D94 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   366 00003D96 C605[5ACF0000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   367 00003D9D 8B3D[5BCF0000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   368 00003DA3 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   369 00003DA6 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   370                              <1> RTC_I_5:
   371 00003DA8 A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   372 00003DAA 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   373                              <1> 
   374 00003DAC B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   375 00003DAE E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   376 00003DB0 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   377 00003DB1 52                  <1> 	push	edx
   378 00003DB2 E8E87D0000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   379 00003DB7 5A                  <1> 	pop	edx
   380 00003DB8 FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   381                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   382 00003DB9 EB94                <1> 	jmp	short RTC_I_1		;  ENTRY AND SECOND EVENT BEFORE DONE
   383                              <1> 
   384                              <1> RTC_I_9:				; EXIT - NO PENDING INTERRUPTS
   385 00003DBB B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   386 00003DBD E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   387 00003DBF B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   388 00003DC1 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   389 00003DC3 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   390 00003DC5 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   391 00003DC6 58                  <1> 	pop	eax
   392 00003DC7 1F                  <1> 	pop	ds
   393 00003DC8 CF                  <1> 	iret				; END OF INTERRUPT
   394                              <1> 
   395                              <1> 
   396                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   397                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
   398                              <1> UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
   399 00003DC9 51                  <1> 	push	ecx
   400 00003DCA B9FFFF0000          <1> 	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
   401                              <1> 		; mov cx, 800	
   402                              <1> UPD_10:
   403 00003DCF B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   404 00003DD1 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   405 00003DD2 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   406 00003DD7 A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   407 00003DD9 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   408 00003DDB FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   409 00003DDC E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   410 00003DDE 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   411                              <1> 		; xor ax, ax
   412 00003DE0 F9                  <1> 	stc				; SET CARRY FOR ERROR
   413                              <1> UPD_90:
   414 00003DE1 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   415 00003DE2 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   416 00003DE3 C3                  <1> 	retn				; RETURN WITH CY FLAG SET
   417                              <1> 
   418                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   419                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
   420                              <1> 
   421                              <1> ;--- CMOS_READ -----------------------------------------------------------------
   422                              <1> ;		READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE	       :
   423                              <1> ;									       :
   424                              <1> ; INPUT: (AL)=	CMOS_TABLE ADDRESS TO BE READ				       :
   425                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   426                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ		       :
   427                              <1> ;									       :
   428                              <1> ; OUTPUT: (AL)	VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS   :
   429                              <1> ;		ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND   :
   430                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   431                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   432                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   433                              <1> ;		ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED.	       :
   434                              <1> ;-------------------------------------------------------------------------------
   435                              <1> 
   436                              <1> CMOS_READ:
   437 00003DE4 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   438 00003DE5 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   439 00003DE7 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   440 00003DE8 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   441 00003DEA FA                  <1> 	cli				; DISABLE INTERRUPTS
   442 00003DEB E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   443 00003DED 90                  <1> 	nop				; I/O DELAY
   444 00003DEE E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   445 00003DF0 6650                <1> 	push	ax			; SAVE (AH) REGISTER VALUE AND CMOS BYTE
   446                              <1> 	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
   447                              <1> 		     ; ----- 10/06/85 (test4.asm)
   448 00003DF2 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
   449                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   450 00003DF4 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   451 00003DF6 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   452 00003DF8 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   453 00003DFA 9D                  <1> 	popf	
   454 00003DFB C3                  <1> 	retn				; RETURN WITH FLAGS RESTORED
   455                              <1> 
   456                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   457                              <1> 
   458                              <1> ;--- CMOS_WRITE ----------------------------------------------------------------
   459                              <1> ;	WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE		       :
   460                              <1> ;									       :
   461                              <1> ; INPUT: (AL)=	CMOS TABLE ADDRESS TO BE WRITTEN TO			       :
   462                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   463                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE		       :
   464                              <1> ;	 (AH)=	NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION	       :
   465                              <1> ;									       :
   466                              <1> ; OUTPUT:	VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED   :
   467                              <1> ;		IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND    :
   468                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   469                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   470                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   471                              <1> ;		ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED.	       :
   472                              <1> ;-------------------------------------------------------------------------------
   473                              <1> 
   474                              <1> CMOS_WRITE:				; WRITE (AH) TO LOCATION (AL)
   475 00003DFC 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   476 00003DFD 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   477 00003DFF D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   478 00003E01 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   479 00003E02 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   480 00003E04 FA                  <1> 	cli				; DISABLE INTERRUPTS
   481 00003E05 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   482 00003E07 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   483 00003E09 E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   484 00003E0B B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2	; GET ADDRESS OF DEFAULT LOCATION
   485                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   486 00003E0D D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   487 00003E0F E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   488 00003E11 90                  <1> 	nop				; I/O DELAY
   489 00003E12 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   490 00003E14 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   491 00003E16 9D                  <1> 	popf
   492 00003E17 C3                  <1> 	retn
   493                              <1> 
   494                              <1> ; /// End Of TIMER FUNCTIONS ///
  1922                                  %include 'sysdefs.s' ; 24/01/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYSTEM DEFINITIONS : sysdefs.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    11                              <1> ; sysdefs.inc (14/11/2015)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
    15                              <1> ; Last Modification: 14/11/2015
    16                              <1> ;
    17                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
    18                              <1> ; (Modified from 
    19                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
    20                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
    21                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
    22                              <1> ; ----------------------------------------------------------------------------
    23                              <1> ;
    24                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    25                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
    26                              <1> ; <Bell Laboratories (17/3/1972)>
    27                              <1> ; <Preliminary Release of UNIX Implementation Document>
    28                              <1> ;
    29                              <1> ; ****************************************************************************
    30                              <1> 
    31                              <1> nproc 	equ	16  ; number of processes
    32                              <1> nfiles 	equ	50
    33                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
    34                              <1> nbuf	equ	4   ; 6 ;; 21/08/2015 - 'namei' buffer problem when nbuf > 4 	
    35                              <1> 		; NOTE: If fd0 super block buffer addres is beyond of the 1st
    36                              <1> 		; 32K, DMA r/w routine or someting else causes a jump to 
    37                              <1> 		; kernel panic routine (in 'alloc' routine, in u5.s)
    38                              <1> 		; because of invalid buffer content (r/w error). 
    39                              <1> 		; When all buffers are set before the end of the 1st 32k,
    40                              <1> 		; there is no problem!? (14/11/2015) 
    41                              <1> 
    42                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
    43                              <1> ;core	equ 	0  	    ; 19/04/2013	
    44                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
    45                              <1> 	; (if total size of argument list and arguments is 128 bytes)
    46                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
    47                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
    48                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
    49                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
    50                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
    51                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
    52                              <1> 	; '/core' dump file size = 32768 bytes
    53                              <1>  
    54                              <1> ; 08/03/2014 
    55                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
    56                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
    57                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
    58                              <1> 
    59                              <1> ; 30/08/2013
    60                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
    61                              <1> 
    62                              <1> ; 05/02/2014
    63                              <1> ; process status
    64                              <1> ;SFREE 	equ 0
    65                              <1> ;SRUN	equ 1
    66                              <1> ;SWAIT	equ 2
    67                              <1> ;SZOMB	equ 3
    68                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
    69                              <1> 
    70                              <1> ; 09/03/2015
    71                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
    72                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
    73                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
    74                              <1> 
    75                              <1> ; 17/09/2015
    76                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
    77                              <1> 
    78                              <1> ; 21/09/2015 (36) 
    79                              <1> ; 01/07/2015 (35)
    80                              <1> ; 14/07/2013 (0-34)
    81                              <1> ; UNIX v1 system calls
    82                              <1> _rele 	equ 0
    83                              <1> _exit 	equ 1
    84                              <1> _fork 	equ 2
    85                              <1> _read 	equ 3
    86                              <1> _write	equ 4
    87                              <1> _open	equ 5
    88                              <1> _close 	equ 6
    89                              <1> _wait 	equ 7
    90                              <1> _creat 	equ 8
    91                              <1> _link 	equ 9
    92                              <1> _unlink	equ 10
    93                              <1> _exec	equ 11
    94                              <1> _chdir	equ 12
    95                              <1> _time 	equ 13
    96                              <1> _mkdir 	equ 14
    97                              <1> _chmod	equ 15
    98                              <1> _chown	equ 16
    99                              <1> _break	equ 17
   100                              <1> _stat	equ 18
   101                              <1> _seek	equ 19
   102                              <1> _tell 	equ 20
   103                              <1> _mount	equ 21
   104                              <1> _umount	equ 22
   105                              <1> _setuid	equ 23
   106                              <1> _getuid	equ 24
   107                              <1> _stime	equ 25
   108                              <1> _quit	equ 26	
   109                              <1> _intr	equ 27
   110                              <1> _fstat	equ 28
   111                              <1> _emt 	equ 29
   112                              <1> _mdate 	equ 30
   113                              <1> _stty 	equ 31
   114                              <1> _gtty	equ 32
   115                              <1> _ilgins	equ 33
   116                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
   117                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
   118                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
   119                              <1> 
   120                              <1> %macro sys 1-4
   121                              <1>     ; 13/04/2015
   122                              <1>     ; Retro UNIX 386 v1 system call.		
   123                              <1>     mov eax, %1
   124                              <1>     %if %0 >= 2   
   125                              <1>         mov ebx, %2
   126                              <1>         %if %0 >= 3    
   127                              <1>             mov ecx, %3
   128                              <1>             %if %0 = 4
   129                              <1>                mov edx, %4   
   130                              <1>             %endif
   131                              <1>         %endif
   132                              <1>     %endif
   133                              <1>     int 30h	   
   134                              <1> %endmacro
   135                              <1> 
   136                              <1> ; 13/05/2015 - ERROR CODES
   137                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
   138                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
   139                              <1> ; 14/05/2015
   140                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
   141                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
   142                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
   143                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
   144                              <1> ; 16/05/2015		
   145                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
   146                              <1> ; 18/05/2015
   147                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
   148                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
   149                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
   150                              <1> ; 07/06/2015
   151                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
   152                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
   153                              <1> ; 09/06/2015
   154                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
   155                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
   156                              <1> ; 16/06/2015
   157                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
   158                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
   159                              <1> ; 22/06/2015
   160                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
   161                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
   162                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
   163                              <1> ; 23/06/2015
   164                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
   165                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
   166                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
   167                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
   168                              <1> ; 27/06/2015
   169                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
   170                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
   171                              <1> ; 29/06/2015
   172                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
   173                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
   174                              <1> 
   175                              <1> ; 26/08/2015
   176                              <1> ; 24/07/2015
   177                              <1> ; 24/06/2015
   178                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
   179                              <1> ; 01/07/2015
   180                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
   181                              <1> ;	 					 		
  1923                                  %include 'trdosk0.s' ; 04/01/2016 
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DEFINITIONS : trdosk0.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; TRDOS2.ASM (c) 2004-2011 Erdogan TAN [ 17/01/2004 ] Last Update: 09/11/2011
    14                              <1> ;
    15                              <1> ; Masterboot / Partition Table at Beginning+1BEh
    16                              <1> ptBootable       equ 0
    17                              <1> ptBeginHead      equ 1
    18                              <1> ptBeginSector    equ 2
    19                              <1> ptBeginCylinder  equ 3
    20                              <1> ptFileSystemID   equ 4
    21                              <1> ptEndHead        equ 5
    22                              <1> ptEndSector      equ 6
    23                              <1> ptEndCylinder    equ 7
    24                              <1> ptStartSector    equ 8
    25                              <1> ptSectors        equ 12
    26                              <1> 
    27                              <1> ; Boot Sector Parameters at 7C00h
    28                              <1> DataArea1     equ -4
    29                              <1> DataArea2     equ -2
    30                              <1> BootStart     equ 0h
    31                              <1> OemName       equ 03h
    32                              <1> BytesPerSec   equ 0Bh
    33                              <1> SecPerClust   equ 0Dh
    34                              <1> ResSectors    equ 0Eh
    35                              <1> FATs          equ 10h
    36                              <1> RootDirEnts   equ 11h
    37                              <1> Sectors       equ 13h
    38                              <1> Media         equ 15h
    39                              <1> FATSecs       equ 16h
    40                              <1> SecPerTrack   equ 18h
    41                              <1> Heads         equ 1Ah 
    42                              <1> Hidden1       equ 1Ch
    43                              <1> Hidden2       equ 1Eh
    44                              <1> HugeSec1      equ 20h
    45                              <1> HugeSec2      equ 22h
    46                              <1> DriveNumber   equ 24h
    47                              <1> Reserved1     equ 25h
    48                              <1> bootsignature equ 26h                 
    49                              <1> VolumeID      equ 27h
    50                              <1> VolumeLabel   equ 2Bh
    51                              <1> FileSysType   equ 36h          
    52                              <1> Reserved2     equ 3Eh                           ; Starting cluster of P2000
    53                              <1> 
    54                              <1> ; FAT32 BPB Structure
    55                              <1> FAT32_FAT_Size equ 36
    56                              <1> FAT32_RootFClust equ 44
    57                              <1> FAT32_FSInfoSec equ 48
    58                              <1> FAT32_DrvNum equ 64
    59                              <1> FAT32_BootSig equ 66
    60                              <1> FAT32_VolID equ 67
    61                              <1> FAT32_VolLab equ 71
    62                              <1> FAT32_FilSysType equ 82
    63                              <1> 
    64                              <1> ; BIOS Disk Parameters
    65                              <1> DPDiskNumber  equ 0h
    66                              <1> DPDType       equ 1h
    67                              <1> DPReturn      equ 2h
    68                              <1> DPHeads       equ 3h
    69                              <1> DPCylinders   equ 4h
    70                              <1> DPSecPerTrack equ 6h
    71                              <1> DPDisks       equ 7h
    72                              <1> DPTableOff    equ 8h
    73                              <1> DPTableSeg    equ 0Ah
    74                              <1> DPNumOfSecs   equ 0Ch
    75                              <1> 
    76                              <1> ; BIOS INT 13h Extensions (LBA extensions)
    77                              <1> ; Just After DP Data (DPDiskNumber+)
    78                              <1> DAP_PacketSize equ 10h  ; If extensions present, this byte will be >=10h
    79                              <1> DAP_Reserved1 equ 11h   ; Reserved Byte 
    80                              <1> DAP_NumOfBlocks equ 12h ; Value of this byte must be 0 to 127
    81                              <1> DAP_Reserved2 equ 13h   ; Reserved Byte
    82                              <1> DAP_Destination equ 14h ; Address of Transfer Buffer as SEGMENT:OFFSET
    83                              <1> DAP_LBA_Address equ 18h ; LBA=(C1*H0+H1)*S0+S1-1
    84                              <1>                         ; C1= Selected Cylinder Number
    85                              <1>                         ; H0= Number Of Heads (Maximum Head Number + 1)
    86                              <1>                         ; H1= Selected Head Number
    87                              <1>                         ; S0= Maximum Sector Number
    88                              <1>                         ; S1= Selected Sector Number
    89                              <1>                         ; QUAD WORD
    90                              <1> ; DAP_Flat_Destination equ 20h ; 64 bit address, if value in 4h is FFFF:FFFFh
    91                              <1>                              ; QUAD WORD (Also, value in 0h must be 18h) 
    92                              <1>                              ; TR-DOS will not use 64 bit Flat Address
    93                              <1> 
    94                              <1> ; INT 13h Function 48h "Get Enhanced Disk Drive Parameters"
    95                              <1> ; Just After DP Data (DPDiskNumber+)
    96                              <1> GetDParams_48h equ 20h ; Word. Data Length, must be 26 (1Ah) for short data.
    97                              <1> GDP_48h_InfoFlag equ 22h ; Word
    98                              <1> ; Bit 1 = 1 -> The geometry returned in bytes 4-15 is valid.
    99                              <1> GDP_48h_NumOfPCyls equ 24h ; Double Word. Number physical cylinders.
   100                              <1> GDP_48h_NumOfPHeads equ 28h ; Double Word. Number of physical heads.
   101                              <1> GDP_48h_NumOfPSpT equ 2Ch ; Double word. Num of physical sectors per track.
   102                              <1> GDP_48h_LBA_Sectors equ 30h ; 8 bytes. Number of physical/LBA sectors.
   103                              <1> GDP_48h_BytesPerSec equ 38h ; Word. Number of bytes in a sector.
   104                              <1> 
   105                              <1> ; TR-DOS Standalone Program Extensions to the DiskParams Block
   106                              <1> ; Just After DP Data (DPDiskNumber+)
   107                              <1> TRDP_CurrentSector equ 3Ah  ; DX:AX (LBA)
   108                              <1> TRDP_SectorCount equ 3Eh    ; CX (or Counter)
   109                              <1> 
   110                              <1> 
   111                              <1> ; DOS Logical Disks
   112                              <1> LD_Name equ 0
   113                              <1> LD_DiskType equ 1
   114                              <1> LD_PhyDrvNo equ 2
   115                              <1> LD_FATType equ 3
   116                              <1> LD_FSType equ 4
   117                              <1> LD_LBAYes equ 5
   118                              <1> LD_BPB equ 6
   119                              <1> LD_FATBegin equ 96
   120                              <1> LD_ROOTBegin equ 100
   121                              <1> LD_DATABegin equ 104
   122                              <1> LD_StartSector equ 108
   123                              <1> LD_TotalSectors equ 112
   124                              <1> LD_FreeSectors equ 116
   125                              <1> LD_Clusters equ 120
   126                              <1> LD_PartitionEntry equ 124
   127                              <1> LD_DParamEntry equ 125
   128                              <1> LD_MediaChanged equ 126
   129                              <1> LD_CDirLevel equ 127
   130                              <1> LD_CurrentDirectory equ 128
   131                              <1> 
   132                              <1> ; Singlix FS Extensions to DOS Logical Disks
   133                              <1> ; 03/01/2010 (LD_BPB compatibility for CHS r/w)
   134                              <1> 
   135                              <1> LD_FS_Name equ 0
   136                              <1> LD_FS_DiskType equ 1
   137                              <1> LD_FS_PhyDrvNo equ 2
   138                              <1> LD_FS_FATType equ 3
   139                              <1> LD_FS_FSType equ 4
   140                              <1> LD_FS_LBAYes equ 5
   141                              <1> LD_FS_BPB equ 6
   142                              <1> LD_FS_MediaAttrib equ 6
   143                              <1> LD_FS_VersionMajor equ 7
   144                              <1> LD_FS_RootDirD equ 8
   145                              <1> LD_FS_MATLocation equ 12
   146                              <1> LD_FS_Reserved1 equ 16 ;1 reserved byte
   147                              <1> LD_FS_BytesPerSec equ 17 ; LD_BPB + 0Bh
   148                              <1> LD_FS_Reserved2 equ 19 ;2 reserved byte
   149                              <1> LD_FS_DATLocation equ 20
   150                              <1> LD_FS_DATSectors equ 24
   151                              <1> LD_FS_Reserved3 equ 28 ;3 reserved word
   152                              <1> LD_FS_SecPerTrack equ 30 ; LD_BPB + 18h
   153                              <1> LD_FS_NumHeads equ 32    ; LD_BPB + 1Ah
   154                              <1> LD_FS_UnDelDirD equ 34
   155                              <1> LD_FS_Reserved4 equ 38 ;4 reserved word
   156                              <1> LD_FS_VolumeSerial equ 40
   157                              <1> LD_FS_VolumeName equ 44
   158                              <1> LD_FS_BeginSector equ 108
   159                              <1> LD_FS_VolumeSize equ 112
   160                              <1> LD_FS_FreeSectors equ 116
   161                              <1> LD_FS_FirstFreeSector equ 120
   162                              <1> LD_FS_PartitionEntry equ 124
   163                              <1> LD_FS_DParamEntry equ 125
   164                              <1> LD_FS_MediaChanged equ 126
   165                              <1> LD_FS_CDirLevel equ 127
   166                              <1> LD_FS_CDIR_Converted equ 128
   167                              <1> 
   168                              <1> ; Valid FAT Types
   169                              <1> FS_FAT12 equ 1
   170                              <1> FS_FAT16_CHS equ 2
   171                              <1> FS_FAT32_CHS equ 3
   172                              <1> FS_FAT16_LBA equ 4
   173                              <1> FS_FAT32_LBA equ 5
   174                              <1> 
   175                              <1> ; Cursor Location
   176                              <1> CCCpointer equ  0450h   ; BIOS data, current cursor column
   177                              <1> ; FAT Clusters EOC sign
   178                              <1> FAT12EOC equ 0FFFh
   179                              <1> FAT16EOC equ 0FFFFh
   180                              <1> ;FAT32EOC equ 0FFFFFFFh ; It is not direct usable for 8086 code
   181                              <1> ; BAD Cluster
   182                              <1> FAT12BADC equ 0FF7h
   183                              <1> FAT16BADC equ 0FFF7h
   184                              <1> ;FAT32BADC equ 0FFFFFF7h ; It is not direct usable for 8086 code
   185                              <1> ; MS-DOS FAT16 FS (Maximum Possible) Last Cluster Number= 0FFF6h 
   186                              <1> 
   187                              <1> ; TRFS
   188                              <1> 
   189                              <1> bs_FS_JmpBoot equ 0 ; jmp short bsBootCode
   190                              <1>                 ; db 0EBh, db 3Fh, db 90h
   191                              <1> bs_FS_Identifier equ 3  ; db 'FS', db 0
   192                              <1> bs_FS_BytesPerSec equ 6 ; dw 512
   193                              <1> bs_FS_MediaAttrib equ 8 ; db 3
   194                              <1> bs_FS_PartitionID equ 9 ; db 0A1h
   195                              <1> bs_FS_VersionMaj equ 10 ; db 01h
   196                              <1> bs_FS_VersionMin equ 11 ; db 0
   197                              <1> bs_FS_BeginSector equ 12   ; dd 0 
   198                              <1> bs_FS_VolumeSize equ 16 ; dd 2880
   199                              <1> bs_FS_StartupFD equ 20 ; dd 0
   200                              <1> bs_FS_MATLocation equ 24 ; dd 1
   201                              <1> bs_FS_RootDirD equ 28 ; dd 8
   202                              <1> bs_FS_SystemConfFD equ 32 ; dd 0
   203                              <1> bs_FS_SwapFD equ 36 ; dd 0
   204                              <1> bs_FS_UnDelDirD equ 40 ; dd 0
   205                              <1> bs_FS_DriveNumber equ 44 ; db 0
   206                              <1> bs_FS_LBA_Ready equ 45 ; db 0
   207                              <1> bs_FS_MagicWord equ 46 
   208                              <1> bs_FS_SecPerTrack equ 46 ; db 0A1h
   209                              <1> bs_FS_Heads equ 47 ; db 01h 
   210                              <1> bs_FS_OperationSys equ 48 ; db "TR-SINGLIX v1.0b"
   211                              <1> bs_FS_Terminator equ 64 ; db 0
   212                              <1> bs_FS_BootCode equ 65 
   213                              <1> 
   214                              <1> FS_MAT_DATLocation equ 12
   215                              <1> FS_MAT_DATScount equ 16
   216                              <1> FS_MAT_FreeSectors equ 20
   217                              <1> FS_MAT_FirstFreeSector equ 24
   218                              <1> FS_RDT_VolumeSerialNo equ 28
   219                              <1> FS_RDT_VolumeName equ 64
   220                              <1> 
   221                              <1> ; FAT12 + FAT16 + FAT32
   222                              <1> BS_JmpBoot equ 0
   223                              <1> BS_OEMName equ 3
   224                              <1> BPB_BytsPerSec equ 11
   225                              <1> BPB_SecPerClust equ 13
   226                              <1> BPB_RsvdSecCnt equ 14
   227                              <1> BPB_NumFATs equ 16
   228                              <1> BPB_RootEntCnt equ 17
   229                              <1> BPB_TotalSec16 equ 19
   230                              <1> BPB_Media equ 21
   231                              <1> BPB_FATSz16 equ 22
   232                              <1> BPB_SecPerTrk equ 24
   233                              <1> BPB_NumHeads equ 26
   234                              <1> BPB_HiddSec equ 28
   235                              <1> BPB_TotalSec32 equ 32
   236                              <1> 
   237                              <1> ; FAT12 and FAT16 only
   238                              <1> BS_DrvNum equ 36
   239                              <1> BS_Reserved1 equ 37
   240                              <1> BS_BootSig equ 38
   241                              <1> BS_VolID equ 39
   242                              <1> BS_VolLab equ 43
   243                              <1> BS_FilSysType equ 54 ; 8 bytes
   244                              <1> BS_BootCode equ 62
   245                              <1> 
   246                              <1> ; FAT32 only
   247                              <1> BPB_FATSz32 equ 36 ; FAT32, 4 bytes
   248                              <1> BPB_ExtFlags equ 40 ; FAT32, 2 bytes
   249                              <1> BPB_FSVer equ 42 ; FAT32, 2 bytes
   250                              <1> BPB_RootClus equ 44 ; FAT32, 4 bytes
   251                              <1> BPB_FSInfo equ 48 ; FAT 32, 2 bytes 
   252                              <1> BPB_BkBootSec equ 50 ; FAT32, 2 bytes
   253                              <1> BPB_Reserved equ 52 ; FAT32, 12 bytes
   254                              <1> BS_FAT32_DrvNum equ 64 ; FAT32, 1 byte
   255                              <1> BS_FAT32_Reserved1 equ 65 ; FAT32, 1 byte
   256                              <1> BS_FAT32_BootSig equ 66 ; FAT32, 1 byte
   257                              <1> BS_FAT32_VolID equ 67 ; FAT32, 4 bytes
   258                              <1> BS_FAT32_VolLab equ 71 ; FAT32, 11 bytes
   259                              <1> BS_FAT32_FilSysType equ 82 ; FAT32, 8 bytes
   260                              <1> BS_FAT32_BootCode equ 90
   261                              <1> 
   262                              <1> ; 29/02/2016
   263                              <1> ;(FAT32 Free Cluster Count & First Free Cluster values)
   264                              <1> ;[BPB_Reserved] = Free Cluster Count (offset 52)
   265                              <1> ;[BPB_Reserved+4] = First Free Cluster (offset 56)
   266                              <1> 
   267                              <1> BS_Validation equ 510
   268                              <1> 
   269                              <1> ; 15/02/2016
   270                              <1> ; FILE.ASM - 09/10/2011
   271                              <1> ; Directory Entry Structure
   272                              <1> ; 29/10/2009 (According to Microsoft FAT32 File System Specification)
   273                              <1> DirEntry_Name equ 0
   274                              <1> DirEntry_Attr equ 11
   275                              <1> DirEntry_NTRes equ 12
   276                              <1> DirEntry_CrtTimeTenth equ 13
   277                              <1> DirEntry_CrtTime equ 14
   278                              <1> DirEntry_CrtDate equ 16
   279                              <1> DirEntry_LastAccDate equ 18
   280                              <1> DirEntry_FstClusHI equ 20
   281                              <1> DirEntry_WrtTime equ 22
   282                              <1> DirEntry_WrtDate equ 24
   283                              <1> DirEntry_FstClusLO equ 26
   284                              <1> DirEntry_FileSize equ 28
  1924                                  %include 'trdosk1.s' ; 04/01/2016 
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYS INIT : trdosk1.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 07/05/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; TRDOS2.ASM (c) 2004-2011 Erdogan TAN [ 17/01/2004 ] Last Update: 09/11/2011
    14                              <1> ;
    15                              <1> 
    16                              <1> sys_init:
    17                              <1> 	; 07/05/2016
    18                              <1> 	; 02/05/2016
    19                              <1> 	; 24/04/2016
    20                              <1> 	; 14/04/2016
    21                              <1> 	; 13/04/2016
    22                              <1> 	; 30/03/2016
    23                              <1> 	; 24/01/2016
    24                              <1> 	; 06/01/2016
    25                              <1> 	; 04/01/2016
    26                              <1> 
    27                              <1> 	; 30/03/2016
    28                              <1> 	; Clear Logical DOS Disk Description Tables Area
    29 00003E18 31C0                <1> 	xor	eax, eax
    30 00003E1A BF00010900          <1> 	mov	edi, Logical_DOSDisks
    31 00003E1F B980060000          <1> 	mov	ecx, 6656/4 ; 26*256 = 6656 bytes
    32 00003E24 F3AB                <1> 	rep	stosd ; 1664 times 4 bytes
    33                              <1> 
    34 00003E26 B83F3A2F00          <1> 	mov	eax, '?:/'
    35 00003E2B A3[A3CF0000]        <1> 	mov	[Current_Dir_Drv], eax
    36                              <1> 
    37                              <1> 	; Logical DRV INIT (only for hard disks)
    38 00003E30 E8B2010000          <1> 	call 	ldrv_init  ; trdosk2.s
    39                              <1> 	
    40                              <1> 	; When floppy_drv_init call is disabled
    41                              <1> 	; media changed sign is needed
    42                              <1> 	; for proper drive initialization
    43                              <1>         
    44 00003E35 BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    45 00003E3A B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    46 00003E3C 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    47 00003E3F 8806                <1> 	mov 	[esi], al ; A:
    48 00003E41 81C600010000        <1> 	add 	esi, 100h 
    49 00003E47 8806                <1> 	mov 	[esi], al ; B: 
    50                              <1>            
    51                              <1> _current_drive_bootdisk:
    52 00003E49 8A15[6AC90000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    53 00003E4F 80FAFF              <1> 	cmp 	dl, 0FFh
    54 00003E52 740A                <1> 	je 	short _last_dos_diskno_check
    55                              <1> _boot_drive_check:
    56 00003E54 80FA80              <1> 	cmp 	dl, 80h
    57 00003E57 7218                <1> 	jb 	short _current_drive_a
    58 00003E59 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    59 00003E5C EB13                <1> 	jmp 	short _current_drive_a 
    60                              <1> 
    61                              <1> _last_dos_diskno_check:
    62 00003E5E 8A15[C5BD0000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    63 00003E64 80FA02              <1> 	cmp 	dl, 2
    64 00003E67 7706                <1> 	ja 	short _current_drive_c
    65 00003E69 7406                <1> 	je 	short _current_drive_a
    66 00003E6B 30D2                <1> 	xor 	dl, dl ; A:
    67 00003E6D EB02                <1> 	jmp 	short _current_drive_a
    68                              <1> 
    69                              <1> _current_drive_c:
    70 00003E6F B202                <1> 	mov 	dl, 2 ; C:
    71                              <1> 
    72                              <1> _current_drive_a:
    73 00003E71 8815[6BC90000]      <1> 	mov	[drv], dl
    74 00003E77 BE[C7BD0000]        <1>         mov     esi, msg_CRLF_temp
    75 00003E7C E89E000000          <1> 	call 	print_msg
    76                              <1> 
    77 00003E81 8A15[6BC90000]      <1> 	mov	dl, [drv]
    78 00003E87 E897090000          <1> 	call 	change_current_drive
    79 00003E8C 730C                <1> 	jnc 	short _start_mainprog
    80                              <1> 
    81                              <1> _drv_not_ready_error: 
    82 00003E8E BE[8BC00000]        <1> 	mov 	esi, msgl_drv_not_ready
    83 00003E93 E887000000          <1> 	call 	print_msg
    84 00003E98 EB63                <1>         jmp     _end_of_mainprog
    85                              <1> 
    86                              <1> _start_mainprog:
    87                              <1> 	; 07/05/2016
    88                              <1> 	; 02/05/2016
    89                              <1> 	; 24/04/2016
    90                              <1> 	; Retro UNIX 386 v1, 'sys_init' (u0.s)
    91                              <1> 	; 23/06/2015
    92                              <1> 
    93                              <1> 	; 02/05/2016
    94                              <1> 	; 24/04/2016
    95 00003E9A 66B80100            <1> 	mov	ax, 1
    96 00003E9E A2[CFDF0000]        <1> 	mov	[u.uno], al
    97 00003EA3 66A3[6EDF0000]      <1> 	mov	[mpid], ax
    98 00003EA9 66A3[78DC0000]      <1> 	mov	[p.pid], ax
    99 00003EAF A2[08DD0000]        <1> 	mov	[p.stat], al
   100 00003EB4 B004                <1> 	mov	al, time_count
   101 00003EB6 A2[C2DF0000]        <1> 	mov	[u.quant], al
   102                              <1> 	;
   103 00003EBB A1[D8CE0000]        <1> 	mov	eax, [k_page_dir]
   104 00003EC0 A3[D9DF0000]        <1> 	mov	[u.pgdir], eax ; reset
   105                              <1> 	;
   106 00003EC5 E845F2FFFF          <1> 	call	allocate_page
   107 00003ECA 0F82A2000000        <1> 	jc	panic
   108 00003ED0 A3[D0DF0000]        <1> 	mov	[u.upage], eax ; user structure page	
   109 00003ED5 A3[18DD0000]        <1> 	mov	[p.upage], eax
   110 00003EDA E8AAF2FFFF          <1> 	call	clear_page
   111                              <1> 	;
   112                              <1> 	; 24/08/2015
   113 00003EDF FE0D[77DF0000]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
   114                              <1> 			      ; 0 = executing a system call
   115                              <1> 	; 13/04/2016
   116                              <1> 	; Clear Environment Variables Page/Area
   117 00003EE5 BF00300900          <1> 	mov	edi, Env_Page ; 93000h
   118 00003EEA B980000000          <1> 	mov	ecx, Env_Page_Size / 4 	; 512/4  (4096/4)				 	  		 	  
   119 00003EEF 31C0                <1> 	xor	eax, eax
   120 00003EF1 F3AB                <1> 	rep	stosd
   121                              <1> 
   122                              <1> 	; 14/04/2016
   123 00003EF3 E8B4320000          <1>  	call	mainprog_startup_configuration
   124                              <1> 
   125 00003EF8 E8620A0000          <1>         call    dos_prompt
   126                              <1>               
   127                              <1> _end_of_mainprog:
   128 00003EFD BE[C7BD0000]        <1>         mov     esi, msg_CRLF_temp
   129 00003F02 E818000000          <1> 	call 	print_msg
   130 00003F07 BE[CDBD0000]        <1> 	mov 	esi, mainprog_Version
   131 00003F0C E80E000000          <1> 	call 	print_msg
   132                              <1> 	; 24/01/2016
   133 00003F11 28E4                <1> 	sub	ah, ah
   134 00003F13 E8D7CCFFFF          <1> 	call	int16h ; call getch
   135 00003F18 E994D1FFFF          <1> 	jmp	cpu_reset
   136                              <1> 
   137 00003F1D EBFE                <1> infinitiveloop: jmp short infinitiveloop
   138                              <1> 
   139                              <1> print_msg:
   140                              <1> 	; 04/01/2016
   141                              <1> 	; 01/07/2015
   142                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   143                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   144                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
   145                              <1> 	;
   146 00003F1F AC                  <1> 	lodsb
   147                              <1> pmsg1:
   148 00003F20 56                  <1> 	push 	esi
   149 00003F21 0FB61D[08CF0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   150 00003F28 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
   151 00003F2A E890D8FFFF          <1> 	call 	WRITE_TTY
   152 00003F2F 5E                  <1> 	pop	esi
   153 00003F30 AC                  <1> 	lodsb
   154 00003F31 20C0                <1> 	and 	al, al
   155 00003F33 75EB                <1> 	jnz 	short pmsg1
   156 00003F35 C3                  <1> 	retn
   157                              <1> 
   158                              <1> clear_screen:
   159                              <1> 	; 30/01/2016
   160                              <1> 	; 24/01/2016
   161                              <1> 	; 04/01/2016
   162 00003F36 0FB61D[08CF0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   163 00003F3D 8AA3[E0C80000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   164 00003F43 80FC04              <1> 	cmp	ah, 4
   165 00003F46 7205                <1> 	jb	short cls1
   166 00003F48 80FC07              <1> 	cmp	ah, 7
   167 00003F4B 7524                <1> 	jne	short vga_clear
   168                              <1> cls1:
   169 00003F4D 3A25[C6C80000]      <1> 	cmp	ah, [CRT_MODE] ; current video mode ? 
   170                              <1> 	;je	short cls2 ; yes (current video mode = 3)
   171                              <1> 	;;call	set_mode_3 ; set video mode to 3 (& clear screen)
   172                              <1> 	;;retn
   173                              <1> 	;jmp	set_mode_3
   174 00003F53 0F8578D5FFFF        <1> 	jne	set_mode_3
   175                              <1> cls2:
   176 00003F59 B407                <1> 	mov	ah, 07h ; attribute to be used on blanked line
   177 00003F5B 28C0                <1> 	sub 	al, al ; 0 =  entire window
   178 00003F5D 6631C9              <1> 	xor 	cx, cx
   179 00003F60 66BA4F18            <1> 	mov 	dx, 184Fh
   180 00003F64 E8ACD6FFFF          <1> 	call	_scroll_up ; 24/01/2016
   181                              <1> 	;
   182                              <1> 	;mov	bl, [ACTIVE_PAGE] ; video page number (0 to 7)
   183 00003F69 6631D2              <1> 	xor 	dx, dx
   184 00003F6C E8E2D8FFFF          <1> 	call	_set_cpos ; 24/01/2016 
   185                              <1> 	;retn
   186                              <1> vga_clear:
   187 00003F71 C3                  <1> 	retn	
   188                              <1> 
   189                              <1> panic:
   190                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   191                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   192 00003F72 BE[79CB0000]        <1> 	mov 	esi, panic_msg
   193 00003F77 E8A3FFFFFF          <1> 	call 	print_msg
   194                              <1> key_to_reboot:
   195                              <1>         ; 24/01/2016
   196 00003F7C 28E4                <1>         sub     ah, ah
   197 00003F7E E86CCCFFFF          <1>         call    int16h ; call   getch
   198                              <1>         ; wait for a character from the current tty
   199                              <1> 	;
   200 00003F83 B00A                <1> 	mov	al, 0Ah
   201 00003F85 8A1D[08CF0000]      <1> 	mov	bl, [ptty] ; [ACTIVE_PAGE]
   202 00003F8B B407                <1> 	mov	ah, 07h ; Black background, 
   203                              <1> 			; light gray forecolor
   204 00003F8D E82DD8FFFF          <1> 	call 	WRITE_TTY
   205 00003F92 E91AD1FFFF          <1> 	jmp	cpu_reset 
   206                              <1> 
   207                              <1> ctrlbrk:
   208                              <1> 	; 12/11/2015
   209                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   210                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
   211                              <1> 	;
   212                              <1> 	; INT 1Bh (control+break) handler		
   213                              <1> 	;
   214                              <1>       	; Retro Unix 8086 v1 feature only!
   215                              <1>       	;
   216 00003F97 66833D[C4DF0000]00  <1> 	cmp 	word [u.intr], 0
   217 00003F9F 7645                <1> 	jna 	short cbrk4
   218                              <1> cbrk0:
   219                              <1> 	; 12/11/2015
   220                              <1> 	; 06/12/2013
   221 00003FA1 66833D[C6DF0000]00  <1> 	cmp 	word [u.quit], 0
   222 00003FA9 743B                <1> 	jz	short cbrk4
   223                              <1> 	;
   224                              <1> 	; 20/09/2013	
   225 00003FAB 6650                <1> 	push 	ax
   226 00003FAD A0[08CF0000]        <1> 	mov	al, [ptty]
   227                              <1> 	;
   228                              <1> 	; 12/11/2015
   229                              <1> 	;
   230                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
   231                              <1> 	; or ctrl+break from console (pseudo) tty
   232                              <1> 	; (!redirection!)
   233                              <1> 	;
   234 00003FB2 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   235 00003FB4 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
   236                              <1> 	;	
   237                              <1> 	; Serial port interrupt handler sets [ptty]
   238                              <1> 	; to the port's tty number (as temporary).
   239                              <1> 	;
   240                              <1> 	; If active process is using a stdin or 
   241                              <1> 	; stdout redirection (by the shell),
   242                              <1>         ; console tty keyboard must be available
   243                              <1> 	; to terminate running process,
   244                              <1> 	; in order to prevent a deadlock. 
   245                              <1> 	;
   246 00003FB6 52                  <1> 	push	edx
   247 00003FB7 0FB615[CFDF0000]    <1> 	movzx	edx, byte [u.uno]
   248 00003FBE 3A82[D7DC0000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   249 00003FC4 5A                  <1> 	pop	edx
   250 00003FC5 7412                <1> 	je	short cbrk2
   251                              <1> cbrk1:
   252 00003FC7 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   253                              <1> 	; 06/12/2013
   254 00003FC9 3A05[B0DF0000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   255 00003FCF 7408                <1> 	je	short cbrk2	
   256 00003FD1 3A05[B1DF0000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   257 00003FD7 750B                <1> 	jne	short cbrk3	
   258                              <1> cbrk2:
   259                              <1> 	;; 06/12/2013
   260                              <1> 	;mov	ax, [u.quit]
   261                              <1> 	;and	ax, ax
   262                              <1> 	;jz	short cbrk3
   263                              <1> 	;
   264 00003FD9 6631C0              <1> 	xor	ax, ax ; 0
   265 00003FDC 6648                <1> 	dec	ax
   266                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   267 00003FDE 66A3[C6DF0000]      <1> 	mov	[u.quit], ax
   268                              <1> cbrk3:
   269 00003FE4 6658                <1> 	pop	ax
   270                              <1> cbrk4:
   271 00003FE6 C3                  <1> 	retn
  1925                                  %include 'trdosk2.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DRV INIT : trdosk2.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DRV_INIT.ASM (c) 2009-2011 Erdogan TAN  [26/09/2009] Last Update: 07/08/2011
    14                              <1> ;
    15                              <1> 
    16                              <1> ldrv_init: ; Logical Drive Initialization
    17                              <1> 	; 12/02/2016
    18                              <1> 	; 06/01/2016
    19                              <1> 	;  	('diskinit.inc', 'diskio.inc' integration)
    20                              <1> 	; 04/01/2016 (TRDOS 386 = TRDOS v2.0)
    21                              <1> 	; 07/08/2011
    22                              <1> 	; 20/09/2009
    23                              <1> 	; 2005
    24 00003FE7 0FB60D[78CF0000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
    25 00003FEE 80F901              <1> 	cmp	cl, 1
    26 00003FF1 7301                <1> 	jnb	short load_hd_partition_tables
    27                              <1> 	; No hard disks
    28 00003FF3 C3                  <1> 	retn
    29                              <1> load_hd_partition_tables:
    30 00003FF4 8B35[7CCF0000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    31 00003FFA BF[A2D30000]        <1> 	mov 	edi, PTable_hd0
    32 00003FFF B280                <1> 	mov 	dl, 80h
    33                              <1> load_next_hd_partition_table:
    34 00004001 51                  <1> 	push	ecx
    35 00004002 57                  <1> 	push	edi
    36 00004003 56                  <1> 	push	esi ; FDPT (+ DPTE) address
    37 00004004 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
    38 00004007 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
    39                              <1> 	;shr	al, 6
    40 00004009 A2[A2D50000]        <1> 	mov 	[HD_LBA_yes], al
    41 0000400E E81C040000          <1> 	call	load_masterboot
    42 00004013 7275                <1> 	jc	short pass_pt_this_hard_disk
    43                              <1> 
    44 00004015 BE[60D30000]        <1> 	mov	esi, PartitionTable
    45 0000401A 89F3                <1> 	mov	ebx, esi
    46                              <1> 	;mov	ecx, 16
    47 0000401C B110                <1> 	mov	cl, 16
    48 0000401E F3A5                <1> 	rep 	movsd
    49 00004020 89DE                <1> 	mov 	esi, ebx 
    50 00004022 C605[6DC90000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
    51                              <1> loc_validate_hdp_partition:
    52 00004029 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
    53 0000402D 7641                <1> 	jna	short loc_validate_next_hdp_partition2
    54 0000402F 56                  <1> 	push	esi ; Masterboot partition table offset
    55 00004030 52                  <1> 	push	edx ; dl = Physical drive number 
    56 00004031 FE05[A3D50000]      <1> 	inc	byte [PP_Counter]
    57 00004037 31FF                <1>         xor	edi, edi ; 0  
    58                              <1> 	; Input -> ESI = PartitionTable offset
    59                              <1> 	; DL = Hard disk drive number 
    60                              <1> 	; EDI = 0 -> Primary Partition
    61                              <1> 	; EDI > 0 -> Extended Partition's Start Sector   
    62 00004039 E879010000          <1> 	call 	validate_hd_fat_partition
    63 0000403E 730A                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
    64                              <1> 	;pop	edx
    65                              <1> 	;push	edx
    66 00004040 8B1424              <1> 	mov	edx, [esp] 
    67 00004043 E8C5020000          <1> 	call	validate_hd_fs_partition
    68 00004048 7224                <1> 	jc	short loc_validate_next_hdp_partition1
    69                              <1> loc_set_valid_hdp_partition_entry:
    70 0000404A 8A0D[C5BD0000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
    71 00004050 80C141              <1> 	add 	cl, 'A'
    72                              <1> 	; ESI = Logical dos drive description table address
    73 00004053 880E                <1> 	mov	[esi+LD_Name], cl
    74 00004055 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
    75 00004058 88E0                <1> 	mov	al, ah ; Physical drive number
    76 0000405A 2C80                <1> 	sub	al, 80h
    77 0000405C C0E002              <1> 	shl	al, 2
    78 0000405F 0404                <1> 	add	al, 4 ; 0 Based
    79 00004061 2A05[6DC90000]      <1> 	sub	al, [hdc] ; 4 - partition index
    80                              <1> 	; AL = Partition entry/index, 0 based
    81                              <1> 	;  0 -> hd 0, Partition Table offset = 0
    82                              <1> 	; 15 -> hd 3, Partition Table offset = 3
    83                              <1> 	;mov	[esi+LD_PartitionEntry], al 
    84 00004067 80EC7E              <1> 	sub 	ah, 7Eh
    85                              <1> 	; AH = Physical drive index, zero based
    86                              <1> 	;  0 for drive A:, 2 for drive C:
    87                              <1> 	;mov 	[esi+LD_DParamEntry], ah 
    88 0000406A 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
    89                              <1> loc_validate_next_hdp_partition1:
    90 0000406E 5A                  <1> 	pop 	edx ; dl = Physical drive number 
    91 0000406F 5E                  <1> 	pop	esi ; Masterboot partition table offset
    92                              <1> loc_validate_next_hdp_partition2:
    93                              <1> 	; ESI = PartitionTable offset
    94                              <1> 	; DL = Hard/Fixed disk drive number
    95 00004070 FE0D[6DC90000]      <1> 	dec	byte [hdc] ; 4 - partition index
    96 00004076 7412                <1> 	jz	short pass_pt_this_hard_disk
    97 00004078 83C610              <1> 	add	esi, 16 ; 10h
    98 0000407B EBAC                <1> 	jmp	short loc_validate_hdp_partition
    99                              <1> loc_next_hd_partition_table:
   100 0000407D FEC2                <1> 	inc	dl
   101 0000407F 83C620              <1> 	add	esi, 32 ; next FDPT address
   102 00004082 83C740              <1> 	add	edi, 64 ; next partition table destination
   103 00004085 E977FFFFFF          <1>         jmp     load_next_hd_partition_table
   104                              <1> pass_pt_this_hard_disk:
   105 0000408A 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
   106 0000408B 5F                  <1> 	pop	edi ; Ptable_hd?
   107 0000408C 59                  <1> 	pop	ecx
   108 0000408D E2EE                <1> 	loop	loc_next_hd_partition_table
   109 0000408F 803D[A3D50000]01    <1> 	cmp	byte [PP_Counter], 1
   110 00004096 7301                <1> 	jnb	short load_extended_dos_partitions
   111                              <1> 	; Empty partition table
   112 00004098 C3                  <1> 	retn 
   113                              <1> load_extended_dos_partitions:
   114 00004099 BE[A2D30000]        <1> 	mov	esi, PTable_hd0
   115 0000409E BF[A2D40000]        <1> 	mov	edi, PTable_ep0
   116 000040A3 C605[6DC90000]80    <1> 	mov	byte [hdc], 80h
   117                              <1> next_hd_extd_partition:
   118 000040AA 56                  <1> 	push	esi ; PTable_hd? offset
   119 000040AB 57                  <1> 	push	edi ; PTable_ep?
   120                              <1> 	;mov	ecx, 4
   121 000040AC B104                <1> 	mov	cl, 4
   122 000040AE 8A15[6DC90000]      <1> 	mov	dl, byte [hdc]
   123                              <1> hd_check_fs_id_05h:
   124 000040B4 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   125 000040B7 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   126 000040B9 7404                <1> 	je	short loc_set_ep_start_sector
   127 000040BB 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   128 000040BD 7546                <1> 	jne	short continue_to_check_ep
   129                              <1> loc_set_ep_start_sector:
   130 000040BF FE05[A4D50000]      <1> 	inc	byte [EP_Counter]
   131 000040C5 88D4                <1> 	mov	ah, dl ; byte [hdc]
   132 000040C7 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
   133 000040C9 50                  <1> 	push	eax 
   134 000040CA 30E4                <1> 	xor	ah, ah  
   135 000040CC 2C80                <1> 	sub	al, 80h
   136 000040CE 50                  <1> 	push	eax
   137 000040CF C0E002              <1> 	shl	al, 2 ; al = al * 4
   138 000040D2 0FB6D8              <1> 	movzx	ebx, al
   139 000040D5 81C3[A5D50000]      <1> 	add	ebx, EP_StartSector
   140 000040DB 8B4608              <1> 	mov	eax, [esi+ptStartSector]
   141                              <1>         ; EAX = Extended partition's start sector
   142 000040DE 8903                <1>         mov	[ebx], eax
   143 000040E0 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
   144 000040E1 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
   145 000040E2 BB[A2D10000]        <1> 	mov	ebx, MasterBootBuff
   146 000040E7 803D[A2D50000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   147 000040EE 7240                <1> 	jb	short loc_hd_load_ep_05h
   148 000040F0 80FE05              <1> 	cmp	dh, 05h
   149 000040F3 743B                <1> 	je	short loc_hd_load_ep_05h
   150                              <1> loc_hd_load_ep_0Fh:
   151                              <1> 	; 04/01/2016
   152 000040F5 51                  <1> 	push	ecx
   153 000040F6 8B4E08              <1> 	mov	ecx, [esi+ptStartSector] ; sector number
   154                              <1> 	;mov	ebx, MasterBootBuff ; buffer address
   155                              <1> 	; LBA read/write (with private LBA function) 
   156                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   157                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   158 000040F9 B41B                <1> 	mov	ah, 1Bh ; LBA read
   159 000040FB B001                <1> 	mov	al, 1 ; sector count
   160 000040FD E8D2E7FFFF          <1> 	call	int13h
   161 00004102 59                  <1> 	pop	ecx
   162 00004103 733F                <1> 	jnc	short loc_hd_move_ep_table
   163                              <1> continue_to_check_ep:
   164 00004105 83C610              <1> 	add	esi, 16
   165 00004108 E2AA                <1> 	loop	hd_check_fs_id_05h
   166                              <1> continue_check_ep_next_disk:
   167 0000410A 5F                  <1> 	pop	edi ; PTable_ep?
   168 0000410B 5E                  <1> 	pop	esi ; PTable_hd?
   169 0000410C A0[78CF0000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   170 00004111 047F                <1> 	add	al, 7Fh
   171 00004113 3805[6DC90000]      <1> 	cmp	[hdc], al
   172 00004119 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
   173 0000411F 83C640              <1> 	add	esi, 64
   174 00004122 83C740              <1> 	add	edi, 64
   175 00004125 FE05[6DC90000]      <1> 	inc	byte [hdc]
   176 0000412B E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
   177                              <1> loc_hd_load_ep_05h:
   178 00004130 51                  <1> 	push	ecx 
   179 00004131 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   180 00004134 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
   181 00004138 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   182                              <1> 	;mov	ebx, MasterBootBuff
   183 0000413C E893E7FFFF          <1> 	call	int13h
   184 00004141 59                  <1> 	pop	ecx  
   185 00004142 72C1                <1> 	jc	short continue_to_check_ep
   186                              <1> loc_hd_move_ep_table:
   187                              <1>         ;pop	edi
   188                              <1> 	;push	edi  ; PTable_ep?
   189 00004144 8B3C24              <1> 	mov	edi, [esp]        
   190 00004147 BE[60D30000]        <1>         mov	esi, PartitionTable ; Extended
   191 0000414C 89F3                <1> 	mov	ebx, esi
   192                              <1> 	;mov	ecx, 16
   193 0000414E B110                <1> 	mov	cl, 16
   194 00004150 F3A5                <1>        	rep	movsd
   195 00004152 89DE                <1> 	mov	esi, ebx 
   196                              <1> loc_set_hde_sub_partition_count:
   197 00004154 C605[A3D50000]04    <1> 	mov	byte [PP_Counter], 4
   198                              <1> loc_validate_hde_partition:
   199 0000415B 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   200 0000415F 763F                <1> 	jna	short loc_validate_next_hde_partition2
   201 00004161 56                  <1> 	push	esi ; Extended partition table offset
   202 00004162 8A15[6DC90000]      <1> 	mov	dl, byte [hdc]
   203 00004168 0FB6C2              <1> 	movzx	eax, dl
   204 0000416B 2C80                <1> 	sub	al, 80h
   205 0000416D C0E002              <1> 	shl	al, 2
   206                              <1> 	; 06/01/2016 
   207                              <1> 	; (TRDOS v1.0 had a bug here, in 'DRV_INIT.ASM')
   208                              <1> 	; BUGFIX *
   209                              <1> 	;mov	ecx, eax
   210 00004170 88C1                <1> 	mov	cl, al
   211 00004172 80C104              <1> 	add	cl, 4
   212 00004175 2A0D[A3D50000]      <1> 	sub	cl, [PP_Counter] ; 4 to 1
   213                              <1> 	; CL = Partition entry/index, 0 based
   214                              <1>         ;  0 -> hd 0, Partition Table offset = 0
   215                              <1>         ; 15 -> hd 3, Partition Table offset = 3
   216 0000417B 88D5                <1>       	mov	ch, dl   
   217 0000417D 80ED7E              <1> 	sub	ch, 7Eh ;
   218                              <1> 	; CH = Physical drive index, zero based
   219                              <1> 	;  0 for drive A:, 2 for drive C:	
   220                              <1> 	; BUGFIX *
   221 00004180 51                  <1> 	push	ecx ; *
   222 00004181 BF[A5D50000]        <1> 	mov	edi, EP_StartSector
   223 00004186 01C7                <1> 	add	edi, eax
   224                              <1> 	; Input -> ESI = PartitionTable offset
   225                              <1> 	; DL = Hard disk drive number   
   226                              <1> 	; EDI = Extended partition start sector pointer
   227 00004188 E82A000000          <1> 	call	validate_hd_fat_partition
   228 0000418D 59                  <1> 	pop	ecx ; *
   229 0000418E 720F                <1> 	jc	short loc_validate_next_hde_partition1
   230                              <1> loc_set_valid_hde_partition_entry:
   231                              <1> 	; 06/01/2016 (TRDOS v2.0)
   232                              <1> 	; BUGFIX *
   233                              <1> 	;mov	[esi+LD_PartitionEntry], cl 
   234                              <1> 	;mov	[esi+LD_DParamEntry], ch 
   235 00004190 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
   236                              <1> 	;
   237 00004194 8A0D[C5BD0000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   238 0000419A 80C141              <1> 	add	cl, 'A'
   239 0000419D 880E                <1> 	mov	[esi+LD_Name], cl
   240                              <1> loc_validate_next_hde_partition1:
   241 0000419F 5E                  <1> 	pop	esi ; Extended partition table offset
   242                              <1> loc_validate_next_hde_partition2:
   243                              <1> 	; ESI = Extended partition table offset
   244                              <1> 	; DL = Hard disk drive number
   245 000041A0 FE0D[A3D50000]      <1> 	dec	byte [PP_Counter]
   246 000041A6 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
   247 000041AC 83C610              <1> 	add 	esi, 16 ; 10h
   248 000041AF EBAA                <1> 	jmp	short loc_validate_hde_partition
   249                              <1> loc_validating_hd_partitions_ok:
   250 000041B1 A0[C5BD0000]        <1> 	mov	al, [Last_DOS_DiskNo]
   251                              <1> loc_drv_init_retn:
   252 000041B6 C3                  <1> 	retn
   253                              <1> 
   254                              <1> validate_hd_fat_partition:
   255                              <1> 	; 12/02/2016
   256                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   257                              <1> 	; 07/08/2011
   258                              <1> 	; 23/07/2011
   259                              <1> 	; Input
   260                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   261                              <1> 	;   ESI = PartitionTable offset
   262                              <1> 	;   EDI = Extend. Part. Start Sector Pointer
   263                              <1> 	;   EDI = 0 -> Primary Partition 
   264                              <1> 	;   byte [Last_DOS_DiskNo]
   265                              <1>  	; Output
   266                              <1> 	;  cf=0 -> Validated
   267                              <1> 	;   ESI = Logical dos drv desc. table
   268                              <1> 	;   EBX = FAT boot sector buffer
   269                              <1> 	;   byte [Last_DOS_DiskNo]
   270                              <1> 	;  cf=1 -> Not a valid FAT partition
   271                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   272                              <1> 	
   273                              <1> 	;mov 	esi, PartitionTable
   274 000041B7 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   275 000041BA 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
   276                              <1> 	; 12/02/2016
   277                              <1> 	;jb	short loc_not_a_valid_fat_partition2
   278 000041BD 7305                <1>  	jnb	short vhdp_FAT16_32
   279                              <1> 	;
   280 000041BF 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)		
   281 000041C2 7519                <1> 	jne	short loc_not_a_valid_fat_partition1
   282                              <1> vhdp_FAT16_32:
   283 000041C4 B002                <1> 	mov	al, 2
   284 000041C6 7417                <1> 	je	short loc_set_valid_hd_partition_params
   285 000041C8 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   286 000041CB 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
   287 000041CD 7410                <1> 	je	short loc_set_valid_hd_partition_params
   288                              <1> 
   289 000041CF FEC0                <1> 	inc	al ; 3
   290 000041D1 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   291 000041D4 7409                <1> 	je	short loc_set_valid_hd_partition_params
   292 000041D6 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
   293 000041D8 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   294 000041DB 7402                <1> 	je	short loc_set_valid_hd_partition_params
   295                              <1> loc_not_a_valid_fat_partition1:
   296 000041DD F9                  <1> 	stc
   297                              <1> loc_not_a_valid_fat_partition2:
   298 000041DE C3                  <1> 	retn
   299                              <1> 
   300                              <1> loc_set_valid_hd_partition_params:
   301 000041DF FE05[C5BD0000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   302                              <1> 	;
   303 000041E5 31DB                <1> 	xor	ebx, ebx
   304 000041E7 8A3D[C5BD0000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   305 000041ED 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   306                              <1> 	;
   307 000041F3 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   308 000041F7 885302              <1> 	mov	byte [ebx+LD_PhyDrvNo], dl
   309                              <1> 	;mov	byte [ebx+LD_FATType], al ; 2 or 3
   310                              <1> 	;mov	byte [ebx+LD_FSType], ah ; 06h, 0Eh, 0Bh, 0Ch
   311 000041FA 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   312                              <1> 	;
   313 000041FE 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   314 00004201 09FF                <1> 	or	edi, edi 
   315 00004203 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   316                              <1> loc_add_hd_FAT_ep_start_sector:
   317 00004205 030F                <1> 	add	ecx, [edi]
   318                              <1> pass_hd_FAT_ep_start_sector_adding:
   319 00004207 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   320                              <1> loc_hd_FAT_logical_drv_init:
   321 0000420A 89DD                <1> 	mov	ebp, ebx
   322                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   323 0000420C A0[A2D50000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   324 00004211 884305              <1> 	mov	[ebx+LD_LBAYes], al
   325 00004214 BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   326 00004219 08C0                <1> 	or	al, al
   327 0000421B 740C                <1> 	jz	short loc_hd_FAT_drv_init_load_bs_chs
   328                              <1> loc_hd_FAT_drv_init_load_bs_lba:
   329                              <1> 	; DL = Physical drive number
   330                              <1>    	;mov	ecx, [esi+ptStartSector] ; sector number
   331                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   332                              <1> 	; LBA read/write (with private LBA function) 
   333                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   334                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   335 0000421D B41B                <1> 	mov	ah, 1Bh ; LBA read
   336 0000421F B001                <1> 	mov	al, 1 ; sector count
   337 00004221 E8AEE6FFFF          <1> 	call	int13h
   338 00004226 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   339                              <1> loc_not_a_valid_fat_partition3:
   340 00004228 C3                  <1> 	retn
   341                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   342 00004229 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   343 0000422C 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   344 00004230 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   345                              <1> 	;mov	ebx, DOSBootSectorBuff
   346 00004234 E89BE6FFFF          <1> 	call	int13h
   347 00004239 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   348                              <1> loc_hd_drv_FAT_boot_validation:
   349                              <1> 	;mov	esi, DOSBootSectorBuff
   350 0000423B 89DE                <1> 	mov	esi, ebx
   351 0000423D 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   352 00004246 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
   353 00004248 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   354 0000424C 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
   355 0000424E 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   356 00004253 770F                <1> 	ja	short loc_hd_FAT16_BPB
   357 00004255 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   358 00004259 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
   359                              <1> loc_hd_FAT32_BPB:
   360 0000425B B92D000000          <1> 	mov	ecx, 45
   361 00004260 EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
   362                              <1> 	;
   363                              <1> loc_not_a_valid_fat_partition4:
   364 00004262 F9                  <1> 	stc
   365 00004263 C3                  <1> 	retn
   366                              <1> 	;
   367                              <1> loc_hd_FAT16_BPB:
   368 00004264 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   369 00004268 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   370 0000426A B920000000          <1> 	mov	ecx, 32
   371                              <1> loc_hd_move_FAT_BPB:
   372 0000426F 89EF                <1> 	mov 	edi, ebp
   373                              <1> 	;mov	esi, ebx ; Boot sector
   374 00004271 57                  <1> 	push	edi
   375 00004272 83C706              <1> 	add	edi, LD_BPB
   376 00004275 F366A5              <1> 	rep	movsw 
   377 00004278 5E                  <1> 	pop	esi
   378 00004279 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   379 0000427D 03466C              <1> 	add	eax, [esi+LD_StartSector]
   380 00004280 894660              <1> 	mov	[esi+LD_FATBegin], eax
   381 00004283 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   382 00004287 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   383                              <1> loc_set_FAT32_RootDirLoc:
   384 00004289 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   385 0000428C 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   386 00004290 F7E3                <1> 	mul	ebx
   387 00004292 034660              <1> 	add	eax, [esi+LD_FATBegin]
   388                              <1> loc_set_FAT32_data_begin:
   389 00004295 894668              <1> 	mov	[esi+LD_DATABegin], eax
   390 00004298 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   391                              <1> 	; If Root Directory Cluster <> 2 then
   392                              <1> 	; change the beginning sector value 
   393                              <1> 	; of the root dir by adding sector offset.
   394 0000429B 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   395 0000429E 83E802              <1> 	sub	eax, 2
   396 000042A1 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   397                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   398 000042A3 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
   399 000042A6 F7E3                <1> 	mul	ebx
   400 000042A8 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   401 000042AB EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   402                              <1> 	;
   403                              <1> loc_set_FAT16_RootDirLoc:
   404 000042AD 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   405 000042B1 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   406 000042B5 F7E2                <1> 	mul	edx
   407 000042B7 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   408 000042BA 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   409                              <1> loc_set_FAT16_data_begin:
   410 000042BD 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   411 000042C0 B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
   412                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   413 000042C5 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   414 000042C9 F7E2                <1>         mul	edx
   415                              <1> 	;mov	ecx, 511
   416 000042CB 66B9FF01            <1> 	mov	cx, 511
   417 000042CF 01C8                <1> 	add	eax, ecx
   418 000042D1 41                  <1> 	inc	ecx ; 512
   419 000042D2 F7F1                <1> 	div	ecx
   420 000042D4 014668              <1> 	add	[esi+LD_DATABegin], eax
   421 000042D7 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   422 000042DB 6685C0              <1> 	test	ax, ax
   423 000042DE 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
   424                              <1> loc_set_16bit_FAT_total_sectors:
   425 000042E0 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   426 000042E3 EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
   427                              <1> loc_set_32bit_FAT_total_sectors:
   428 000042E5 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   429 000042E8 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   430                              <1> loc_set_hd_FAT_cluster_count:
   431 000042EB 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   432 000042EE 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   433 000042F1 29D0                <1> 	sub	eax, edx
   434 000042F3 31D2                <1> 	xor	edx, edx ; 0
   435 000042F5 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   436 000042F9 F7F1                <1>         div	ecx 
   437 000042FB 894678              <1> 	mov	[esi+LD_Clusters], eax
   438                              <1> 	; Maximum Valid Cluster Number= EAX +1
   439                              <1> 	; with 2 reserved clusters= EAX +2
   440                              <1> loc_set_hd_FAT_fs_free_sectors:
   441                              <1> 	;mov	dword [esi+LD_FreeSectors], 0
   442 000042FE E859010000          <1> 	call	get_free_FAT_sectors
   443 00004303 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   444 00004305 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   445 00004308 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6  ; Volume Name Reset
   446                              <1> 	;mov	cl, [Last_DOS_DiskNo] 
   447                              <1> 	;add	cl, 'A'
   448                              <1> 	;mov	[esi+LD_FS_Name], cl
   449                              <1> 
   450                              <1> loc_validate_hd_FAT_partition_retn:         
   451 0000430C C3                  <1> 	retn
   452                              <1> 
   453                              <1> validate_hd_fs_partition:
   454                              <1> 	; 13/02/2016
   455                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   456                              <1> 	; 29/01/2011
   457                              <1> 	; 23/07/2011
   458                              <1> 	; Input
   459                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   460                              <1> 	;   ESI = PartitionTable offset
   461                              <1> 	;   byte [Last_DOS_DiskNo]
   462                              <1> 	; Output
   463                              <1> 	;  cf=0 -> Validated
   464                              <1> 	;   ESI = Logical dos drv desc. table
   465                              <1> 	;   EBX = Singlix FS boot sector buffer
   466                              <1> 	;   byte [Last_DOS_DiskNo]
   467                              <1> 	;  cf=1 -> Not a valid 'Singlix FS' partition
   468                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   469                              <1> 
   470                              <1> 	;mov	esi, PartitionTable
   471 0000430D 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   472 00004310 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   473 00004313 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   474                              <1> loc_set_valid_hd_fs_partition_params:
   475 00004315 FE05[C5BD0000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   476 0000431B 30C0                <1> 	xor	al, al ; mov al, 0
   477                              <1> 	;mov	[drv], dl
   478 0000431D 29DB                <1> 	sub	ebx, ebx ; 0
   479 0000431F 8A3D[C5BD0000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   480 00004325 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   481 0000432B C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   482 0000432F 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   483                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   484                              <1> 	;mov	[ebx+LD_FSType], ah
   485 00004332 66894303            <1> 	mov	[ebx+LD_FATType], ax
   486                              <1> 	;mov	eax, [esi+ptStartSector]
   487                              <1> 	;mov	[ebx+LD_StartSector], eax
   488                              <1> loc_hd_fs_logical_drv_init:
   489 00004336 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   490                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   491 00004338 A0[A2D50000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   492 0000433D 884305              <1> 	mov	[ebx+LD_LBAYes], al
   493 00004340 89DE                <1> 	mov	esi, ebx
   494 00004342 BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
   495 00004347 08C0                <1> 	or	al, al
   496 00004349 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   497                              <1> loc_hd_fs_drv_init_load_bs_chs:
   498 0000434B 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   499 0000434E 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   500 00004352 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   501                              <1> 	;mov	ebx, DOSBootSectorBuff
   502 00004356 E879E5FFFF          <1> 	call	int13h
   503 0000435B 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   504                              <1> loc_validate_hd_fs_partition_err_retn:
   505 0000435D C3                  <1> 	retn
   506                              <1> loc_validate_hd_fs_partition_stc_retn:
   507 0000435E F9                  <1> 	stc
   508 0000435F C3                  <1> 	retn
   509                              <1> loc_hd_fs_drv_init_load_bs_lba:
   510                              <1> 	; DL = Physical drive number
   511                              <1> 	;mov	esi, ebx
   512 00004360 8B4E08              <1>    	mov	ecx, [esi+ptStartSector] ; sector number
   513                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   514                              <1> 	; LBA read/write (with private LBA function) 
   515                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   516                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   517 00004363 B41B                <1> 	mov	ah, 1Bh ; LBA read
   518 00004365 B001                <1> 	mov	al, 1 ; sector count
   519 00004367 E868E5FFFF          <1> 	call	int13h
   520 0000436C 72EF                <1> 	jc	short loc_validate_hd_fs_partition_err_retn
   521                              <1> loc_hd_drv_fs_boot_validation:
   522                              <1> 	;mov	esi, DOSBootSectorBuff
   523 0000436E 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   524 00004370 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   525 00004379 75E3                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   526                              <1>         ;
   527                              <1> 	;Singlix FS Extensions to TR-DOS (7/6/2009) 
   528 0000437B 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
   529 00004381 75DB                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   530                              <1>         ;'A1h' check is not necessary
   531                              <1> 	;  if 'FS' check is passed as OK/Yes.
   532 00004383 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   533 00004387 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   534                              <1> 	;
   535 00004389 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   536                              <1> 	;
   537 0000438B 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   538 0000438E 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   539                              <1> 	;
   540                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   541 00004391 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   542 00004394 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   543                              <1> 	;
   544 00004397 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   545 0000439A 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   546                              <1> 	;
   547 0000439D 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   548 000043A1 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   549 000043A5 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   550 000043A8 6698                <1> 	cbw
   551 000043AA 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   552 000043AE 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   553                              <1> 	;cbw
   554 000043B1 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   555                              <1> 	;
   556 000043B5 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   557 000043B8 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   558 000043BB 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   559 000043BE 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   560 000043C1 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   561 000043C4 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   562 000043C7 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   563 000043CA 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   564 000043CD 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   565 000043D0 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   566                              <1> 	;
   567 000043D3 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   568 000043D5 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   569 000043D8 89FE                <1> 	mov	esi, edi
   570                              <1> mread_hd_fs_MAT_sector:
   571                              <1>        ;mov	ebx, DOSBootSectorBuff
   572 000043DA B901000000          <1> 	mov	ecx, 1
   573 000043DF E8A7760000          <1> 	call	disk_read
   574 000043E4 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   575                              <1> 	; EDI will not be changed
   576 000043E6 89DE                <1> 	mov	esi, ebx
   577                              <1> use_hdfs_mat_sector_params:
   578 000043E8 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   579 000043EB 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   580 000043EE 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   581 000043F1 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   582 000043F4 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   583 000043F7 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   584 000043FA 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   585 000043FD 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   586 00004400 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   587 00004403 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   588 00004406 89FE                <1> 	mov	esi, edi   
   589                              <1> read_hd_fs_RDT_sector:
   590 00004408 BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff
   591                              <1> 	;mov	ecx, 1
   592 0000440D B101                <1> 	mov	cl, 1
   593 0000440F E877760000          <1> 	call	disk_read
   594 00004414 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   595                              <1> 	; EDI will not be changed
   596 00004416 89DE                <1> 	mov	esi, ebx
   597                              <1> use_hdfs_RDT_sector_params:
   598 00004418 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   599 0000441B 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   600 0000441E 57                  <1> 	push	edi
   601                              <1> 	;mov	ecx, 16
   602 0000441F B110                <1> 	mov	cl, 16
   603 00004421 83C640              <1> 	add	esi, FS_RDT_VolumeName
   604 00004424 83C72C              <1> 	add	edi, LD_FS_VolumeName
   605 00004427 F3A5                <1> 	rep	movsd ; 64 bytes
   606 00004429 5E                  <1> 	pop	esi
   607                              <1> 		; Volume Name Reset
   608 0000442A C6467E06            <1>         mov     byte [esi+LD_FS_MediaChanged], 6
   609                              <1> 	;
   610                              <1>         ;mov	cl, [Last_DOS_DiskNo] 
   611                              <1> 	;add	cl, 'A'
   612                              <1> 	;mov	[esi+LD_FS_Name], cl
   613                              <1> 
   614                              <1> loc_validate_hd_fs_partition_retn:
   615 0000442E C3                  <1> 	retn
   616                              <1> 
   617                              <1> load_masterboot:
   618                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   619                              <1> 	; 2005 - 2011
   620                              <1> 	; input -> DL = drive number
   621 0000442F B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
   622 00004431 E89EE4FFFF          <1> 	call	int13h
   623 00004436 7301                <1> 	jnc	short pass_reset_error
   624                              <1> harddisk_error:
   625 00004438 C3                  <1>   	retn
   626                              <1> pass_reset_error:
   627 00004439 BB[A2D10000]        <1> 	mov	ebx, MasterBootBuff
   628 0000443E 66B80102            <1> 	mov	ax, 0201h
   629 00004442 66B90100            <1> 	mov	cx, 1
   630 00004446 30F6                <1> 	xor	dh, dh
   631 00004448 E887E4FFFF          <1>  	call	int13h
   632 0000444D 72E9                <1> 	jc	short harddisk_error
   633                              <1> 	;
   634 0000444F 66813D[A0D30000]55- <1> 	cmp	word [MBIDCode], 0AA55h
   634 00004457 AA                  <1>
   635 00004458 7401                <1> 	je	short load_masterboot_ok
   636 0000445A F9                  <1> 	stc
   637                              <1> load_masterboot_ok:
   638 0000445B C3                  <1> 	retn
   639                              <1> 
   640                              <1> get_free_FAT_sectors:
   641                              <1> 	; 29/02/2016
   642                              <1> 	; 13/02/2016
   643                              <1> 	; 04/02/2016
   644                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   645                              <1> 	; 11/07/2010
   646                              <1> 	; 21/06/2009
   647                              <1> 	; INPUT: ESI = Logical DOS Drive Description Table address
   648                              <1> 	; OUTPUT: STC => Error
   649                              <1>         ;	cf = 0 and EAX = Free FAT sectors
   650                              <1> 	; Also, related parameters and FAT buffer will be reset and updated
   651                              <1> 
   652 0000445C 31C0                <1> 	xor	eax, eax
   653                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
   654                              <1> 	
   655 0000445E 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
   656 00004462 7650                <1> 	jna	short loc_gfc_get_fat_free_clusters
   657                              <1> 
   658                              <1> 	; 29/02/2016
   659 00004464 48                  <1> 	dec	eax ; 0FFFFFFFFh
   660 00004465 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
   661 00004468 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
   662 0000446B 40                  <1> 	inc	eax ; 0
   663                              <1> 	;
   664 0000446C 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
   665 00004470 03466C              <1> 	add	eax, [esi+LD_StartSector]
   666                              <1> 
   667 00004473 BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff
   668 00004478 B901000000          <1> 	mov	ecx, 1
   669 0000447D E809760000          <1>  	call	disk_read
   670 00004482 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
   671                              <1> retn_gfc_get_fsinfo_sec:
   672 00004484 C3                  <1> 	retn
   673                              <1> 
   674                              <1> loc_gfc_check_fsinfo_signs:
   675 00004485 BB[B5D50000]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
   676 0000448A 813B52526141        <1>         cmp     dword [ebx], 41615252h
   677 00004490 7520                <1> 	jne	short retn_gfc_get_fsinfo_stc
   678                              <1> 	;add	ebx, 484
   679                              <1> 	;cmp	dword [ebx], 61417272h
   680 00004492 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   680 0000449B 61                  <1>
   681 0000449C 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
   682                              <1> 	;add	ebx, 4
   683                              <1> 	;mov	eax, [ebx]
   684 0000449E 8B83E8010000        <1> 	mov	eax, [ebx+488]
   685                              <1> 	; 29/02/2016
   686 000044A4 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
   687 000044A7 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
   688 000044AD 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
   689                              <1> 	;
   690 000044B0 EB12                <1> 	jmp	short retn_from_get_free_fat32_clusters
   691                              <1> 
   692                              <1> retn_gfc_get_fsinfo_stc:
   693 000044B2 F9                  <1> 	stc
   694 000044B3 C3                  <1> 	retn
   695                              <1> 
   696                              <1> loc_gfc_get_fat_free_clusters:
   697                              <1> 	;mov	eax, 2
   698 000044B4 B002                <1> 	mov	al, 2
   699                              <1> 	;mov	[FAT_CurrentCluster], eax
   700                              <1> loc_gfc_loop_get_next_cluster:
   701 000044B6 E8F54F0000          <1> 	call	get_next_cluster
   702 000044BB 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
   703 000044BD 21C0                <1> 	and	eax, eax
   704 000044BF 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
   705                              <1>  
   706                              <1> retn_from_get_free_fat_clusters:
   707 000044C1 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
   708                              <1> retn_from_get_free_fat32_clusters:
   709 000044C4 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   710 000044C8 F7E3                <1>       	mul	ebx
   711                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
   712                              <1> retn_get_free_sectors_calc:
   713 000044CA C3                  <1> 	retn
   714                              <1> 
   715                              <1> loc_gfc_free_fat_clusters_cont:
   716 000044CB 09C0                <1> 	or	eax, eax
   717 000044CD 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
   718 000044CF FF4674              <1> 	inc	dword [esi+LD_FreeSectors] ; Free clusters !
   719                              <1>    
   720                              <1> loc_gfc_pass_inc_free_cluster_count:
   721                              <1> 	;mov	eax, [FAT_CurrentCluster]
   722 000044D2 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
   723 000044D4 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
   724 000044D7 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
   725 000044D9 40                  <1> 	inc	eax
   726                              <1> 	;mov	[FAT_CurrentCluster], eax
   727 000044DA EBDA                <1> 	jmp	short loc_gfc_loop_get_next_cluster
   728                              <1> 
   729                              <1> floppy_drv_init:
   730                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   731                              <1> 	; 24/07/2011
   732                              <1> 	; 04/07/2009
   733                              <1> 	; INPUT ->
   734                              <1> 	;	DL = Drive number (0,1)
   735                              <1> 	; OUTPUT ->
   736                              <1> 	;	BL = drive name
   737                              <1> 	;	BH = drive number
   738                              <1> 	;	ESI = Logical DOS drv description table
   739                              <1> 	;	EAX = Volume serial number
   740                              <1>  
   741 000044DC BE[6EC90000]        <1> 	mov	esi, fd0_type ; 10/01/2016
   742 000044E1 BF00010900          <1> 	mov	edi, Logical_DOSDisks
   743 000044E6 08D2                <1> 	or	dl, dl
   744 000044E8 7407                <1> 	jz	short loc_drv_init_fd0_fd1
   745 000044EA 81C700010000        <1> 	add	edi, 100h
   746 000044F0 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
   747                              <1> loc_drv_init_fd0_fd1:
   748 000044F1 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
   749 000044F5 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
   750                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
   751 000044F8 7221                <1> 	jb	short read_fd_boot_sector_retn
   752 000044FA 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
   753                              <1> read_fd_boot_sector:
   754 000044FD 30F6                <1> 	xor	dh, dh
   755 000044FF B904000000          <1> 	mov	ecx, 4 ; Retry Count
   756                              <1> read_fd_boot_sector_again:
   757 00004504 51                  <1> 	push 	ecx
   758                              <1> 	;mov	cx, 1
   759 00004505 B101                <1> 	mov	cl, 1
   760 00004507 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   761 0000450B BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff
   762 00004510 E8BFE3FFFF          <1> 	call	int13h
   763 00004515 59                  <1> 	pop	ecx
   764 00004516 7304                <1> 	jnc	short use_fd_boot_sector_params
   765 00004518 E2EA                <1> 	loop	read_fd_boot_sector_again
   766                              <1> 
   767                              <1> read_fd_boot_sector_stc_retn:
   768 0000451A F9                  <1> 	stc
   769                              <1> read_fd_boot_sector_retn:
   770 0000451B C3                  <1> 	retn
   771                              <1> 
   772                              <1> use_fd_boot_sector_params:
   773                              <1> 	;mov	esi, DOSBootSectorBuff
   774 0000451C 89DE                <1> 	mov	esi, ebx
   775 0000451E 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   776 00004527 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
   777 00004529 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
   778 0000452F 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
   779                              <1> 	;
   780 00004535 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
   781 00004538 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   782                              <1> 	;
   783                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   784 0000453B 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   785 0000453E 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
   786                              <1> 	;
   787 00004541 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
   788 00004544 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
   789 00004547 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   790 0000454B 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   791 0000454F 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   792 00004552 6698                <1> 	cbw
   793 00004554 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   794 00004558 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   795                              <1> 	;cbw
   796 0000455B 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   797                              <1> 	;
   798 0000455F 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   799 00004562 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   800 00004565 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
   801 00004568 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
   802 0000456B 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   803 0000456E 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   804 00004571 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   805 00004574 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   806 00004577 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
   807 0000457A 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   808                              <1> 	;		
   809 0000457D 89FE                <1> 	mov	esi, edi
   810 0000457F 8B460C              <1>  	mov	eax, [esi+LD_FS_MATLocation]
   811                              <1> 	;add	eax, [edi+LD_FS_BeginSector]
   812                              <1> read_fd_MAT_sector_again:
   813                              <1> 	;mov	ebx, DOSBootSectorBuff
   814                              <1> 	;mov	ecx, 1
   815 00004582 B101                <1> 	mov	cl, 1
   816 00004584 E808750000          <1> 	call	chs_read
   817 00004589 89DE                <1> 	mov	esi, ebx
   818 0000458B 7301                <1> 	jnc	short use_fdfs_mat_sector_params
   819                              <1> 	;jmp	short read_fd_boot_sector_retn
   820 0000458D C3                  <1> 	retn
   821                              <1> use_fdfs_mat_sector_params:
   822 0000458E 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   823 00004591 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   824 00004594 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   825 00004597 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   826 0000459A 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
   827 0000459D 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
   828 000045A0 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   829 000045A3 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   830                              <1> 	;
   831 000045A6 89FE                <1> 	mov	esi, edi
   832 000045A8 8B4608              <1>  	mov	eax, [esi+LD_FS_RootDirD]
   833                              <1> read_fd_RDT_sector_again:
   834                              <1> 	;mov	ebx, DOSBootSectorBuff
   835                              <1> 	;mov	cx, 1
   836 000045AB B101                <1> 	mov	cl, 1
   837 000045AD E8DF740000          <1> 	call	chs_read
   838 000045B2 89DE                <1> 	mov	esi, ebx
   839 000045B4 7220                <1> 	jc	short read_fd_RDT_sector_retn
   840                              <1> use_fdfs_RDT_sector_params:
   841 000045B6 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   842 000045B9 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   843 000045BC 57                  <1> 	push	edi
   844                              <1> 	;mov	ecx, 16
   845 000045BD B110                <1> 	mov	cl, 16	
   846 000045BF 83C640              <1> 	add	esi, FS_RDT_VolumeName
   847 000045C2 83C72C              <1> 	add	edi, LD_FS_VolumeName
   848 000045C5 F3A5                <1> 	rep	movsd ; 64 bytes
   849 000045C7 5E                  <1> 	pop	esi
   850 000045C8 C6460300            <1> 	mov	byte [esi+LD_FATType], 0
   851 000045CC C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
   852 000045D0 E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
   853                              <1> 
   854                              <1> read_fd_RDT_sector_stc_retn:
   855 000045D5 F9                  <1> 	stc
   856                              <1> read_fd_RDT_sector_retn:
   857 000045D6 C3                  <1> 	retn
   858                              <1> 
   859                              <1> use_fd_fatfs_boot_sector_params:
   860 000045D7 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   861 000045DB 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
   862 000045DD 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
   863 000045E1 72F3                <1> 	jb	short read_fd_RDT_sector_retn
   864 000045E3 57                  <1> 	push	edi
   865 000045E4 83C706              <1> 	add	edi, LD_BPB
   866                              <1> 	;mov	ecx, 16
   867 000045E7 B110                <1> 	mov	cl, 16
   868 000045E9 F3A5                <1> 	rep	movsd ; 64 bytes 
   869 000045EB 5E                  <1> 	pop	esi
   870 000045EC 31C0                <1> 	xor	eax, eax
   871 000045EE 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
   872 000045F1 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
   873 000045F5 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
   874 000045F8 F7E1                <1>   	mul	ecx
   875                              <1> 	; edx = 0 !
   876 000045FA 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
   877 000045FE 66895660            <1> 	mov	[esi+LD_FATBegin], dx
   878                              <1> 	;add	eax, edx
   879 00004602 6601D0              <1> 	add	ax, dx
   880 00004605 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   881 00004608 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   882 0000460B 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
   883                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
   884 0000460F 66C1E205            <1> 	shl	dx, 5
   885                              <1> 	;add	edx, 511
   886 00004613 6681C2FF01          <1> 	add	dx, 511
   887                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
   888 00004618 66C1EA09            <1> 	shr	dx, 9
   889 0000461C 015668              <1> 	add 	[esi+LD_DATABegin], edx
   890                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   891 0000461F 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   892 00004623 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   893 00004626 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
   894                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   895 00004629 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
   896 0000462C 80F901              <1> 	cmp	cl, 1
   897 0000462F 7605                <1> 	jna	short save_fd_fatfs_cluster_count
   898                              <1> 	;sub	edx, edx
   899 00004631 6629D2              <1> 	sub	dx, dx ; 0
   900 00004634 F7F1                <1> 	div	ecx
   901                              <1> save_fd_fatfs_cluster_count:
   902 00004636 894678              <1> 	mov	[esi+LD_Clusters], eax
   903                              <1> 
   904                              <1>       ; Maximum Valid Cluster Number = EAX +1
   905                              <1>       ; with 2 reserved clusters= EAX +2
   906                              <1>  
   907                              <1> reset_FAT_buffer_decriptors:
   908 00004639 29C0                <1> 	sub	eax, eax ; 0  
   909 0000463B A2[B9D70000]        <1> 	mov	[FAT_BuffValidData], al ; 0
   910 00004640 A2[BAD70000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
   911 00004645 A3[BDD70000]        <1> 	mov	[FAT_BuffSector], eax ; 0
   912                              <1> 
   913                              <1> read_fd_FAT_sectors:
   914 0000464A BB001C0900          <1>   	mov	ebx, FAT_Buffer
   915 0000464F 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
   916                              <1> 	;mov	ecx, 3
   917 00004653 B103                <1> 	mov	cl, 3 ; 3 sectors
   918 00004655 E837740000          <1> 	call	chs_read
   919 0000465A 7240                <1> 	jc	short read_fd_FAT_sectors_retn
   920                              <1> use_fd_FAT_sectors:
   921 0000465C 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
   922 0000465F 0441                <1> 	add	al, 'A' 
   923 00004661 A2[BAD70000]        <1> 	mov	[FAT_BuffDrvName], al 
   924 00004666 C605[B9D70000]01    <1>  	mov	byte [FAT_BuffValidData], 1
   925 0000466D E82B000000          <1> 	call	fd_init_calculate_free_clusters
   926 00004672 7228                <1> 	jc	short read_fd_FAT_sectors_retn
   927                              <1>   
   928                              <1> loc_use_fd_boot_sector_params_FAT:
   929 00004674 C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
   930 00004678 C6460401            <1> 	mov	byte [esi+LD_FSType], 1
   931 0000467C 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
   932                              <1> loc_cont_use_fd_boot_sector_params:
   933 0000467F 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
   934 00004682 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
   935 00004685 88FB                <1> 	mov	bl, bh
   936 00004687 80C341              <1> 	add	bl, 'A'
   937 0000468A 881E                <1> 	mov	byte [esi+LD_Name], bl
   938 0000468C C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
   939 00004690 C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
   940 00004694 C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
   941 00004698 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
   942                              <1> 
   943                              <1> read_fd_FAT_sectors_retn:
   944 0000469C C3                  <1> 	retn   
   945                              <1> 
   946                              <1> fd_init_calculate_free_clusters:
   947                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   948                              <1> 	; 04/07/2009
   949                              <1> 	; INPUT ->
   950                              <1> 	;     ESI = Logical DOS drive description table address
   951                              <1> 	; OUTPUT ->
   952                              <1> 	;    [ESI+LD_FreeSectors] will be set
   953                              <1> 	
   954 0000469D 29C0                <1> 	sub	eax, eax
   955 0000469F 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
   956 000046A2 B002                <1> 	mov	al, 2 ; eax = 2
   957                              <1> 
   958                              <1> fd_init_loop_get_next_cluster:
   959 000046A4 E830000000          <1> 	call	fd_init_get_next_cluster
   960 000046A9 722D                <1> 	jc	short fd_init_calculate_free_clusters_retn
   961                              <1> 
   962                              <1> fd_init_free_fat_clusters:
   963                              <1> 	;cmp 	eax, 0
   964                              <1> 	;ja	short fd_init_pass_inc_free_cluster_count
   965                              <1> 	;and	eax, eax
   966                              <1> 	;jnz	short fd_init_pass_inc_free_cluster_count
   967 000046AB 6621C0              <1> 	and	ax, ax
   968 000046AE 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
   969                              <1> 	;inc	dword [esi+LD_FreeSectors]
   970 000046B0 66FF4674            <1>         inc	word [esi+LD_FreeSectors]
   971                              <1>     
   972                              <1> fd_init_pass_inc_free_cluster_count:
   973                              <1>   	;mov	eax, [FAT_CurrentCluster]
   974 000046B4 66A1[B5D70000]      <1> 	mov	ax, [FAT_CurrentCluster]
   975                              <1> 	;cmp	eax, [esi+LD_Clusters]
   976 000046BA 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
   977 000046BE 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
   978                              <1> 	;inc	eax
   979 000046C0 6640                <1> 	inc	ax
   980 000046C2 EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
   981                              <1> 
   982                              <1> retn_from_fd_init_calculate_free_clusters:
   983 000046C4 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
   984 000046C7 3C01                <1>   	cmp	al, 1
   985 000046C9 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
   986                              <1> 	;movzx	eax, al
   987 000046CB 6698                <1> 	cbw
   988                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
   989 000046CD 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
   990                              <1>   	;mul	ecx
   991 000046D1 66F7E1              <1> 	mul	cx
   992                              <1> 	;mov	[esi+LD_FreeSectors], eax
   993 000046D4 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
   994                              <1> fd_init_calculate_free_clusters_retn:
   995 000046D8 C3                  <1> 	retn
   996                              <1> 
   997                              <1> fd_init_get_next_cluster:
   998                              <1> 	; 04/02/2016
   999                              <1> 	; 02/02/2016
  1000                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1001                              <1> 	; 04/07/2009
  1002                              <1> 	; INPUT ->
  1003                              <1> 	;    EAX = Current cluster
  1004                              <1> 	;    ESI = Logical DOS drive description table address
  1005                              <1> 	;    EDX = 0
  1006                              <1> 	; OUTPUT ->
  1007                              <1> 	;    EAX = Next cluster
  1008                              <1> 
  1009 000046D9 A3[B5D70000]        <1> 	mov	[FAT_CurrentCluster], eax
  1010                              <1> fd_init_get_next_cluster_readnext:
  1011 000046DE 29D2                <1> 	sub	edx, edx ; 0
  1012 000046E0 BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1013 000046E5 F7F3                <1>   	div	ebx
  1014                              <1>   	; EAX = Count of 3 FAT sectors
  1015                              <1>   	; EDX = Buffer entry index
  1016 000046E7 89C1                <1> 	mov	ecx, eax
  1017                              <1> 	;mov	eax, 3
  1018 000046E9 B003                <1> 	mov	al, 3
  1019 000046EB F7E2                <1> 	mul	edx ; Multiply by 3
  1020 000046ED 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1021 000046F0 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1022 000046F2 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1023 000046F8 89C8                <1> 	mov	eax, ecx
  1024                              <1> 	;mov	edx, 3
  1025 000046FA 66BA0300            <1> 	mov	dx, 3
  1026 000046FE F7E2                <1> 	mul	edx 
  1027                              <1>   	; EAX = FAT Beginning Sector
  1028                              <1> 	; EDX = 0
  1029 00004700 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1030                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1031                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1032 00004702 3A0D[BAD70000]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1033 00004708 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1034 0000470A 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
  1035 00004710 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1036                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1037 00004712 A0[B5D70000]        <1> 	mov	al, [FAT_CurrentCluster]
  1038                              <1> 	;shr	eax, 1
  1039 00004717 D0E8                <1> 	shr	al, 1
  1040 00004719 668B03              <1> 	mov	ax, [ebx]
  1041 0000471C 7306                <1>   	jnc	short fd_init_gnc_even
  1042 0000471E 66C1E804            <1> 	shr	ax, 4
  1043                              <1> fd_init_gnc_clc_retn:
  1044 00004722 F8                  <1> 	clc
  1045 00004723 C3                  <1> 	retn
  1046                              <1> 
  1047                              <1> fd_init_gnc_even:
  1048 00004724 80E40F              <1> 	and	ah, 0Fh
  1049 00004727 C3                  <1> 	retn
  1050                              <1> 
  1051                              <1> fd_init_load_FAT_sectors0:
  1052 00004728 880D[BAD70000]      <1> 	mov 	[FAT_BuffDrvName], cl
  1053                              <1> fd_init_load_FAT_sectors1:
  1054 0000472E C605[B9D70000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1055 00004735 A3[BDD70000]        <1> 	mov	[FAT_BuffSector], eax
  1056 0000473A 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1057 0000473D BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1058                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1059 00004742 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1060 00004746 662B0D[BDD70000]    <1> 	sub	cx, [FAT_BuffSector]
  1061                              <1>         ;cmp	ecx, 3
  1062 0000474D 6683F903            <1> 	cmp	cx, 3
  1063 00004751 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1064                              <1> 	;mov	ecx, 3
  1065 00004753 B903000000          <1> 	mov	ecx, 3
  1066                              <1> fdinit_pass_fix_sector_count_3:  
  1067 00004758 E834730000          <1> 	call	chs_read
  1068 0000475D 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1069 0000475F C605[B9D70000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1070                              <1> 		; Drv not ready or read Error !
  1071 00004766 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1072                              <1> 	;xor	edx, edx
  1073 0000476B C3                  <1> 	retn
  1074                              <1> 
  1075                              <1> fd_init_FAT_sectors_no_load_error:
  1076 0000476C C605[B9D70000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1077 00004773 A1[B5D70000]        <1> 	mov	eax, [FAT_CurrentCluster]
  1078 00004778 E961FFFFFF          <1>         jmp     fd_init_get_next_cluster_readnext
  1079                              <1> 
  1080                              <1> get_FAT_volume_name:
  1081                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1082                              <1> 	; 12/09/2009
  1083                              <1> 	; INPUT ->
  1084                              <1> 	;	BH = Logical DOS drive number (0,1,2,3,4 ...)
  1085                              <1> 	;       BL = 0
  1086                              <1> 	; OUTPUT ->
  1087                              <1> 	;	CF = 0 -> ESI = Volume name address
  1088                              <1> 	; 	CF = 1 -> Root volume name not found
  1089                              <1> 
  1090                              <1> 	;mov 	ah, 0FFh
  1091                              <1> 	;mov 	al, [Last_Dos_DiskNo]
  1092                              <1> 	;cmp 	al, bh
  1093                              <1> 	;jb     short loc_gfvn_dir_load_err
  1094                              <1> 
  1095 0000477D 89DE                <1> 	mov	esi, ebx
  1096 0000477F 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1097 00004785 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1098 0000478B 8A06                <1> 	mov     al, [esi+LD_Name]
  1099 0000478D 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1100 00004790 80FC01              <1> 	cmp     ah, 1
  1101 00004793 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1102 00004795 3C41                <1> 	cmp 	al, 'A'
  1103 00004797 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1104 00004799 80FC02              <1> 	cmp 	ah, 2 
  1105 0000479C 7708                <1> 	ja      short get_FAT32_root_cluster
  1106                              <1> 	
  1107 0000479E E8684E0000          <1> 	call    load_FAT_root_directory
  1108 000047A3 730B                <1> 	jnc     short loc_get_volume_name
  1109                              <1> 
  1110                              <1> loc_gfvn_dir_load_err:
  1111 000047A5 C3                  <1> 	retn
  1112                              <1> 
  1113                              <1> get_FAT32_root_cluster:
  1114 000047A6 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1115 000047A9 E8E84E0000          <1> 	call    load_FAT_sub_directory
  1116 000047AE 7224                <1> 	jc	short loc_get_volume_name_retn
  1117                              <1> 
  1118                              <1> loc_get_volume_name:
  1119 000047B0 BE00000800          <1>         mov     esi, Directory_Buffer
  1120 000047B5 6631C9              <1> 	xor	cx, cx ; 0
  1121                              <1> check_root_volume_name:
  1122 000047B8 8A06                <1> 	mov	al, [esi]
  1123 000047BA 08C0                <1> 	or      al, al
  1124 000047BC 7416                <1> 	jz      short loc_get_volume_name_retn
  1125 000047BE 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1126 000047C2 7410                <1> 	je      short loc_get_volume_name_retn
  1127 000047C4 663B0D[CFD70000]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1128 000047CB 7308                <1> 	jnb     short pass_check_root_volume_name
  1129 000047CD 6641                <1> 	inc     cx
  1130 000047CF 83C620              <1> 	add     esi, 32
  1131 000047D2 EBE4                <1> 	jmp     short check_root_volume_name
  1132                              <1> 
  1133                              <1> loc_get_volume_name_retn:
  1134 000047D4 C3                  <1> 	retn
  1135                              <1>     
  1136                              <1> pass_check_root_volume_name:
  1137 000047D5 803D[CBD70000]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1138 000047DC 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1139                              <1> 
  1140 000047DE BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1141 000047E3 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1142 000047E8 31C0                <1> 	xor	eax, eax
  1143 000047EA 8A25[CAD70000]      <1> 	mov	ah, [DirBuff_DRV]
  1144 000047F0 80EC41              <1> 	sub	ah, 'A' 
  1145 000047F3 01C6                <1> 	add	esi, eax
  1146 000047F5 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
  1147 000047FA E8B14C0000          <1> 	call	get_next_cluster
  1148 000047FF 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1149                              <1>   	
  1150 00004801 83F801              <1> 	cmp     eax, 1
  1151 00004804 F5                  <1> 	cmc
  1152 00004805 C3                  <1> 	retn
  1153                              <1>   
  1154                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1155 00004806 E88B4E0000          <1> 	call	load_FAT_sub_directory
  1156 0000480B 73A3                <1> 	jnc	short loc_get_volume_name
  1157 0000480D C3                  <1> 	retn
  1158                              <1> 
  1159                              <1> loc_get_volume_name_retn_xor:
  1160 0000480E 31C0                <1> 	xor 	eax, eax
  1161 00004810 C3                  <1> 	retn
  1162                              <1> 
  1163                              <1> get_media_change_status:
  1164                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1165                              <1> 	; 09/09/2009
  1166                              <1> 	; INPUT:
  1167                              <1> 	;     DL = Drive number (physical)
  1168                              <1> 	; OUTPUT: clc & AH = 6 media changed
  1169                              <1> 	;     clc & AH = 0 media not changed         
  1170                              <1> 	;     stc -> Drive not ready or an error 
  1171                              <1>   
  1172 00004811 B416                <1> 	mov	ah, 16h
  1173 00004813 E8BCE0FFFF          <1>   	call	int13h
  1174 00004818 80FC06              <1> 	cmp	ah, 06h
  1175 0000481B 7405                <1> 	je	short loc_gmc_status_retn
  1176 0000481D 08E4                <1> 	or	ah, ah
  1177 0000481F 7401                <1> 	jz	short loc_gmc_status_retn
  1178                              <1> loc_gmc_status_stc_retn:    
  1179 00004821 F9                  <1> 	stc
  1180                              <1> loc_gmc_status_retn:
  1181 00004822 C3                  <1> 	retn
  1926                                  %include 'trdosk3.s' ; 06/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk3.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 07/05/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 06/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; MAINPROG.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; MAINPROG.ASM [ TRDOS KERNEL - COMMAND EXECUTER SECTION - MAIN PROGRAM ]
    14                              <1> ; (c) 2004-2011  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/11/2011
    15                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ] Last Update: 09/11/2011
    16                              <1> ; DIR.ASM [ DIRECTORY FUNCTIONS ] Last Update: 09/10/2011
    17                              <1> ; FILE.ASM [ FILE FUNCTIONS ] Last Update: 09/10/2011
    18                              <1> 
    19                              <1> change_current_drive:
    20                              <1> 	; 02/02/2016
    21                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
    22                              <1> 	; 18/08/2011
    23                              <1> 	; 09/09/2009
    24                              <1> 	; INPUT:
    25                              <1> 	;   DL = Logical DOS Drive Number
    26                              <1> 	; OUTPUT:
    27                              <1> 	;  cf=1 -> Not successful
    28                              <1> 	;   EAX = Error code
    29                              <1> 	;  cf=0 ->
    30                              <1> 	;   EAX = 0 (successful)
    31                              <1> 
    32 00004823 31DB                <1> 	xor	ebx, ebx
    33 00004825 88D7                <1> 	mov	bh, dl
    34                              <1> 
    35                              <1> 	;cmp	dl, 1
    36                              <1> 	;jna	short loc_ccdrv_initial_media_change_check
    37                              <1> 	;cmp	bh, [Last_Dos_DiskNo]
    38                              <1> 	;ja	short loc_ccdrv_drive_not_ready_err
    39                              <1> 
    40                              <1> loc_ccdrv_initial_media_change_check:
    41 00004827 BE00010900          <1> 	mov	esi, Logical_DOSDisks
    42 0000482C 01DE                <1> 	add	esi, ebx
    43                              <1> loc_ccdrv_dos_drive_name_check:
    44 0000482E 80FA02              <1> 	cmp	dl, 2
    45 00004831 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    46                              <1> 
    47 00004833 8A06                <1> 	mov	al, [esi+LD_Name]
    48 00004835 2C41                <1> 	sub	al, 'A'
    49 00004837 38D0                <1> 	cmp	al, dl
    50 00004839 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    51                              <1> 
    52                              <1> loc_ccdrv_drive_not_ready_err:
    53 0000483B B815000000          <1> 	mov	eax, 15h ; Drive not ready
    54                              <1> loc_change_current_drive_stc_retn:
    55 00004840 F9                  <1> 	stc
    56 00004841 C3                  <1> 	retn  
    57                              <1> 
    58                              <1> loc_ccdrv_dos_drive_name_check_ok:
    59 00004842 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    60 00004845 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    61 00004848 7450                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    62                              <1> 
    63 0000484A 80FA01              <1> 	cmp	dl, 1
    64 0000484D 7778                <1> 	ja	short loc_gmcs_init_drv_hd
    65                              <1> 
    66                              <1> loc_gmcs_init_drv_fd:
    67 0000484F 08E4                <1> 	or	ah, ah 
    68                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    69 00004851 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    70                              <1> 
    71 00004853 E8B9FFFFFF          <1> 	call	get_media_change_status
    72 00004858 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    73                              <1> 
    74 0000485A 20E4                <1> 	and	ah, ah
    75 0000485C 7471                <1> 	jz	short loc_change_current_drv3
    76                              <1> 
    77 0000485E 80F406              <1> 	xor	ah, 6
    78 00004861 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    79                              <1> 
    80                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    81 00004863 E84B0A0000          <1> 	call	get_volume_serial_number
    82 00004868 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
    83                              <1> 
    84                              <1> loc_ccdrv_call_fd_init:
    85 0000486A E86DFCFFFF          <1> 	call	floppy_drv_init
    86 0000486F 7315                <1> 	jnc	short loc_reset_drv_fd_current_dir
    87                              <1> 
    88                              <1> loc_ccdrv_fdinit_fail_retn:
    89 00004871 C3                  <1> 	retn
    90                              <1> 
    91                              <1> loc_ccdrv_check_vol_serial:
    92 00004872 A3[98CF0000]        <1> 	mov	[Current_VolSerial], eax
    93                              <1> 	;mov	dl, bh
    94 00004877 E860FCFFFF          <1> 	call	floppy_drv_init
    95 0000487C 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
    96                              <1> 
    97 0000487E 3B05[98CF0000]      <1> 	cmp	eax, [Current_VolSerial]
    98 00004884 7445                <1> 	je	short loc_change_current_drv2
    99                              <1> 
   100                              <1> loc_reset_drv_fd_current_dir:
   101 00004886 31C0                <1> 	xor	eax, eax              
   102 00004888 88467F              <1>         mov	[esi+LD_CDirLevel], al
   103 0000488B 89F7                <1> 	mov	edi, esi
   104 0000488D 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   105 00004893 B920000000          <1> 	mov	ecx, 32
   106 00004898 F3AB                <1> 	rep	stosd   
   107                              <1>  
   108                              <1> loc_ccdrv_get_FAT_volume_name_0:
   109 0000489A 8A4603              <1> 	mov	al, [esi+LD_FATType]
   110 0000489D 08C0                <1> 	or	al, al
   111 0000489F 742A                <1> 	jz	short loc_change_current_drv2
   112                              <1> 
   113 000048A1 56                  <1> 	push	esi 
   114 000048A2 3C02                <1> 	cmp	al, 2
   115 000048A4 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   116                              <1>              
   117                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   118 000048A6 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   119 000048A9 EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   120                              <1> 
   121                              <1> loc_ccdrv_get_FAT32_vol_name:
   122 000048AB 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   123                              <1> loc_ccdrv_get_FAT_volume_name_1:
   124 000048AE 53                  <1> 	push	ebx
   125 000048AF 56                  <1> 	push	esi
   126 000048B0 E8C8FEFFFF          <1> 	call	get_FAT_volume_name
   127 000048B5 5F                  <1> 	pop	edi
   128 000048B6 5B                  <1> 	pop	ebx
   129                              <1> 	; BL = 0
   130 000048B7 720B                <1> 	jc	short loc_change_current_drv1
   131 000048B9 20C0                <1> 	and	al, al
   132 000048BB 7407                <1> 	jz	short loc_change_current_drv1
   133                              <1> 
   134                              <1> loc_ccdrv_move_FAT_volume_name:
   135 000048BD B90B000000          <1> 	mov	ecx, 11
   136 000048C2 F3A4                <1> 	rep	movsb
   137                              <1> 
   138                              <1> loc_change_current_drv1:
   139 000048C4 5E                  <1> 	pop	esi
   140 000048C5 EB04                <1> 	jmp	short loc_change_current_drv2
   141                              <1> 
   142                              <1> loc_gmcs_init_drv_hd:
   143 000048C7 08E4                <1> 	or	ah, ah
   144 000048C9 7404                <1> 	jz	short loc_change_current_drv3
   145                              <1> 	; BL = 0, BH = Logical DOS drive number
   146                              <1> loc_change_current_drv2:
   147 000048CB C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   148                              <1> loc_change_current_drv3:
   149 000048CF 883D[A2CF0000]      <1> 	mov	[Current_Drv], bh
   150                              <1> 
   151                              <1> 	;call	restore_current_directory
   152                              <1> 	;retn
   153                              <1> 
   154                              <1> restore_current_directory:
   155                              <1> 	; 11/02/2016
   156                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
   157                              <1> 	; 25/01/2010
   158                              <1> 	; 12/10/2009
   159                              <1> 	;
   160                              <1> 	; INPUT:
   161                              <1> 	;   ESI = Logical DOS Drive Description Table
   162                              <1> 	;
   163                              <1> 	; OUTPUT:
   164                              <1> 	;   ESI = Logical DOS Drive Description Table
   165                              <1> 	;   EDI = offset Current_Dir_Drv 
   166                              <1> 
   167 000048D5 8A4603              <1> 	mov	al, [esi+LD_FATType]
   168 000048D8 A2[A1CF0000]        <1> 	mov	[Current_FATType], al
   169                              <1> 
   170 000048DD 8A26                <1> 	mov	ah, [esi+LD_Name] 
   171 000048DF 8825[A3CF0000]      <1> 	mov	[Current_Dir_Drv], ah
   172                              <1> 
   173 000048E5 20C0                <1> 	and	al, al
   174 000048E7 741D                <1> 	jz	short loc_restore_FS_current_directory
   175                              <1> 
   176                              <1> loc_restore_FAT_current_directory:
   177 000048E9 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   178 000048EC 8825[A0CF0000]      <1> 	mov	[Current_Dir_Level], ah
   179 000048F2 08E4                <1> 	or	ah, ah
   180 000048F4 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   181                              <1> 
   182 000048F6 0FB6D4              <1> 	movzx	edx, ah
   183 000048F9 C0E204              <1> 	shl	dl, 4 ; * 16
   184 000048FC 01F2                <1>         add	edx, esi
   185 000048FE 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   186 00004904 EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   187                              <1> 
   188                              <1> loc_restore_FS_current_directory:
   189 00004906 E8C64D0000          <1> 	call	load_current_FS_directory 
   190 0000490B C3                  <1> 	retn 
   191                              <1> 
   192                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   193 0000490C 3C03                <1> 	cmp	al, 3
   194 0000490E 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   195                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   196 00004910 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   197 00004913 EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   198                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   199 00004915 30C0                <1> 	xor	al, al  ; xor eax, eax
   200 00004917 31D2                <1> 	xor	edx, edx
   201                              <1> loc_ccdrv_check_rootdir_sign:
   202 00004919 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   203 00004920 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   204                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   205 00004922 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   206 00004928 C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   206 00004931 54                  <1>
   207                              <1> 
   208                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   209 00004932 A3[9CCF0000]        <1> 	mov	[Current_Dir_FCluster], eax
   210                              <1> 
   211 00004937 BF[03D80000]        <1> 	mov	edi, PATH_Array
   212 0000493C 89F2                <1> 	mov	edx, esi
   213 0000493E 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   214 00004944 B920000000          <1> 	mov	ecx, 32
   215 00004949 F3A5                <1> 	rep	movsd
   216                              <1> 
   217 0000494B E8752D0000          <1> 	call	change_prompt_dir_string
   218                              <1> 	
   219 00004950 89D6                <1> 	mov	esi, edx
   220                              <1> 	
   221 00004952 29C0                <1>         sub	eax, eax
   222                              <1>        ;sub	edx, edx
   223 00004954 BF[A3CF0000]        <1> 	mov	edi, Current_Dir_Drv
   224                              <1> 
   225 00004959 A2[C6BD0000]        <1> 	mov	[Restore_CDIR], al ; 0
   226 0000495E C3                  <1> 	retn
   227                              <1> 
   228                              <1> dos_prompt:
   229                              <1> 	; 06/05/2016
   230                              <1> 	; 30/01/2016
   231                              <1> 	; 29/01/2016
   232                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   233                              <1> 	; 15/09/2011
   234                              <1> 	; 13/09/2009
   235                              <1> 	; 2004-2005
   236                              <1> 
   237                              <1> 	; 06/05/2016
   238 0000495F C705[50DC0000]-     <1> 	mov	dword [mainprog_return_addr], return_from_command_intepreter
   238 00004965 [134A0000]          <1>
   239                              <1> 
   240                              <1> loc_TRDOS_prompt:
   241 00004969 BF[A2D00000]        <1> 	mov	edi, TextBuffer
   242 0000496E C6075B              <1> 	mov	byte [edi], "["
   243 00004971 47                  <1> 	inc	edi
   244 00004972 BE[19BE0000]        <1> 	mov	esi, TRDOSPromptLabel
   245                              <1> get_next_prompt_label_char:
   246 00004977 803E20              <1> 	cmp	byte [esi], 20h
   247 0000497A 7203                <1> 	jb	short pass_prompt_label
   248 0000497C A4                  <1> 	movsb
   249 0000497D EBF8                <1> 	jmp	short get_next_prompt_label_char
   250                              <1> pass_prompt_label:
   251 0000497F C6075D              <1> 	mov	byte [edi], "]"
   252 00004982 47                  <1> 	inc	edi
   253 00004983 C60720              <1> 	mov	byte [edi], 20h
   254 00004986 47                  <1> 	inc	edi
   255 00004987 BE[A3CF0000]        <1> 	mov	esi, Current_Dir_Drv
   256 0000498C 66A5                <1> 	movsw
   257 0000498E A4                  <1> 	movsb 
   258                              <1> loc_prompt_current_directory:
   259 0000498F 803E20              <1> 	cmp	byte [esi], 20h
   260 00004992 7203                <1> 	jb	short pass_prompt_current_directory
   261 00004994 A4                  <1> 	movsb
   262 00004995 EBF8                <1> 	jmp	short loc_prompt_current_directory  
   263                              <1> pass_prompt_current_directory:
   264 00004997 C6073E              <1> 	mov	byte [edi], '>'
   265 0000499A 47                  <1> 	inc	edi
   266 0000499B C60700              <1> 	mov	byte [edi], 0  
   267 0000499E BE[A2D00000]        <1> 	mov	esi, TextBuffer
   268 000049A3 E877F5FFFF          <1> 	call	print_msg
   269                              <1>         
   270                              <1> 	;sub	bl, bl ; video page = 0
   271                              <1> 	;call	get_cpos ; get cursor position
   272 000049A8 668B15[F8CE0000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   273 000049AF 8815[02D00000]      <1> 	mov	[CursorColumn], dl
   274                              <1> 
   275                              <1> 	; 30/01/2016 (to show cursor on the row, again)
   276                              <1> 	; (Initial color attributes of video page 0 is 0)
   277                              <1> 	; (see: 'StartPMP' in trdos386.s)
   278                              <1> 	; 
   279                              <1> 	;mov	edi, 0B8000h ; start of video page 0
   280                              <1> 	;movzx	ecx, dl ; column	 
   281                              <1> 	;mov	al, 80
   282                              <1> 	;mul	dh
   283                              <1> 	;add	ax, cx
   284                              <1> 	;shl	ax, 1 ; character + attribute
   285                              <1> 	;add	di, ax ; (2*80*row) + (2*column)
   286                              <1> 	;neg	cl
   287                              <1> 	;add	cl, 80
   288                              <1> 	;mov	ax, 700h ;  ah = 7 (color attribute)
   289                              <1> 	;rep	stosw	
   290                              <1> 
   291                              <1> loc_rw_char:
   292 000049B5 E899000000          <1> 	call	rw_char
   293                              <1> loc_move_command:
   294 000049BA BE[52D00000]        <1> 	mov	esi, CommandBuffer
   295 000049BF 89F7                <1> 	mov	edi, esi
   296 000049C1 31C9                <1> 	xor	ecx, ecx
   297                              <1> first_command_char:
   298 000049C3 AC                  <1> 	lodsb
   299 000049C4 3C20                <1> 	cmp	al, 20h
   300 000049C6 772E                <1> 	ja	short pass_space_control
   301 000049C8 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   302 000049CA 81FE[A1D00000]      <1> 	cmp	esi, CommandBuffer + 79
   303 000049D0 72F1                <1> 	jb	short first_command_char
   304 000049D2 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   305                              <1> 
   306                              <1> next_command_char:
   307 000049D4 AC                  <1> 	lodsb
   308 000049D5 3C20                <1> 	cmp	al, 20h
   309 000049D7 771D                <1> 	ja	short pass_space_control
   310 000049D9 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   311                              <1> 
   312                              <1> loc_1st_cmd_arg: ; 30/01/2016
   313 000049DB AC                  <1> 	lodsb
   314 000049DC 3C20                <1> 	cmp	al, 20h
   315 000049DE 74FB                <1> 	je	short loc_1st_cmd_arg
   316 000049E0 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   317                              <1> 	
   318 000049E2 C60700              <1>         mov     byte [edi], 0
   319 000049E5 47                  <1> 	inc	edi
   320                              <1> 
   321                              <1> loc_move_cmd_arguments:
   322 000049E6 AA                  <1> 	stosb
   323 000049E7 81FE[A1D00000]      <1> 	cmp	esi, CommandBuffer + 79
   324 000049ED 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   325 000049EF AC                  <1>         lodsb
   326 000049F0 3C20                <1> 	cmp	al, 20h
   327 000049F2 73F2                <1> 	jnb	short loc_move_cmd_arguments
   328 000049F4 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   329                              <1> 
   330                              <1> pass_space_control:
   331 000049F6 3C61                <1> 	cmp	al, 61h
   332 000049F8 7206                <1> 	jb	short pass_capitalize
   333 000049FA 3C7A                <1> 	cmp	al, 7Ah
   334 000049FC 7702                <1> 	ja	short pass_capitalize
   335 000049FE 24DF                <1> 	and	al, 0DFh
   336                              <1> pass_capitalize:
   337 00004A00 AA                  <1> 	stosb   
   338 00004A01 FEC1                <1> 	inc     cl
   339 00004A03 81FE[A1D00000]      <1>         cmp     esi, CommandBuffer + 79
   340 00004A09 72C9                <1> 	jb      short next_command_char 
   341                              <1> 
   342                              <1> loc_move_cmd_arguments_ok:
   343 00004A0B C60700              <1>         mov     byte [edi], 0
   344                              <1>        
   345                              <1> call_command_intepreter:
   346 00004A0E E8DB080000          <1> 	call    command_interpreter
   347                              <1> 
   348                              <1> return_from_command_intepreter:
   349 00004A13 B950000000          <1>         mov	ecx, 80
   350                              <1> 	;mov	cx, 80
   351 00004A18 BF[52D00000]        <1> 	mov	edi, CommandBuffer
   352 00004A1D 30C0                <1> 	xor	al, al
   353 00004A1F F3AA                <1> 	rep	stosb
   354                              <1> 	;cmp	byte [Program_Exit], 0
   355                              <1> 	;ja	short loc_terminate_trdos
   356                              <1>         
   357                              <1> 	; 16/01/2016
   358 00004A21 803D[C6C80000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   359 00004A28 741D                <1> 	je	short pass_set_txt_mode
   360                              <1> 
   361 00004A2A E8D3CAFFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   362                              <1> 
   363                              <1> loc_check_active_page:
   364 00004A2F 30C0                <1> 	xor	al, al
   365 00004A31 3805[08CF0000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   366 00004A37 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   367                              <1> 	; AL = 0 = video page 0
   368 00004A3D E85ACBFFFF          <1> 	call	set_active_page
   369 00004A42 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   370                              <1> 
   371                              <1> pass_set_txt_mode: 
   372 00004A47 BE[76CB0000]        <1> 	mov	esi, nextline
   373 00004A4C E8CEF4FFFF          <1> 	call	print_msg
   374 00004A51 EBDC                <1> 	jmp     short loc_check_active_page
   375                              <1> 
   376                              <1> rw_char:
   377                              <1> 	; 30/01/2016
   378                              <1> 	; 29/01/2016
   379                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   380                              <1> 	; 2004-2005
   381                              <1> 	
   382                              <1> 	; DH = cursor row, DL = cursor column
   383                              <1> 	; BL = 0 = video page number (active page)
   384                              <1> 
   385                              <1> readnextchar:
   386 00004A53 30E4                <1> 	xor     ah, ah
   387 00004A55 E895C1FFFF          <1> 	call	int16h
   388 00004A5A 20C0                <1> 	and	al, al
   389 00004A5C 7439                <1> 	jz	short loc_arrow    
   390 00004A5E 3CE0                <1> 	cmp	al, 0E0h          
   391 00004A60 7435                <1> 	je	short loc_arrow
   392 00004A62 3C08                <1> 	cmp	al, 08h             
   393 00004A64 7549                <1> 	jne	short char_return
   394                              <1> loc_back:
   395 00004A66 3A15[02D00000]      <1> 	cmp	dl, [CursorColumn]
   396 00004A6C 76E5                <1> 	jna     short readnextchar
   397                              <1> prev_column:
   398 00004A6E FECA                <1> 	dec	dl
   399                              <1> set_cursor_pos:
   400 00004A70 6652                <1> 	push	dx
   401 00004A72 30DB                <1> 	xor	bl, bl ; 0 = video page 0
   402                              <1> 	; DH = Row, DL = Column
   403 00004A74 E8DACDFFFF          <1> 	call	_set_cpos ; 17/01/2016
   404 00004A79 665A                <1>         pop	dx
   405 00004A7B 0FB6DA              <1> 	movzx	ebx, dl
   406 00004A7E 2A1D[02D00000]      <1> 	sub	bl, [CursorColumn] 
   407 00004A84 B407                <1> 	mov	ah, 7 ; color attribute
   408 00004A86 B020                <1> 	mov	al, 20h
   409 00004A88 8883[52D00000]      <1> 	mov	[CommandBuffer+ebx], al
   410 00004A8E 28DB                <1> 	sub	bl, bl ; video page 0
   411                              <1> 	;mov	cx, 1
   412 00004A90 E8F9CCFFFF          <1> 	call	_write_c_current ; 17/01/2016
   413                              <1> 	;mov	dx, [CURSOR_POSN]
   414 00004A95 EBBC                <1> 	jmp	short readnextchar
   415                              <1> loc_arrow:    
   416 00004A97 80FC4B              <1> 	cmp	ah, 4Bh
   417 00004A9A 74CA                <1> 	je	short loc_back
   418 00004A9C 80FC53              <1> 	cmp	ah, 53h
   419 00004A9F 74C5                <1> 	je      short loc_back
   420 00004AA1 80FC4D              <1> 	cmp	ah, 4Dh
   421 00004AA4 75AD                <1> 	jne	short readnextchar
   422 00004AA6 80FA4F              <1> 	cmp	dl, 79
   423 00004AA9 73A8                <1> 	jnb	short readnextchar
   424 00004AAB FEC2                <1> 	inc	dl
   425 00004AAD EBC1                <1> 	jmp	short set_cursor_pos
   426                              <1> char_return:
   427 00004AAF 0FB6DA              <1> 	movzx	ebx, dl
   428 00004AB2 2A1D[02D00000]      <1> 	sub	bl, [CursorColumn] 
   429 00004AB8 3C20                <1> 	cmp	al, 20h
   430 00004ABA 7220                <1> 	jb	short loc_escape
   431 00004ABC 8883[52D00000]      <1> 	mov	[CommandBuffer+ebx], al
   432 00004AC2 28DB                <1> 	sub	bl, bl ; 0
   433 00004AC4 80FA4F              <1> 	cmp	dl, 79
   434 00004AC7 738A                <1> 	jnb	short readnextchar
   435 00004AC9 B407                <1> 	mov	ah, 7 ; color attribute
   436 00004ACB E8EFCCFFFF          <1> 	call	WRITE_TTY
   437 00004AD0 668B15[F8CE0000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   438 00004AD7 E977FFFFFF          <1>         jmp     readnextchar
   439                              <1> loc_escape:
   440 00004ADC 3C1B                <1> 	cmp	al, 1Bh
   441 00004ADE 741A                <1> 	je	short rw_char_retn
   442                              <1> 	;
   443 00004AE0 3C0D                <1> 	cmp	al, 0Dh ; CR
   444 00004AE2 0F856BFFFFFF        <1>         jne     readnextchar
   445 00004AE8 30DB                <1> 	xor	bl, bl ; 0
   446 00004AEA B407                <1> 	mov	ah, 7 ; attribute/color
   447 00004AEC E8CECCFFFF          <1> 	call	WRITE_TTY
   448 00004AF1 B407                <1> 	mov	ah, 7 ; attribute/color
   449 00004AF3 B00A                <1> 	mov	al, 0Ah ; LF
   450 00004AF5 E8C5CCFFFF          <1> 	call	WRITE_TTY
   451                              <1> rw_char_retn:
   452 00004AFA C3                  <1> 	retn
   453                              <1> 
   454                              <1> show_date:
   455                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   456                              <1>         ; 2004-2005
   457                              <1> 
   458                              <1> 	;mov	ah, 04h
   459                              <1> 	;call	int1Ah
   460 00004AFB E84AF1FFFF          <1> 	call	RTC_40	; GET RTC DATE
   461                              <1> 
   462 00004B00 88D0                <1> 	mov	al, dl
   463 00004B02 E8DFC0FFFF          <1>   	call	bcd_to_ascii
   464 00004B07 66A3[0EBF0000]      <1> 	mov	[Day], ax
   465                              <1> 
   466 00004B0D 88F0                <1> 	mov	al, dh
   467 00004B0F E8D2C0FFFF          <1>   	call	bcd_to_ascii
   468 00004B14 66A3[11BF0000]      <1> 	mov	[Month], ax
   469                              <1> 
   470 00004B1A 88E8                <1> 	mov	al, ch
   471 00004B1C E8C5C0FFFF          <1>   	call	bcd_to_ascii
   472 00004B21 66A3[14BF0000]      <1> 	mov	[Century], ax
   473                              <1> 
   474 00004B27 88C8                <1> 	mov	al, cl
   475 00004B29 E8B8C0FFFF          <1>   	call	bcd_to_ascii
   476 00004B2E 66A3[16BF0000]      <1> 	mov	word [Year], ax
   477                              <1> 
   478 00004B34 BE[FEBE0000]        <1> 	mov	esi, Msg_Show_Date
   479 00004B39 E8E1F3FFFF          <1> 	call	print_msg
   480                              <1> 
   481 00004B3E C3                  <1> 	retn
   482                              <1> 
   483                              <1> set_date:
   484                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   485                              <1>         ; 2004-2005
   486                              <1> 
   487 00004B3F BE[E2BE0000]        <1> 	mov	esi, Msg_Enter_Date
   488 00004B44 E8D6F3FFFF          <1> 	call	print_msg
   489                              <1> 
   490                              <1> loc_enter_day_1:
   491 00004B49 30E4                <1> 	xor     ah, ah
   492 00004B4B E89FC0FFFF          <1> 	call	int16h
   493                              <1> 	; AL = ASCII Code of the Character
   494 00004B50 3C0D                <1> 	cmp	al, 13
   495 00004B52 0F84B7010000        <1> 	je	loc_set_date_retn
   496 00004B58 3C1B                <1> 	cmp	al, 27
   497 00004B5A 0F84AF010000        <1> 	je	loc_set_date_retn
   498 00004B60 A2[0EBF0000]        <1> 	mov	[Day], al
   499 00004B65 3C30                <1> 	cmp	al, '0'
   500 00004B67 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   501 00004B6D 3C33                <1> 	cmp	al, '3'
   502 00004B6F 0F87A5010000        <1> 	ja	loc_set_date_stc_0
   503                              <1> 	;sub	bl, bl ; 0
   504 00004B75 B407                <1> 	mov	ah, 7 ; attribute/color
   505 00004B77 E843CCFFFF          <1> 	call	WRITE_TTY
   506                              <1> loc_enter_day_2:
   507 00004B7C 30E4                <1> 	xor     ah, ah
   508 00004B7E E86CC0FFFF          <1> 	call	int16h
   509                              <1> 	; AL = ASCII Code of the Character
   510 00004B83 3C1B                <1> 	cmp	al, 27
   511 00004B85 0F8484010000        <1>         je      loc_set_date_retn
   512 00004B8B A2[0FBF0000]        <1> 	mov	[Day+1], al
   513 00004B90 3C30                <1> 	cmp	al, '0'
   514 00004B92 0F828C010000        <1>         jb      loc_set_date_stc_1
   515 00004B98 3C39                <1> 	cmp	al, '9'
   516 00004B9A 0F8784010000        <1>         ja      loc_set_date_stc_1
   517 00004BA0 803D[0EBF0000]33    <1> 	cmp	byte [Day], '3'
   518 00004BA7 7208                <1> 	jb	short pass_set_day_31
   519 00004BA9 3C31                <1> 	cmp	al, '1'
   520 00004BAB 0F8773010000        <1>         ja      loc_set_date_stc_1
   521                              <1> pass_set_day_31:
   522                              <1> 	;sub	bl, bl ; 0
   523 00004BB1 B407                <1> 	mov	ah, 7 ; attribute/color
   524 00004BB3 E807CCFFFF          <1> 	call	WRITE_TTY
   525                              <1> loc_enter_separator_1:
   526 00004BB8 28E4                <1> 	sub     ah, ah ; 0
   527 00004BBA E830C0FFFF          <1> 	call	int16h
   528                              <1> 	; AL = ASCII Code of the Character
   529 00004BBF 3C1B                <1> 	cmp	al, 27
   530 00004BC1 0F8448010000        <1>         je      loc_set_date_retn
   531 00004BC7 3C2D                <1> 	cmp	al, '-'
   532 00004BC9 7408                <1> 	je	short pass_set_date_separator_1
   533 00004BCB 3C2F                <1> 	cmp	al, '/'
   534 00004BCD 0F856C010000        <1>         jne     loc_set_date_stc_2
   535                              <1> pass_set_date_separator_1:
   536                              <1> 	;xor	bl, bl ; 0
   537 00004BD3 B407                <1> 	mov	ah, 7 ; attribute/color
   538 00004BD5 E8E5CBFFFF          <1> 	call	WRITE_TTY
   539                              <1> loc_enter_month_1:
   540 00004BDA 30E4                <1> 	xor     ah, ah ; 0
   541 00004BDC E80EC0FFFF          <1> 	call	int16h
   542                              <1> 	; AL = ASCII Code of the Character
   543 00004BE1 3C1B                <1> 	cmp	al, 27
   544 00004BE3 0F8426010000        <1>         je      loc_set_date_retn
   545 00004BE9 A2[11BF0000]        <1> 	mov	[Month], al
   546 00004BEE 3C30                <1> 	cmp	al, '0'
   547 00004BF0 0F8264010000        <1>         jb      loc_set_date_stc_3
   548 00004BF6 3C31                <1> 	cmp	al, '1'
   549 00004BF8 0F875C010000        <1>         ja      loc_set_date_stc_3
   550                              <1> 	;sub	bl, bl
   551 00004BFE B407                <1> 	mov	ah, 7 ; attribute/color
   552 00004C00 E8BACBFFFF          <1> 	call	WRITE_TTY
   553                              <1> loc_enter_month_2:
   554 00004C05 30E4                <1> 	xor     ah, ah
   555 00004C07 E8E3BFFFFF          <1> 	call	int16h
   556                              <1> 	; AL = ASCII Code of the Character
   557 00004C0C 3C1B                <1> 	cmp	al, 27
   558 00004C0E 0F84FB000000        <1>         je      loc_set_date_retn
   559 00004C14 A2[12BF0000]        <1> 	mov	[Month+1], al
   560 00004C19 3C30                <1> 	cmp	al, '0'
   561 00004C1B 0F8254010000        <1>         jb      loc_set_date_stc_4
   562 00004C21 3C39                <1> 	cmp	al, '9'
   563 00004C23 0F874C010000        <1>         ja      loc_set_date_stc_4
   564 00004C29 803D[11BF0000]31    <1> 	cmp	byte [Month], '1'
   565 00004C30 7208                <1> 	jb	short pass_set_month_12
   566 00004C32 3C32                <1> 	cmp	al, '2'
   567 00004C34 0F873B010000        <1>         ja      loc_set_date_stc_4
   568                              <1> pass_set_month_12:
   569                              <1> 	;sub	bl, bl
   570 00004C3A B407                <1> 	mov	ah, 7 ; attribute/color
   571 00004C3C E87ECBFFFF          <1> 	call	WRITE_TTY
   572                              <1> loc_enter_separator_2:
   573 00004C41 28E4                <1> 	sub     ah, ah
   574 00004C43 E8A7BFFFFF          <1> 	call	int16h
   575                              <1> 	; AL = ASCII Code of the Character
   576 00004C48 3C1B                <1> 	cmp	al, 27
   577 00004C4A 0F84BF000000        <1>         je      loc_set_date_retn
   578 00004C50 3C2D                <1> 	cmp	al, '-'
   579 00004C52 7408                <1> 	je	short pass_set_date_separator_2
   580 00004C54 3C2F                <1> 	cmp	al, '/'
   581 00004C56 0F8534010000        <1>         jne     loc_set_date_stc_5
   582                              <1> pass_set_date_separator_2:
   583                              <1> 	;xor	bl, bl
   584 00004C5C B407                <1> 	mov	ah, 7 ; attribute/color
   585 00004C5E E85CCBFFFF          <1> 	call	WRITE_TTY
   586                              <1> loc_enter_year_1:
   587 00004C63 30E4                <1> 	xor    ah, ah
   588 00004C65 E885BFFFFF          <1> 	call	int16h
   589                              <1> 	; AL = ASCII Code of the Character
   590 00004C6A 3C1B                <1> 	cmp	al, 27
   591 00004C6C 0F849D000000        <1>         je      loc_set_date_retn
   592 00004C72 A2[16BF0000]        <1> 	mov	[Year], al
   593 00004C77 3C30                <1> 	cmp	al, '0'
   594 00004C79 0F822C010000        <1>         jb      loc_set_date_stc_6
   595 00004C7F 3C39                <1> 	cmp	al, '9'
   596 00004C81 0F8724010000        <1>         ja      loc_set_date_stc_6
   597                              <1> 	;sub	bl, bl
   598 00004C87 B407                <1> 	mov	ah, 7 ; attribute/color
   599 00004C89 E831CBFFFF          <1> 	call	WRITE_TTY
   600                              <1> loc_enter_year_2:
   601 00004C8E 30E4                <1> 	xor	ah, ah
   602 00004C90 E85ABFFFFF          <1> 	call	int16h
   603                              <1> 	; AL = ASCII Code of the Character
   604 00004C95 3C1B                <1> 	cmp	al, 27
   605 00004C97 7476                <1> 	je	short loc_set_date_retn
   606 00004C99 A2[17BF0000]        <1> 	mov	byte [Year+1], al
   607 00004C9E 3C30                <1> 	cmp	al, '0'
   608 00004CA0 0F8220010000        <1>         jb      loc_set_date_stc_7
   609 00004CA6 3C39                <1> 	cmp	al, '9'
   610 00004CA8 0F8718010000        <1>         ja      loc_set_date_stc_7
   611                              <1> 	;sub	bl, bl
   612 00004CAE B407                <1> 	mov	ah, 7 ; attribute/color
   613 00004CB0 E80ACBFFFF          <1> 	call	WRITE_TTY
   614                              <1> loc_set_date_get_lchar_again:
   615 00004CB5 28E4                <1> 	sub	ah, ah ; 0
   616 00004CB7 E833BFFFFF          <1> 	call	int16h
   617                              <1> 	; AL = ASCII Code of the Character
   618 00004CBC 3C0D                <1> 	cmp	al, 13 ; ENTER key
   619 00004CBE 7412                <1> 	je	short loc_set_date_progress
   620 00004CC0 3C1B                <1> 	cmp	al, 27 ; ESC key
   621 00004CC2 744B                <1> 	je	short loc_set_date_retn
   622                              <1> 	;
   623 00004CC4 E82A010000          <1> 	call	check_for_backspace
   624 00004CC9 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   625                              <1> 
   626                              <1> loc_set_date_bs_8:
   627 00004CCB E811010000          <1> 	call	write_backspace
   628 00004CD0 EBBC                <1> 	jmp	short loc_enter_year_2
   629                              <1> 
   630                              <1> loc_set_date_progress:
   631                              <1> 	; Get Current Date
   632                              <1> 	;mov	ah, 04h
   633                              <1> 	;call	int1Ah
   634 00004CD2 E873EFFFFF          <1> 	call	RTC_40	; GET RTC DATE
   635                              <1> 	; CH = century (in BCD)
   636                              <1> 
   637 00004CD7 66A1[16BF0000]      <1> 	mov	ax, [Year]
   638 00004CDD 662D3030            <1> 	sub	ax, '00'
   639 00004CE1 C0E004              <1> 	shl	al, 4 ; * 16
   640 00004CE4 88C1                <1> 	mov	cl, al
   641 00004CE6 00E1                <1> 	add	cl, ah
   642 00004CE8 66A1[11BF0000]      <1> 	mov	ax, [Month]
   643 00004CEE 662D3030            <1> 	sub	ax, '00'
   644 00004CF2 C0E004              <1> 	shl	al, 4 ; * 16
   645 00004CF5 88C6                <1> 	mov	dh, al
   646 00004CF7 00E6                <1> 	add	dh, ah
   647 00004CF9 66A1[0EBF0000]      <1> 	mov	ax, [Day]
   648 00004CFF 662D3030            <1> 	sub	ax, '00'
   649 00004D03 C0E004              <1> 	shl	al, 4 ; * 16
   650 00004D06 88C2                <1> 	mov	dl, al
   651 00004D08 00E2                <1> 	add	dl, ah
   652                              <1> 
   653                              <1> 	;mov	ah, 05h
   654                              <1> 	;call	int1Ah
   655 00004D0A E868EFFFFF          <1> 	call	RTC_50	; SET RTC DATE
   656                              <1> 
   657                              <1> loc_set_date_retn:
   658 00004D0F BE[76CB0000]        <1> 	mov	esi, nextline
   659 00004D14 E806F2FFFF          <1> 	call	print_msg
   660 00004D19 C3                  <1> 	retn
   661                              <1> 
   662                              <1> loc_set_date_stc_0:
   663                              <1> 	;xor	bl, bl ; video page 0
   664 00004D1A E87ECBFFFF          <1> 	call	beeper ; BEEP !
   665 00004D1F E925FEFFFF          <1>         jmp     loc_enter_day_1
   666                              <1> loc_set_date_stc_1:
   667 00004D24 E8CA000000          <1> 	call	check_for_backspace
   668 00004D29 740A                <1> 	je	short loc_set_date_bs_1
   669                              <1> 	;xor	bl, bl ; video page 0
   670 00004D2B E86DCBFFFF          <1> 	call	beeper ; BEEP !
   671 00004D30 E947FEFFFF          <1>         jmp     loc_enter_day_2
   672                              <1> loc_set_date_bs_1:
   673 00004D35 E8A7000000          <1> 	call	write_backspace
   674 00004D3A E90AFEFFFF          <1>         jmp     loc_enter_day_1
   675                              <1> loc_set_date_stc_2:
   676 00004D3F E8AF000000          <1> 	call	check_for_backspace
   677 00004D44 740A                <1> 	je	short loc_set_date_bs_2
   678                              <1> 	;xor	bl, bl ; video page 0
   679 00004D46 E852CBFFFF          <1> 	call	beeper ; BEEP !
   680 00004D4B E968FEFFFF          <1>         jmp     loc_enter_separator_1
   681                              <1> loc_set_date_bs_2:
   682 00004D50 E88C000000          <1> 	call	write_backspace
   683 00004D55 E922FEFFFF          <1>         jmp     loc_enter_day_2
   684                              <1> loc_set_date_stc_3:
   685 00004D5A E894000000          <1> 	call	check_for_backspace	
   686 00004D5F 740A                <1> 	je short loc_set_date_bs_3
   687                              <1> 	;xor	bl, bl ; video page 0
   688 00004D61 E837CBFFFF          <1> 	call	beeper ; BEEP !
   689 00004D66 E96FFEFFFF          <1>         jmp     loc_enter_month_1
   690                              <1> loc_set_date_bs_3:
   691 00004D6B E871000000          <1> 	call	write_backspace
   692 00004D70 E943FEFFFF          <1>         jmp     loc_enter_separator_1
   693                              <1> loc_set_date_stc_4:
   694 00004D75 E879000000          <1> 	call	check_for_backspace	
   695 00004D7A 740A                <1> 	je	short loc_set_date_bs_4
   696                              <1> 	;xor	bl, bl ; video page 0
   697 00004D7C E81CCBFFFF          <1> 	call	beeper ; BEEP !
   698 00004D81 E97FFEFFFF          <1>         jmp     loc_enter_month_2
   699                              <1> loc_set_date_bs_4:
   700 00004D86 E856000000          <1> 	call	write_backspace
   701 00004D8B E94AFEFFFF          <1>         jmp     loc_enter_month_1
   702                              <1> loc_set_date_stc_5:
   703 00004D90 E85E000000          <1> 	call	check_for_backspace
   704 00004D95 740A                <1> 	je	short loc_set_date_bs_5
   705                              <1> 	;xor	bl, bl ; video page 0
   706 00004D97 E801CBFFFF          <1> 	call	beeper ; BEEP !
   707 00004D9C E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   708                              <1> loc_set_date_bs_5:
   709 00004DA1 E83B000000          <1> 	call	write_backspace
   710 00004DA6 E95AFEFFFF          <1>         jmp     loc_enter_month_2
   711                              <1> loc_set_date_stc_6:
   712 00004DAB E843000000          <1> 	call	check_for_backspace
   713 00004DB0 740A                <1>         je      short  loc_set_date_bs_6
   714                              <1> 	;xor	bl, bl ; video page 0
   715 00004DB2 E8E6CAFFFF          <1> 	call	beeper ; BEEP !
   716 00004DB7 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   717                              <1> loc_set_date_bs_6:
   718 00004DBC E820000000          <1> 	call	write_backspace
   719 00004DC1 E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   720                              <1> loc_set_date_stc_7:
   721 00004DC6 E828000000          <1> 	call	check_for_backspace
   722 00004DCB 740A                <1> 	je	short loc_set_date_bs_7
   723                              <1> 	;xor	bl, bl ; video page 0
   724 00004DCD E8CBCAFFFF          <1> 	call	beeper ; BEEP !
   725 00004DD2 E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   726                              <1> loc_set_date_bs_7:
   727 00004DD7 E805000000          <1> 	call	write_backspace
   728 00004DDC E982FEFFFF          <1>         jmp     loc_enter_year_1
   729                              <1> 
   730                              <1> write_backspace:
   731                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   732 00004DE1 B008                <1> 	mov	al, 08h ; BACKSPACE
   733                              <1> 	;xor	bl, bl
   734 00004DE3 B407                <1> 	mov	ah, 7 ; attribute/color
   735 00004DE5 E8D5C9FFFF          <1> 	call	WRITE_TTY
   736 00004DEA B020                <1> 	mov	al, 20h ; BLANK/SPACE char 
   737                              <1> 	;xor	bl, bl
   738 00004DEC B407                <1> 	mov	ah, 7 ; attribute/color
   739                              <1> 	;call	_write_c_current
   740                              <1> 	;retn
   741 00004DEE E99BC9FFFF          <1> 	jmp	_write_c_current
   742                              <1> 
   743                              <1> check_for_backspace:
   744                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   745 00004DF3 663D080E            <1> 	cmp	ax, 0E08h
   746 00004DF7 7410                <1> 	je	short cfbs_retn
   747 00004DF9 663DE04B            <1> 	cmp	ax, 4BE0h
   748 00004DFD 740A                <1> 	je	short cfbs_retn
   749 00004DFF 663D004B            <1> 	cmp	ax, 4B00h
   750 00004E03 7404                <1> 	je	short cfbs_retn
   751 00004E05 663DE053            <1> 	cmp	ax, 53E0h
   752                              <1> cfbs_retn:
   753 00004E09 C3                  <1> 	retn
   754                              <1> 
   755                              <1> show_time:
   756                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   757                              <1>         ; 2004-2005
   758                              <1> 
   759                              <1> 	;mov	ah, 02h
   760                              <1> 	;call	int1Ah
   761 00004E0A E8CAEDFFFF          <1> 	call	RTC_20	; GET RTC TIME
   762                              <1> 	
   763 00004E0F 88E8                <1> 	mov	al, ch
   764 00004E11 E8D0BDFFFF          <1> 	call	bcd_to_ascii
   765 00004E16 66A3[3CBF0000]      <1> 	mov	[Hour], ax
   766                              <1> 
   767 00004E1C 88C8                <1> 	mov	al, cl
   768 00004E1E E8C3BDFFFF          <1> 	call	bcd_to_ascii
   769 00004E23 66A3[3FBF0000]      <1> 	mov	[Minute], ax
   770                              <1> 
   771 00004E29 88F0                <1> 	mov	al, dh
   772 00004E2B E8B6BDFFFF          <1> 	call	bcd_to_ascii
   773 00004E30 66A3[42BF0000]      <1> 	mov	[Second], ax
   774                              <1> 
   775 00004E36 BE[2CBF0000]        <1> 	mov	esi, Msg_Show_Time
   776 00004E3B E8DFF0FFFF          <1> 	call	print_msg
   777 00004E40 C3                  <1> 	retn
   778                              <1> 
   779                              <1> set_time:
   780                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   781                              <1>         ; 2004-2005
   782                              <1> 
   783 00004E41 BE[1BBF0000]        <1> 	mov 	esi, Msg_Enter_Time
   784 00004E46 E8D4F0FFFF          <1> 	call	print_msg
   785                              <1> 
   786                              <1> loc_enter_hour_1:
   787 00004E4B 30E4                <1> 	xor     ah, ah
   788 00004E4D E89DBDFFFF          <1> 	call	int16h
   789                              <1> 	; AL = ASCII Code of the Character
   790 00004E52 3C0D                <1> 	cmp	al, 13 ; ENTER key
   791 00004E54 0F84AE010000        <1>         je      loc_set_time_retn
   792 00004E5A 3C1B                <1> 	cmp	al, 27 ; ESC key
   793 00004E5C 0F84A6010000        <1>         je      loc_set_time_retn
   794 00004E62 A2[3CBF0000]        <1> 	mov	[Hour], al
   795 00004E67 3C30                <1> 	cmp	al, '0'
   796 00004E69 0F82A4010000        <1>         jb      loc_set_time_stc_0
   797 00004E6F 3C32                <1> 	cmp	al, '2'
   798 00004E71 0F879C010000        <1>         ja      loc_set_time_stc_0
   799                              <1> 	;sub	bl, bl ; 0
   800 00004E77 B407                <1> 	mov	ah, 7 ; attribute/color
   801 00004E79 E841C9FFFF          <1> 	call	WRITE_TTY
   802                              <1> loc_enter_hour_2:
   803 00004E7E 30E4                <1> 	xor     ah, ah
   804 00004E80 E86ABDFFFF          <1> 	call	int16h
   805                              <1> 	; AL = ASCII Code of the Character
   806 00004E85 3C1B                <1> 	cmp	al, 27
   807 00004E87 0F847B010000        <1>         je      loc_set_time_retn
   808 00004E8D A2[3DBF0000]        <1> 	mov	[Hour+1], al
   809 00004E92 3C30                <1> 	cmp	al, '0'
   810 00004E94 0F8283010000        <1>         jb      loc_set_time_stc_1
   811 00004E9A 3C39                <1> 	cmp	al, '9'
   812 00004E9C 0F877B010000        <1> 	ja	loc_set_time_stc_1
   813 00004EA2 803D[3CBF0000]32    <1>         cmp     byte [Hour], '2'
   814 00004EA9 7208                <1> 	jb	short pass_set_time_24
   815 00004EAB 3C34                <1> 	cmp	al, '4'
   816 00004EAD 0F876A010000        <1>         ja      loc_set_time_stc_1
   817                              <1> pass_set_time_24:
   818                              <1> 	;sub	bl, bl ; 0
   819 00004EB3 B407                <1> 	mov	ah, 7 ; attribute/color
   820 00004EB5 E805C9FFFF          <1> 	call	WRITE_TTY
   821                              <1> loc_enter_time_separator_1:
   822 00004EBA 28E4                <1> 	sub    ah, ah ; 0
   823 00004EBC E82EBDFFFF          <1> 	call	int16h
   824                              <1> 	; AL = ASCII Code of the Character
   825 00004EC1 3C1B                <1> 	cmp	al, 27
   826 00004EC3 0F843F010000        <1>         je      loc_set_time_retn
   827 00004EC9 3C3A                <1> 	cmp	al, ':'
   828 00004ECB 0F8567010000        <1>         jne     loc_set_time_stc_2
   829                              <1> 	;xor	bl, bl
   830 00004ED1 B407                <1> 	mov	ah, 7 ; attribute/color
   831 00004ED3 E8E7C8FFFF          <1> 	call	WRITE_TTY
   832                              <1> loc_enter_minute_1:
   833 00004ED8 30E4                <1> 	xor     ah, ah
   834 00004EDA E810BDFFFF          <1> 	call	int16h
   835                              <1> 	; AL = ASCII Code of the Character
   836 00004EDF 3C1B                <1> 	cmp	al, 27
   837 00004EE1 0F8421010000        <1>         je      loc_set_time_retn
   838 00004EE7 A2[3FBF0000]        <1> 	mov	[Minute], al
   839 00004EEC 3C30                <1> 	cmp	al, '0'
   840 00004EEE 0F825F010000        <1>         jb      loc_set_time_stc_3
   841 00004EF4 3C35                <1> 	cmp	al, '5'
   842 00004EF6 0F8757010000        <1>         ja      loc_set_time_stc_3
   843                              <1> 	;sub	bl, bl
   844 00004EFC B407                <1> 	mov	ah, 7 ; attribute/color
   845 00004EFE E8BCC8FFFF          <1> 	call	WRITE_TTY
   846                              <1> loc_enter_minute_2:
   847 00004F03 30E4                <1> 	xor     ah, ah
   848 00004F05 E8E5BCFFFF          <1> 	call	int16h
   849                              <1> 	; AL = ASCII Code of the Character
   850 00004F0A 3C1B                <1> 	cmp	al, 27
   851 00004F0C 0F84F6000000        <1>         je      loc_set_time_retn
   852 00004F12 A2[40BF0000]        <1> 	mov	[Minute+1], al
   853 00004F17 3C30                <1> 	cmp	al, '0'
   854 00004F19 0F824F010000        <1>         jb      loc_set_time_stc_4
   855 00004F1F 3C39                <1> 	cmp	al, '9'
   856 00004F21 0F8747010000        <1>         ja      loc_set_time_stc_4
   857                              <1> 	;sub	bl, bl
   858 00004F27 B407                <1> 	mov	ah, 7 ; attribute/color
   859 00004F29 E891C8FFFF          <1> 	call	WRITE_TTY
   860                              <1> loc_enter_time_separator_2:
   861 00004F2E 66C705[42BF0000]30- <1> 	mov	word [Second], 3030h
   861 00004F36 30                  <1>
   862 00004F37 28E4                <1> 	sub     ah, ah
   863 00004F39 E8B1BCFFFF          <1> 	call	int16h
   864                              <1> 	; AL = ASCII Code of the Character
   865 00004F3E 3C0D                <1> 	cmp	al, 13
   866 00004F40 0F8485000000        <1>         je      loc_set_time_progress
   867 00004F46 3C1B                <1> 	cmp	al, 27
   868 00004F48 0F84BA000000        <1>         je      loc_set_time_retn
   869 00004F4E 3C3A                <1> 	cmp	al, ':'
   870 00004F50 0F8533010000        <1>         jne     loc_set_time_stc_5
   871                              <1> 	;xor	bl, bl
   872 00004F56 B407                <1> 	mov	ah, 7 ; attribute/color
   873 00004F58 E862C8FFFF          <1> 	call	WRITE_TTY
   874                              <1> loc_enter_second_1:
   875 00004F5D 30E4                <1> 	xor     ah, ah
   876 00004F5F E88BBCFFFF          <1> 	call	int16h
   877                              <1> 	; AL = ASCII Code of the Character
   878 00004F64 3C0D                <1> 	cmp	al, 13
   879 00004F66 7463                <1> 	je	short loc_set_time_progress
   880 00004F68 3C1B                <1> 	cmp	al, 27
   881 00004F6A 0F8498000000        <1>         je      loc_set_time_retn
   882 00004F70 A2[42BF0000]        <1> 	mov	[Second], al
   883 00004F75 3C30                <1> 	cmp	al, '0'
   884 00004F77 0F8227010000        <1>         jb      loc_set_time_stc_6
   885 00004F7D 3C35                <1> 	cmp	al, '5'
   886 00004F7F 0F871F010000        <1>         ja      loc_set_time_stc_6
   887                              <1> 	;sub	bl, bl
   888 00004F85 B407                <1> 	mov	ah, 7 ; attribute/color
   889 00004F87 E833C8FFFF          <1> 	call	WRITE_TTY
   890                              <1> loc_enter_second_2:
   891 00004F8C 30E4                <1> 	xor     ah, ah
   892 00004F8E E85CBCFFFF          <1> 	call	int16h
   893                              <1> 	; AL = ASCII Code of the Character
   894 00004F93 3C1B                <1> 	cmp	al, 27
   895 00004F95 7471                <1> 	je	short loc_set_time_retn
   896 00004F97 3C30                <1> 	cmp	al, '0'
   897 00004F99 0F8229010000        <1>         jb      loc_set_time_stc_7
   898 00004F9F 3C39                <1> 	cmp	al, '9'
   899 00004FA1 0F8721010000        <1>         ja      loc_set_time_stc_7
   900                              <1> 	;sub	bl, bl
   901 00004FA7 B407                <1> 	mov	ah, 7 ; attribute/color
   902 00004FA9 E811C8FFFF          <1> 	call	WRITE_TTY
   903                              <1> loc_set_time_get_lchar_again:
   904 00004FAE 28E4                <1> 	sub	ah, ah ; 0
   905 00004FB0 E83ABCFFFF          <1> 	call	int16h
   906                              <1> 	; AL = ASCII Code of the Character
   907 00004FB5 3C0D                <1> 	cmp	al, 13
   908 00004FB7 7412                <1> 	je	short loc_set_time_progress
   909 00004FB9 3C1B                <1> 	cmp	al, 27
   910 00004FBB 744B                <1> 	je	short loc_set_time_retn
   911                              <1> 	;
   912 00004FBD E831FEFFFF          <1> 	call	check_for_backspace
   913 00004FC2 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   914                              <1> 
   915                              <1> loc_set_time_bs_8:
   916 00004FC4 E818FEFFFF          <1> 	call	write_backspace
   917 00004FC9 EBC1                <1> 	jmp	short loc_enter_second_2
   918                              <1> 
   919                              <1> loc_set_time_progress:
   920                              <1> 	; Get Current Time
   921                              <1> 	;mov 	ah, 02h
   922                              <1> 	;call	int1Ah
   923 00004FCB E809ECFFFF          <1> 	call	RTC_20	; GET RTC TIME
   924                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   925                              <1> 
   926 00004FD0 66A1[3CBF0000]      <1> 	mov	ax, [Hour]
   927 00004FD6 662D3030            <1> 	sub	ax, '00'
   928 00004FDA C0E004              <1> 	shl	al, 4 ; * 16
   929 00004FDD 88C5                <1> 	mov	ch, al
   930 00004FDF 00E5                <1> 	add	ch, ah
   931 00004FE1 66A1[3FBF0000]      <1> 	mov	ax, [Minute]
   932 00004FE7 662D3030            <1> 	sub	ax, '00'
   933 00004FEB C0E004              <1> 	shl	al, 4 ; * 16
   934 00004FEE 88C1                <1> 	mov	cl, al
   935 00004FF0 00E1                <1> 	add	cl, ah
   936 00004FF2 66A1[42BF0000]      <1> 	mov	ax, [Second]
   937 00004FF8 662D3030            <1> 	sub	ax, '00'
   938 00004FFC C0E004              <1> 	shl	al, 4 ; * 16
   939 00004FFF 88C6                <1> 	mov	dh, al
   940 00005001 00E6                <1> 	add	dh, ah
   941                              <1> 	
   942                              <1> 	;mov	ah, 03h
   943                              <1> 	;call	int1Ah
   944 00005003 E800ECFFFF          <1> 	call	RTC_30	; SET RTC TIME
   945                              <1> 
   946                              <1> loc_set_time_retn:
   947 00005008 BE[76CB0000]        <1> 	mov 	esi, nextline
   948 0000500D E80DEFFFFF          <1> 	call	print_msg
   949 00005012 C3                  <1> 	retn
   950                              <1> 
   951                              <1> loc_set_time_stc_0:
   952                              <1> 	;xor	bl, bl ; video page 0
   953 00005013 E885C8FFFF          <1> 	call	beeper ; BEEP !
   954 00005018 E92EFEFFFF          <1>         jmp     loc_enter_hour_1
   955                              <1> loc_set_time_stc_1:
   956 0000501D E8D1FDFFFF          <1> 	call	check_for_backspace
   957 00005022 740A                <1> 	je	short loc_set_time_bs_1
   958                              <1> 	;xor	bl, bl ; video page 0
   959 00005024 E874C8FFFF          <1> 	call	beeper ; BEEP !
   960 00005029 E950FEFFFF          <1>         jmp     loc_enter_hour_2
   961                              <1> loc_set_time_bs_1:
   962 0000502E E8AEFDFFFF          <1> 	call	write_backspace
   963 00005033 E913FEFFFF          <1>         jmp     loc_enter_hour_1
   964                              <1> loc_set_time_stc_2:
   965 00005038 E8B6FDFFFF          <1> 	call	check_for_backspace
   966 0000503D 740A                <1> 	je	short loc_set_time_bs_2
   967                              <1> 	;xor	bl, bl ; video page 0
   968 0000503F E859C8FFFF          <1> 	call	beeper ; BEEP !
   969 00005044 E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
   970                              <1> loc_set_time_bs_2:
   971 00005049 E893FDFFFF          <1> 	call	write_backspace
   972 0000504E E92BFEFFFF          <1>         jmp     loc_enter_hour_2
   973                              <1> loc_set_time_stc_3:
   974 00005053 E89BFDFFFF          <1> 	call	check_for_backspace
   975 00005058 740A                <1> 	je	short loc_set_time_bs_3
   976                              <1> 	;xor	bl, bl ; video page 0
   977 0000505A E83EC8FFFF          <1> 	call	beeper ; BEEP !6
   978 0000505F E974FEFFFF          <1>         jmp     loc_enter_minute_1
   979                              <1> loc_set_time_bs_3:
   980 00005064 E878FDFFFF          <1> 	call	write_backspace
   981 00005069 E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
   982                              <1> loc_set_time_stc_4:
   983 0000506E E880FDFFFF          <1> 	call	check_for_backspace
   984 00005073 740A                <1> 	je	short loc_set_time_bs_4
   985                              <1> 	;xor	bl, bl ; video page 0
   986 00005075 E823C8FFFF          <1> 	call	beeper ; BEEP !
   987 0000507A E984FEFFFF          <1>         jmp     loc_enter_minute_2
   988                              <1> loc_set_time_bs_4:
   989 0000507F E85DFDFFFF          <1> 	call	write_backspace
   990 00005084 E94FFEFFFF          <1>         jmp     loc_enter_minute_1
   991                              <1> loc_set_time_stc_5:
   992 00005089 E865FDFFFF          <1> 	call	check_for_backspace
   993 0000508E 740A                <1> 	je	short loc_set_time_bs_5
   994                              <1> 	;xor	bl, bl ; video page 0
   995 00005090 E808C8FFFF          <1> 	call	beeper ; BEEP !
   996 00005095 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
   997                              <1> loc_set_time_bs_5:
   998 0000509A E842FDFFFF          <1> 	call	write_backspace
   999 0000509F E95FFEFFFF          <1>         jmp     loc_enter_minute_2
  1000                              <1> loc_set_time_stc_6:
  1001 000050A4 E84AFDFFFF          <1> 	call	check_for_backspace
  1002 000050A9 7413                <1> 	je	short loc_set_time_bs_6
  1003                              <1> 	;xor	bl, bl ; video page 0
  1004 000050AB E8EDC7FFFF          <1> 	call	beeper ; BEEP !
  1005 000050B0 66C705[42BF0000]30- <1> 	mov	word [Second], 3030h
  1005 000050B8 30                  <1>
  1006 000050B9 E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1007                              <1> loc_set_time_bs_6:
  1008 000050BE E81EFDFFFF          <1> 	call	write_backspace
  1009 000050C3 E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1010                              <1> loc_set_time_stc_7:
  1011 000050C8 E826FDFFFF          <1> 	call	check_for_backspace
  1012 000050CD 740A                <1> 	je	short loc_set_time_bs_7
  1013                              <1> 	;xor	bl, bl ; video page 0
  1014 000050CF E8C9C7FFFF          <1> 	call	beeper ; BEEP !
  1015 000050D4 E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1016                              <1> loc_set_time_bs_7:
  1017 000050D9 E803FDFFFF          <1> 	call	write_backspace
  1018 000050DE E97AFEFFFF          <1>         jmp     loc_enter_second_1
  1019                              <1> 
  1020                              <1> print_volume_info:
  1021                              <1> 	; 01/03/2016
  1022                              <1> 	; 08/02/2016
  1023                              <1> 	; 06/02/2016
  1024                              <1> 	; 04/02/2016
  1025                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
  1026                              <1> 	; 25/10/2009
  1027                              <1> 	;
  1028                              <1> 	; "Volume Serial No: "
  1029                              <1>  	;
  1030                              <1> 	; INPUT  : AL = DOS Drive Number
  1031                              <1> 	; OUTPUT : AH = FS Type
  1032                              <1> 	;          AL = DOS Drive Name
  1033                              <1> 	; CF = 0 -> OK
  1034                              <1> 	; CF = 1 -> Drive not ready 
  1035                              <1> 
  1036 000050E3 88C4                <1> 	mov	ah, al
  1037 000050E5 28C0                <1> 	sub	al, al
  1038 000050E7 0FB7F0              <1> 	movzx	esi, ax	
  1039 000050EA 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1040 000050F0 8A06                <1> 	mov	al, [esi]
  1041 000050F2 3C41                <1> 	cmp	al, 'A'  
  1042 000050F4 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1043 000050F6 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1044 000050F9 C3                  <1> 	retn
  1045                              <1> 
  1046                              <1> loc_pvi_set_vol_name:
  1047 000050FA A2[76BF0000]        <1> 	mov	[Vol_Drv_Name], al
  1048 000050FF 56                  <1> 	push	esi
  1049 00005100 E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1050 00005105 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1051 00005107 5E                  <1> 	pop	esi
  1052 00005108 C3                  <1> 	retn
  1053                              <1> 
  1054                              <1> loc_pvi_mvn_ok:
  1055 00005109 8B3424              <1> 	mov	esi, [esp]
  1056 0000510C 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1057 00005110 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1058 00005112 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1059 00005115 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1060 00005119 EB07                <1> 	jmp	short loc_vol_size_mul32
  1061                              <1> loc_pvi_fat_vol_size:
  1062 0000511B 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1063 0000511E 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1064                              <1> loc_vol_size_mul32:
  1065 00005122 F7E3                <1> 	mul	ebx
  1066 00005124 09D2                <1> 	or	edx, edx
  1067 00005126 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1068                              <1> loc_vol_size_in_bytes:
  1069 00005128 B9[54BF0000]        <1> 	mov	ecx, VolSize_Bytes
  1070 0000512D EB0D                <1> 	jmp	short loc_write_vol_size_str
  1071                              <1> loc_vol_size_in_kbytes:
  1072 0000512F 66BB0004            <1> 	mov	bx, 1024
  1073 00005133 F7F3                <1> 	div	ebx
  1074 00005135 B9[47BF0000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1075 0000513A 31D2                <1> 	xor	edx, edx ; 0
  1076                              <1> loc_write_vol_size_str:
  1077 0000513C 890D[DBD70000]      <1> 	mov	[VolSize_Unit1], ecx
  1078                              <1> 	; 
  1079 00005142 BF[F1D70000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1080                              <1>         ;mov	byte [edi], 0
  1081 00005147 B90A000000          <1> 	mov	ecx, 10
  1082                              <1> loc_write_vol_size_chr:
  1083 0000514C F7F1                <1> 	div	ecx
  1084 0000514E 80C230              <1> 	add	dl, '0'
  1085 00005151 4F                  <1> 	dec	edi	
  1086 00005152 8817                <1> 	mov	[edi], dl
  1087 00005154 85C0                <1> 	test	eax, eax
  1088 00005156 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1089 00005158 28D2                <1> 	sub	dl, dl ; 0
  1090 0000515A EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1091                              <1> 
  1092                              <1> loc_write_vol_size_str_ok:
  1093 0000515C 893D[E3D70000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1094                              <1> 	;
  1095 00005162 BF[5FBF0000]        <1> 	mov	edi, Vol_FS_Name
  1096 00005167 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1097 0000516A 20C9                <1> 	and	cl, cl ; 0 ?
  1098 0000516C 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1099 0000516E 66C7075452          <1> 	mov	word [edi], 'TR'
  1100 00005173 C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1101                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1102 0000517A 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1103 0000517E 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1104 00005181 EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1105                              <1> 
  1106                              <1> loc_write_vol_FAT_str_1:
  1107 00005183 66B83332            <1> 	mov	ax, '32' ; FAT32
  1108 00005187 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1109 0000518A 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1110 0000518C 66B83132            <1> 	mov	ax, '12' ; FAT12
  1111 00005190 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1112 00005192 B436                <1> 	mov	ah, '6'  ; FAT16
  1113                              <1> loc_write_vol_FAT_str_2:
  1114 00005194 C70746415420        <1> 	mov	dword [edi], 'FAT '
  1115 0000519A 66894704            <1> 	mov	word [edi+4], ax
  1116                              <1> 	;
  1117                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1118 0000519E 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1119 000051A2 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1120                              <1> 
  1121                              <1> loc_vol_freespace_recalc0:
  1122                              <1> 	; 01/03/2016
  1123 000051A5 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1124 000051A8 720F                <1> 	jb	short loc_vol_freespace_mul32
  1125                              <1> 	;inc	eax ; 0
  1126 000051AA 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1127 000051AC 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1128 000051AE 53                  <1> 	push	ebx
  1129 000051AF 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1130 000051B3 E874490000          <1> 	call	calculate_fat_freespace
  1131 000051B8 5B                  <1> 	pop	ebx
  1132                              <1> 
  1133                              <1> loc_vol_freespace_mul32:
  1134 000051B9 F7E3                <1> 	mul	ebx
  1135 000051BB 09D2                <1> 	or	edx, edx
  1136 000051BD 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1137                              <1> loc_vol_fspace_in_bytes:
  1138 000051BF B9[54BF0000]        <1> 	mov	ecx, VolSize_Bytes
  1139 000051C4 EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1140                              <1> loc_vol_fspace_in_kbytes:
  1141 000051C6 66BB0004            <1> 	mov	bx, 1024
  1142 000051CA F7F3                <1> 	div	ebx
  1143 000051CC B9[47BF0000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1144 000051D1 31D2                <1> 	xor	edx, edx ; 0
  1145                              <1> loc_write_vol_fspace_str:
  1146 000051D3 890D[DFD70000]      <1> 	mov	[VolSize_Unit2], ecx
  1147                              <1> 	;	
  1148 000051D9 BF[01D80000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1149                              <1>         ;mov	byte [edi], 0
  1150 000051DE B90A000000          <1> 	mov	ecx, 10
  1151                              <1> loc_write_vol_fspace_chr:
  1152 000051E3 F7F1                <1> 	div	ecx
  1153 000051E5 80C230              <1> 	add	dl, '0'
  1154 000051E8 4F                  <1> 	dec	edi	
  1155 000051E9 8817                <1> 	mov	[edi], dl
  1156 000051EB 85C0                <1> 	test	eax, eax
  1157 000051ED 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1158 000051EF 28D2                <1> 	sub	dl, dl ; 0
  1159 000051F1 EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1160                              <1> 
  1161                              <1> loc_write_vol_fspace_str_ok:
  1162 000051F3 893D[F3D70000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1163                              <1> 	;
  1164 000051F9 BE[5DBF0000]        <1> 	mov	esi, Volume_in_drive
  1165 000051FE E81CEDFFFF          <1> 	call	print_msg
  1166 00005203 BE[9DBF0000]        <1> 	mov	esi, Vol_Name
  1167 00005208 E812EDFFFF          <1> 	call	print_msg
  1168 0000520D BE[76CB0000]        <1> 	mov	esi, nextline
  1169 00005212 E808EDFFFF          <1> 	call	print_msg
  1170                              <1> 	;
  1171 00005217 BE[FEBF0000]        <1> 	mov	esi, Vol_Total_Sector_Header
  1172 0000521C E8FEECFFFF          <1> 	call	print_msg
  1173 00005221 8B35[E3D70000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1174 00005227 E8F3ECFFFF          <1> 	call	print_msg
  1175 0000522C 8B35[DBD70000]      <1> 	mov	esi, [VolSize_Unit1]
  1176 00005232 E8E8ECFFFF          <1> 	call	print_msg
  1177                              <1> 	;
  1178 00005237 BE[0FC00000]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1179 0000523C E8DEECFFFF          <1> 	call	print_msg
  1180 00005241 8B35[F3D70000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1181 00005247 E8D3ECFFFF          <1> 	call	print_msg
  1182 0000524C 8B35[DFD70000]      <1> 	mov	esi, [VolSize_Unit2]
  1183 00005252 E8C8ECFFFF          <1> 	call	print_msg
  1184                              <1> 	;
  1185 00005257 5E                  <1> 	pop	esi
  1186                              <1> 	
  1187                              <1> 	;mov	ah, [esi+LD_FSType]
  1188                              <1> 	;mov	al, [esi+LD_FATType]
  1189 00005258 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1190                              <1> 
  1191 0000525C C3                  <1> 	retn
  1192                              <1> 
  1193                              <1> move_volume_name_and_serial_no:
  1194                              <1> 	; 08/02/2016  (TRDOS 386 = TRDOS v2.0)
  1195                              <1> 	; this routine will be called by
  1196                              <1> 	; "print_volume_info" and "print_directory"
  1197                              <1> 	; INPUT ->
  1198                              <1> 	;	ESI = Logical DOS drv descripton table address
  1199                              <1> 	; OUTPUT ->
  1200                              <1> 	;	*Volume name will be moved to text area
  1201                              <1> 	;	*Volume serial number will be converted to
  1202                              <1> 	;	 text and will be moved to text area
  1203                              <1> 	;   cf = 1 -> invalid/unknown dos drive
  1204                              <1> 	;   cf = 0 -> ecx = 0
  1205                              <1> 	;
  1206                              <1> 	; (eax, edx, ecx, esi, edi will be changed)
  1207                              <1> 
  1208 0000525D BF[9DBF0000]        <1> 	mov 	edi, Vol_Name
  1209                              <1> 
  1210                              <1> 	;mov	ah, [esi+LD_FSType]
  1211                              <1> 	;mov	al, [esi+LD_FATType]
  1212 00005262 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1213 00005266 80FCA1              <1> 	cmp	ah, 0A1h
  1214 00005269 7418                <1> 	je	short mvn_2
  1215 0000526B 08E4                <1> 	or	ah, ah
  1216 0000526D 7404                <1> 	jz	short mvn_0
  1217 0000526F 08C0                <1> 	or	al, al
  1218 00005271 7504                <1> 	jnz	short mvn_1
  1219                              <1> mvn_0:
  1220 00005273 8A06                <1> 	mov	al, [esi]
  1221 00005275 F9                  <1> 	stc
  1222 00005276 C3                  <1> 	retn
  1223                              <1> mvn_1:
  1224 00005277 3C02                <1> 	cmp	al, 2
  1225 00005279 7717                <1> 	ja	short mvn_3 
  1226                              <1> 	;or	al, al
  1227                              <1> 	;jz	short mvn_2
  1228 0000527B 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1229 0000527E 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1230 00005281 EB15                <1> 	jmp	short mvn_4
  1231                              <1> mvn_2:
  1232 00005283 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1233 00005286 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1234 00005289 B910000000          <1> 	mov	ecx, 16
  1235 0000528E F3A5                <1> 	rep	movsd
  1236 00005290 EB10                <1> 	jmp	short mvn_5
  1237                              <1> mvn_3:
  1238 00005292 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1239 00005295 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1240                              <1> mvn_4:
  1241 00005298 B90B000000          <1> 	mov	ecx, 11
  1242 0000529D F3A4                <1> 	rep	movsb
  1243 0000529F C60700              <1> 	mov	byte [edi], 0
  1244                              <1> mvn_5:
  1245                              <1> 	;mov	[Current_VolSerial], eax  
  1246 000052A2 E848C7FFFF          <1> 	call	dwordtohex
  1247 000052A7 8915[F2BF0000]      <1> 	mov	[Vol_Serial1], edx
  1248 000052AD A3[F7BF0000]        <1> 	mov	[Vol_Serial2], eax
  1249                              <1> 	; ecx = 0
  1250 000052B2 C3                  <1> 	retn
  1251                              <1> 
  1252                              <1> get_volume_serial_number:
  1253                              <1> 	; 19/01/2016 (TRDOS 386 = TRDOS v2.0)
  1254                              <1> 	; 08/08/2010
  1255                              <1> 	;
  1256                              <1> 	; INPUT -> DL = Logical DOS Drive number
  1257                              <1> 	; OUTPUT -> EAX = Volume serial number
  1258                              <1> 	;          BL= FAT Type	    
  1259                              <1> 	;          BH = Logical DOS drv Number (DL input)
  1260                              <1> 	; cf = 1 -> Drive not ready
  1261                              <1> 
  1262 000052B3 31DB                <1> 	xor	ebx, ebx
  1263 000052B5 88D7                <1> 	mov	bh, dl
  1264 000052B7 3815[C5BD0000]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1265 000052BD 7304                <1> 	jnb	short loc_gvsn_start
  1266                              <1> loc_gvsn_stc_retn:
  1267 000052BF 31C0                <1> 	xor	eax, eax
  1268 000052C1 F9                  <1> 	stc 
  1269 000052C2 C3                  <1>         retn 
  1270                              <1> loc_gvsn_start:
  1271 000052C3 56                  <1> 	push	esi
  1272 000052C4 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1273 000052C9 01DE                <1> 	add	esi, ebx
  1274 000052CB 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1275 000052CE 20DB                <1> 	and	bl, bl
  1276 000052D0 740F                <1> 	jz	short loc_gvsn_fs
  1277 000052D2 80FB02              <1> 	cmp	bl, 2
  1278 000052D5 7705                <1> 	ja	short loc_gvsn_fat32
  1279                              <1> loc_gvsn_fat:
  1280 000052D7 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1281 000052DA EB0E                <1> 	jmp	short loc_gvsn_return
  1282                              <1> loc_gvsn_fat32: 
  1283 000052DC 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1284 000052DF EB09                <1> 	jmp	short loc_gvsn_return 
  1285                              <1> loc_gvsn_fs:
  1286 000052E1 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1287 000052E5 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1288 000052E7 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1289                              <1> loc_gvsn_return:
  1290 000052EA 8B06                <1> 	mov	eax, [esi]
  1291 000052EC 5E                  <1> 	pop	esi
  1292 000052ED C3                  <1> 	retn
  1293                              <1> 
  1294                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ]
  1295                              <1> ; 09/11/2011
  1296                              <1> ; 29/01/2005
  1297                              <1> 
  1298                              <1> command_interpreter:
  1299                              <1> 	; 07/05/2016
  1300                              <1> 	; 04/03/2016
  1301                              <1> 	; 04/02/2016
  1302                              <1> 	; 03/02/2016
  1303                              <1> 	; 30/01/2016
  1304                              <1> 	; 29/01/2016 (TRDOS 386 = TRDOS 2.0)
  1305                              <1> 	; 15/09/2011         
  1306                              <1> 	; 29/01/2005
  1307                              <1>         
  1308                              <1> 	; Input: ecx = command word length (CL)
  1309                              <1> 	;	 CommandBuffer = Command string offset
  1310                              <1>  
  1311 000052EE C605[94D80000]00    <1> 	mov	byte [Program_Exit],0
  1312 000052F5 80F904              <1> 	cmp	cl, 4
  1313 000052F8 0F87A7020000        <1>         ja      c_6
  1314 000052FE 0F8227010000        <1>         jb      c_2
  1315                              <1> c_4:
  1316                              <1> 
  1317                              <1> cmp_cmd_exit:
  1318 00005304 BF[33BE0000]        <1> 	mov	edi, Cmd_Exit
  1319 00005309 E8C2030000          <1> 	call	cmp_cmd	
  1320 0000530E 7208                <1> 	jc	short cmp_cmd_date
  1321                              <1> 
  1322 00005310 C605[94D80000]01    <1>         mov     byte [Program_Exit], 1
  1323 00005317 C3                  <1>         retn
  1324                              <1> 
  1325                              <1> cmp_cmd_date:
  1326 00005318 B104                <1> 	mov	cl, 4
  1327 0000531A BF[4FBE0000]        <1> 	mov	edi, Cmd_Date
  1328 0000531F E8AC030000          <1> 	call	cmp_cmd	
  1329 00005324 720B                <1>         jc	short cmp_cmd_time
  1330                              <1> 	
  1331 00005326 E8D0F7FFFF          <1> 	call	show_date
  1332 0000532B E80FF8FFFF          <1> 	call	set_date
  1333 00005330 C3                  <1> 	retn
  1334                              <1> 
  1335                              <1> cmp_cmd_time:
  1336 00005331 B104                <1> 	mov	cl, 4
  1337 00005333 BF[54BE0000]        <1> 	mov	edi, Cmd_Time
  1338 00005338 E893030000          <1>    	call	cmp_cmd	
  1339 0000533D 720B                <1> 	jc	short cmp_cmd_show
  1340                              <1> 
  1341 0000533F E8C6FAFFFF          <1> 	call	show_time
  1342 00005344 E8F8FAFFFF          <1> 	call	set_time
  1343 00005349 C3                  <1> 	retn
  1344                              <1> 
  1345                              <1> cmp_cmd_show:
  1346 0000534A B104                <1> 	mov	cl, 4
  1347 0000534C BF[65BE0000]        <1> 	mov	edi, Cmd_Show
  1348 00005351 E87A030000          <1>    	call	cmp_cmd	
  1349 00005356 0F83E9090000        <1>         jnc     show_file
  1350                              <1> 
  1351                              <1> cmp_cmd_echo:
  1352 0000535C B104                <1> 	mov	cl, 4
  1353 0000535E BF[AABE0000]        <1> 	mov	edi, Cmd_Echo
  1354 00005363 E868030000          <1>    	call	cmp_cmd	
  1355 00005368 721B                <1> 	jc	short cmp_cmd_copy
  1356                              <1> 
  1357                              <1> 	; 14/04/2016
  1358 0000536A 56                  <1> 	push	esi
  1359                              <1> cmd_echo_asciiz:
  1360 0000536B 46                  <1>         inc	esi
  1361 0000536C 8A06                <1> 	mov	al, [esi]
  1362 0000536E 3C20                <1> 	cmp	al, 20h
  1363 00005370 73F9                <1> 	jnb	short cmd_echo_asciiz
  1364 00005372 C60600              <1> 	mov	byte [esi], 0                 
  1365 00005375 5E                  <1> 	pop	esi  
  1366 00005376 E8A4EBFFFF          <1> 	call	print_msg
  1367 0000537B BE[E7CB0000]        <1> 	mov	esi, NextLine
  1368                              <1> 	;call	print_msg   
  1369                              <1> 	;retn
  1370 00005380 E99AEBFFFF          <1> 	jmp	print_msg
  1371                              <1> 
  1372                              <1> cmp_cmd_copy:
  1373 00005385 B104                <1> 	mov	cl, 4
  1374 00005387 BF[88BE0000]        <1> 	mov	edi, Cmd_Copy
  1375 0000538C E83F030000          <1>    	call	cmp_cmd	
  1376 00005391 0F83F0170000        <1> 	jnc	copy_file
  1377                              <1> 
  1378                              <1> cmp_cmd_move:
  1379 00005397 B104                <1> 	mov	cl, 4
  1380 00005399 BF[8DBE0000]        <1> 	mov	edi, Cmd_Move
  1381 0000539E E82D030000          <1>    	call	cmp_cmd	
  1382 000053A3 0F8384160000        <1> 	jnc	move_file
  1383                              <1> 
  1384                              <1> cmp_cmd_path:
  1385 000053A9 B104                <1> 	mov	cl, 4
  1386 000053AB BF[92BE0000]        <1> 	mov	edi, Cmd_Path
  1387 000053B0 E81B030000          <1>    	call	cmp_cmd	
  1388 000053B5 0F83241A0000        <1> 	jnc	set_get_path
  1389                              <1> 
  1390                              <1> cmp_cmd_beep:
  1391 000053BB B104                <1> 	mov	cl, 4
  1392 000053BD BF[C8BE0000]        <1> 	mov	edi, Cmd_Beep
  1393 000053C2 E809030000          <1>    	call	cmp_cmd	
  1394 000053C7 0F83D0C4FFFF        <1> 	jnc	beeper
  1395                              <1> 
  1396                              <1> cmp_cmd_find:
  1397 000053CD B104                <1> 	mov	cl, 4
  1398 000053CF BF[9CBE0000]        <1> 	mov	edi, Cmd_Find
  1399 000053D4 E8F7020000          <1>    	call	cmp_cmd	
  1400 000053D9 0F82D4020000        <1>         jc      cmp_cmd_external
  1401                              <1> 
  1402                              <1> 	;call	find_and_list_files
  1403 000053DF E9DC220000          <1> 	jmp	find_and_list_files
  1404                              <1> 	;retn
  1405                              <1> 
  1406                              <1> c_1:
  1407 000053E4 AD                  <1> 	lodsd
  1408                              <1> cmp_cmd_help:
  1409 000053E5 3C3F                <1> 	cmp	al, '?'
  1410 000053E7 751D                <1>         jne     short cmp_cmd_remark
  1411                              <1> 
  1412 000053E9 BE[25BE0000]        <1> 	mov	esi, Command_List
  1413                              <1> cmd_help_next_w:
  1414 000053EE E82CEBFFFF          <1> 	call	print_msg
  1415                              <1> 
  1416 000053F3 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1417 000053F6 7232                <1> 	jb	short cmd_help_retn
  1418                              <1> 	
  1419 000053F8 56                  <1> 	push	esi
  1420 000053F9 BE[76CB0000]        <1> 	mov	esi, nextline
  1421 000053FE E81CEBFFFF          <1> 	call	print_msg
  1422 00005403 5E                  <1> 	pop	esi
  1423 00005404 EBE8                <1> 	jmp	short cmd_help_next_w	
  1424                              <1> 
  1425                              <1> cmp_cmd_remark:
  1426 00005406 3C2A                <1> 	cmp	al, '*'
  1427 00005408 0F85A5020000        <1>         jne     cmp_cmd_external
  1428 0000540E 46                  <1> 	inc	esi
  1429 0000540F BF[04D00000]        <1> 	mov	edi, Remark
  1430 00005414 8A06                <1> 	mov	al, [esi]
  1431 00005416 3C20                <1> 	cmp	al, 20h
  1432 00005418 7707                <1> 	ja	short cmd_remark_write
  1433 0000541A 89FE                <1> 	mov	esi, edi ; Remark
  1434 0000541C E9FEEAFFFF          <1> 	jmp	print_msg
  1435                              <1> 
  1436                              <1> cmd_remark_write:
  1437 00005421 AA                  <1> 	stosb
  1438 00005422 AC                  <1> 	lodsb
  1439 00005423 3C20                <1> 	cmp	al, 20h
  1440 00005425 73FA                <1> 	jnb	short cmd_remark_write
  1441 00005427 C60700              <1> 	mov	byte [edi], 0
  1442                              <1> 
  1443                              <1> cmd_help_retn:
  1444                              <1> cmd_remark_retn:
  1445                              <1> cd_retn:
  1446 0000542A C3                  <1> 	retn
  1447                              <1> 
  1448                              <1> c_2:
  1449 0000542B 80F902              <1> 	cmp	cl, 2
  1450 0000542E 0F87B1000000        <1>         ja      c_3
  1451 00005434 BE[52D00000]        <1> 	mov	esi, CommandBuffer
  1452 00005439 72A9                <1> 	jb	short c_1
  1453                              <1> 
  1454                              <1> cmp_cmd_cd:
  1455 0000543B 66AD                <1> 	lodsw
  1456 0000543D 663D4344            <1> 	cmp	ax, 'CD'
  1457 00005441 7553                <1> 	jne	short cmp_cmd_drive
  1458 00005443 46                  <1>         inc	esi
  1459                              <1> cd_0:
  1460 00005444 668B06              <1> 	mov	ax, [esi]	
  1461 00005447 3C20                <1> 	cmp	al, 20h
  1462 00005449 76DF                <1> 	jna	short cd_retn
  1463                              <1> 	; 10/02/2016
  1464 0000544B 80FC3A              <1> 	cmp	ah, ':'
  1465 0000544E 7504                <1> 	jne	short cd_1
  1466 00005450 46                  <1> 	inc	esi
  1467 00005451 46                  <1> 	inc	esi
  1468 00005452 EB4B                <1> 	jmp	short cd_2
  1469                              <1> 
  1470                              <1> cd_1:	; change current directory
  1471                              <1> 	; 29/11/2009
  1472                              <1> 	; AH = CDh	; to separate 'CD' command from others
  1473                              <1> 			; for restoring current directory
  1474                              <1> 			; 0CDh sign is for saving cdir into 
  1475                              <1> 			; DOS drv description table cdir area
  1476                              <1> 	
  1477 00005454 B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1478                              <1> 
  1479 00005456 E84A230000          <1> 	call	change_current_directory
  1480 0000545B 0F8364220000        <1>         jnc     change_prompt_dir_string
  1481                              <1> 
  1482                              <1> cd_error_messages:
  1483 00005461 3C03                <1> 	cmp	al, 3
  1484 00005463 740C                <1> 	je	short cd_path_not_found
  1485 00005465 3C15                <1> 	cmp	al, 15h 
  1486 00005467 745B                <1> 	je	short cd_drive_not_ready
  1487 00005469 3C18                <1> 	cmp	al, 18h ; Bad request structure length 
  1488 0000546B 746C                <1> 	je	short cd_command_failed
  1489 0000546D 3C1A                <1> 	cmp	al, 1Ah ; Unknown media type, non-DOS disk
  1490 0000546F 7468                <1>         je      short cd_command_failed
  1491                              <1> 
  1492                              <1> cd_path_not_found:
  1493 00005471 6650                <1> 	push	ax	
  1494 00005473 BE[D1C00000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1495 00005478 E8A2EAFFFF          <1> 	call	print_msg
  1496 0000547D 6658                <1> 	pop	ax
  1497 0000547F 3A25[A0CF0000]      <1> 	cmp	ah, [Current_Dir_Level]
  1498 00005485 0F833A220000        <1>         jnb     change_prompt_dir_string
  1499 0000548B 8825[A0CF0000]      <1> 	mov	[Current_Dir_Level], ah
  1500 00005491 E92F220000          <1>         jmp     change_prompt_dir_string   
  1501                              <1> 
  1502                              <1> cmp_cmd_drive: ; change current drive
  1503                              <1> 	; C:, D:, E: etc.
  1504 00005496 80FC3A              <1> 	cmp	ah, ':'
  1505 00005499 0F8514020000        <1>         jne     cmp_cmd_external
  1506                              <1> 
  1507                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1508 0000549F 803E20              <1> 	cmp	byte [esi], 20h
  1509 000054A2 0F8715020000        <1>         ja      loc_cmd_failed
  1510                              <1> 
  1511 000054A8 24DF                <1> 	and	al, 0DFh
  1512 000054AA 2C41                <1> 	sub	al, 'A'
  1513 000054AC 0F820B020000        <1>         jc      loc_cmd_failed
  1514                              <1> 
  1515 000054B2 3A05[C5BD0000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1516 000054B8 770A                <1>         ja	short cd_drive_not_ready
  1517                              <1> 	
  1518 000054BA 88C2                <1> 	mov	dl, al
  1519 000054BC E862F3FFFF          <1> 	call 	change_current_drive
  1520 000054C1 7201                <1> 	jc	short cd_drive_not_ready	
  1521 000054C3 C3                  <1> 	retn
  1522                              <1> 
  1523                              <1> cd_drive_not_ready:
  1524 000054C4 BE[8EC00000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1525 000054C9 E851EAFFFF          <1> 	call	print_msg
  1526                              <1> 
  1527                              <1> cd_fail_drive_restart:
  1528 000054CE 8A15[A2CF0000]      <1> 	mov	dl, [Current_Drv]
  1529                              <1> 	;call 	change_current_drive
  1530 000054D4 E94AF3FFFF          <1>         jmp     change_current_drive
  1531                              <1> 	;retn
  1532                              <1> 
  1533                              <1> cd_command_failed:
  1534 000054D9 BE[6FC00000]        <1> 	mov	esi, Msg_Bad_Command
  1535 000054DE E83CEAFFFF          <1> 	call	print_msg
  1536 000054E3 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1537                              <1> 
  1538                              <1> c_3:
  1539                              <1> cmp_cmd_dir:
  1540 000054E5 BF[25BE0000]        <1> 	mov	edi, Cmd_Dir
  1541 000054EA E8E1010000          <1> 	call	cmp_cmd	
  1542 000054EF 0F8380020000        <1> 	jnc	print_directory_list
  1543                              <1> 
  1544                              <1> cmp_cmd_cls:
  1545 000054F5 B103                <1> 	mov	cl, 3
  1546 000054F7 BF[61BE0000]        <1> 	mov	edi, Cmd_Cls
  1547 000054FC E8CF010000          <1> 	call	cmp_cmd	
  1548 00005501 0F832FEAFFFF        <1>         jnc	clear_screen
  1549                              <1> 
  1550                              <1> cmp_cmd_ver:
  1551 00005507 B103                <1> 	mov	cl, 3
  1552 00005509 BF[2FBE0000]        <1> 	mov	edi, Cmd_Ver
  1553 0000550E E8BD010000          <1> 	call	cmp_cmd	
  1554 00005513 720A                <1> 	jc	short cmp_cmd_mem
  1555                              <1> 
  1556 00005515 BE[CDBD0000]        <1> 	mov	esi, mainprog_Version
  1557                              <1> 	;call	print_msg
  1558 0000551A E900EAFFFF          <1> 	jmp	print_msg
  1559                              <1> 	;retn
  1560                              <1> 
  1561                              <1> cmp_cmd_mem:
  1562 0000551F B103                <1> 	mov	cl, 3
  1563 00005521 BF[97BE0000]        <1> 	mov	edi, Cmd_Mem
  1564 00005526 E8A5010000          <1> 	call	cmp_cmd	
  1565 0000552B 0F8308C4FFFF        <1> 	jnc	memory_info
  1566                              <1> 
  1567                              <1> cmp_cmd_del:
  1568 00005531 B103                <1> 	mov	cl, 3
  1569 00005533 BF[6ABE0000]        <1> 	mov	edi, Cmd_Del
  1570 00005538 E893010000          <1> 	call	cmp_cmd	
  1571 0000553D 0F832A0F0000        <1>         jnc     delete_file
  1572                              <1> 
  1573                              <1> cmp_cmd_set:
  1574 00005543 B103                <1> 	mov	cl, 3
  1575 00005545 BF[5DBE0000]        <1> 	mov	edi, Cmd_Set
  1576 0000554A E881010000          <1> 	call	cmp_cmd	
  1577 0000554F 0F8302180000        <1>         jnc     set_get_env
  1578                              <1> 
  1579                              <1> cmp_cmd_run:
  1580 00005555 B103                <1> 	mov	cl, 3
  1581 00005557 BF[59BE0000]        <1> 	mov	edi, Cmd_Run
  1582 0000555C E86F010000          <1> 	call	cmp_cmd	
  1583                              <1> 	; 07/05/2016
  1584 00005561 0F824C010000        <1>         jc      cmp_cmd_external
  1585 00005567 E9391E0000          <1> 	jmp	load_and_execute_file
  1586                              <1> c_5:
  1587                              <1> cmp_cmd_mkdir:
  1588 0000556C BF[82BE0000]        <1> 	mov	edi, Cmd_Mkdir
  1589 00005571 E85A010000          <1> 	call	cmp_cmd	
  1590 00005576 0F83890A0000        <1>         jnc     make_directory
  1591                              <1> 
  1592                              <1> cmp_cmd_rmdir:
  1593 0000557C B105                <1> 	mov	cl, 5
  1594 0000557E BF[7CBE0000]        <1> 	mov	edi, Cmd_Rmdir
  1595 00005583 E848010000          <1> 	call	cmp_cmd	
  1596 00005588 0F83960B0000        <1>         jnc     delete_directory
  1597                              <1> 
  1598                              <1> cmp_cmd_chdir:
  1599 0000558E B105                <1> 	mov	cl, 5
  1600 00005590 BF[C2BE0000]        <1> 	mov	edi, Cmd_Chdir
  1601 00005595 E836010000          <1> 	call	cmp_cmd	
  1602 0000559A 0F8213010000        <1>         jc      cmp_cmd_external
  1603                              <1> 
  1604 000055A0 E99FFEFFFF          <1> 	jmp	cd_0
  1605                              <1> 
  1606                              <1> c_6:
  1607 000055A5 80F906              <1> 	cmp	cl, 6
  1608 000055A8 0F87DF000000        <1>         ja      c_8
  1609 000055AE 72BC                <1> 	jb	short c_5
  1610                              <1> cmp_cmd_prompt:
  1611 000055B0 BF[38BE0000]        <1> 	mov	edi, Cmd_Prompt
  1612 000055B5 E816010000          <1> 	call	cmp_cmd	
  1613 000055BA 722E                <1>         jc	short cmp_cmd_volume
  1614                              <1> get_prompt_name_fchar:
  1615 000055BC AC                  <1> 	lodsb
  1616 000055BD 3C20                <1> 	cmp	al, 20h
  1617 000055BF 74FB                <1> 	je	short get_prompt_name_fchar
  1618 000055C1 7712                <1> 	ja	short loc_change_prompt_label
  1619 000055C3 BE[19BE0000]        <1> 	mov	esi, TRDOSPromptLabel
  1620 000055C8 C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1621 000055CE 66C746045300        <1>        	mov	word [esi+4], "S" 
  1622                              <1> loc_cmd_prompt_return:
  1623 000055D4 C3                  <1> 	retn
  1624                              <1> loc_change_prompt_label:
  1625 000055D5 66B90B00            <1> 	mov	cx, 11
  1626 000055D9 BF[19BE0000]        <1> 	mov	edi, TRDOSPromptLabel
  1627                              <1> put_char_new_prompt_label:
  1628 000055DE AA                  <1> 	stosb
  1629 000055DF AC                  <1> 	lodsb
  1630 000055E0 3C20                <1> 	cmp	al, 20h
  1631 000055E2 7202                <1> 	jb	short pass_put_new_prompt_label
  1632 000055E4 E2F8                <1> 	loop	put_char_new_prompt_label
  1633                              <1> pass_put_new_prompt_label:
  1634 000055E6 C60700              <1> 	mov	byte [edi], 0
  1635 000055E9 C3                  <1> 	retn
  1636                              <1> 
  1637                              <1> cmp_cmd_volume:
  1638 000055EA B106                <1> 	mov	cl, 6
  1639 000055EC BF[3FBE0000]        <1> 	mov	edi, Cmd_Volume
  1640 000055F1 E8DA000000          <1> 	call	cmp_cmd	
  1641 000055F6 7255                <1>         jc	short cmp_cmd_attrib
  1642                              <1> 
  1643                              <1> cmd_vol1:
  1644 000055F8 AC                  <1> 	lodsb
  1645 000055F9 3C20                <1> 	cmp	al, 20h
  1646 000055FB 7707                <1> 	ja	short cmd_vol2
  1647 000055FD A0[A2CF0000]        <1> 	mov	al, [Current_Drv]
  1648 00005602 EB3D                <1> 	jmp	short cmd_vol4
  1649                              <1> cmd_vol2:
  1650 00005604 3C41                <1> 	cmp	al, 'A'
  1651 00005606 0F82B1000000        <1>         jb      loc_cmd_failed
  1652 0000560C 3C7A                <1> 	cmp	al, 'z'
  1653 0000560E 0F87A9000000        <1>         ja      loc_cmd_failed
  1654 00005614 3C5A                <1> 	cmp	al, 'Z'
  1655 00005616 760A                <1> 	jna	short cmd_vol3
  1656 00005618 3C61                <1> 	cmp	al, 'a'
  1657 0000561A 0F829D000000        <1>         jb      loc_cmd_failed
  1658 00005620 24DF                <1> 	and	al, 0DFh
  1659                              <1> cmd_vol3:
  1660 00005622 8A26                <1> 	mov	ah, [esi]
  1661 00005624 80FC3A              <1> 	cmp	ah, ':'
  1662 00005627 0F8590000000        <1>         jne     loc_cmd_failed
  1663 0000562D 2C41                <1> 	sub	al, 'A'
  1664 0000562F 3A05[C5BD0000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1665 00005635 760A                <1> 	jna	short cmd_vol4
  1666                              <1> 
  1667 00005637 BE[8EC00000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1668 0000563C E9DEE8FFFF          <1> 	jmp	print_msg
  1669                              <1> 	
  1670                              <1> cmd_vol4:
  1671 00005641 E89DFAFFFF          <1> 	call	print_volume_info
  1672 00005646 0F8278FEFFFF        <1>         jc      cd_drive_not_ready
  1673 0000564C C3                  <1> 	retn
  1674                              <1> 
  1675                              <1> cmp_cmd_attrib:
  1676 0000564D B106                <1> 	mov	cl, 6
  1677 0000564F BF[6EBE0000]        <1> 	mov	edi, Cmd_Attrib
  1678 00005654 E877000000          <1> 	call	cmp_cmd	
  1679 00005659 0F832E0F0000        <1>         jnc     set_file_attributes
  1680                              <1> 
  1681                              <1> cmp_cmd_rename:
  1682 0000565F B106                <1> 	mov	cl, 6
  1683 00005661 BF[75BE0000]        <1> 	mov	edi, Cmd_Rename
  1684 00005666 E865000000          <1> 	call	cmp_cmd	
  1685 0000566B 0F8364110000        <1>         jnc     rename_file
  1686                              <1> 
  1687                              <1> cmp_cmd_device:
  1688 00005671 B106                <1> 	mov	cl, 6
  1689 00005673 BF[B3BE0000]        <1> 	mov	edi, Cmd_Device
  1690 00005678 E853000000          <1> 	call	cmp_cmd	
  1691 0000567D 7234                <1>         jc	short cmp_cmd_external
  1692                              <1> 
  1693 0000567F C3                  <1> 	retn
  1694                              <1> 
  1695                              <1> c_7:
  1696                              <1> cmp_cmd_devlist:
  1697 00005680 BF[BABE0000]        <1> 	mov	edi, Cmd_DevList
  1698 00005685 E846000000          <1> 	call	cmp_cmd	
  1699 0000568A 7227                <1>         jc	short cmp_cmd_external
  1700                              <1> 
  1701 0000568C C3                  <1> 	retn
  1702                              <1> 
  1703                              <1> c_8:
  1704 0000568D 80F908              <1>         cmp	cl, 8
  1705 00005690 7721                <1> 	ja	short cmp_cmd_external
  1706 00005692 72EC                <1> 	jb	short c_7
  1707                              <1> 
  1708                              <1> cmp_cmd_longname:
  1709 00005694 BF[46BE0000]        <1> 	mov	edi, Cmd_LongName
  1710 00005699 E832000000          <1> 	call	cmp_cmd	
  1711 0000569E 0F834B060000        <1>         jnc     get_and_print_longname
  1712                              <1> 
  1713                              <1> cmp_cmd_readfile:
  1714 000056A4 B108                <1> 	mov	cl, 8
  1715 000056A6 BF[A1BE0000]        <1> 	mov	edi, Cmd_ReadFile
  1716 000056AB E820000000          <1> 	call	cmp_cmd	
  1717 000056B0 7201                <1>         jc	short cmp_cmd_external
  1718                              <1> 
  1719                              <1> loc_cmd_return:
  1720 000056B2 C3                  <1> 	retn
  1721                              <1> 
  1722                              <1> cmp_cmd_external:
  1723                              <1> 	; 07/05/2016
  1724                              <1> 	; 22/04/2016
  1725 000056B3 BE[52D00000]        <1> 	mov	esi, CommandBuffer
  1726 000056B8 E9E81C0000          <1> 	jmp	loc_run_check_filename 
  1727                              <1> 
  1728                              <1> loc_cmd_failed:
  1729 000056BD 803D[52D00000]20    <1> 	cmp	byte [CommandBuffer], 20h
  1730 000056C4 76EC                <1> 	jna	short loc_cmd_return
  1731 000056C6 BE[6FC00000]        <1> 	mov	esi, Msg_Bad_Command
  1732                              <1> ;	call	print_msg
  1733                              <1> ;loc_cmd_return:
  1734                              <1> ;	retn
  1735 000056CB E94FE8FFFF          <1> 	jmp	print_msg
  1736                              <1> 
  1737                              <1> cmp_cmd:
  1738                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1739 000056D0 BE[52D00000]        <1>          mov	esi, CommandBuffer
  1740                              <1>          ; edi = internal command word (ASCIIZ)
  1741                              <1> 	 ; ecx = command length (<=8)
  1742                              <1> cmp_cmd_1:
  1743 000056D5 AC                  <1> 	lodsb
  1744 000056D6 AE                  <1> 	scasb
  1745 000056D7 750D                <1> 	jne	short cmp_cmd_3
  1746 000056D9 E2FA                <1> 	loop	cmp_cmd_1
  1747 000056DB AC                  <1>  	lodsb
  1748 000056DC 3C20                <1> 	cmp	al, 20h
  1749 000056DE 7703                <1> 	ja	short cmp_cmd_2
  1750 000056E0 30C0                <1> 	xor	al, al
  1751                              <1> 	; ZF = 1 -> internal command word matches
  1752 000056E2 C3                  <1> 	retn
  1753                              <1> cmp_cmd_2:
  1754                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1755 000056E3 58                  <1> 	pop	eax ; no return to the caller from here 
  1756 000056E4 EBCD                <1> 	jmp	cmp_cmd_external	
  1757                              <1> cmp_cmd_3:
  1758 000056E6 F9                  <1> 	stc
  1759                              <1> 	; CF = 1 -> internal command word does not match
  1760 000056E7 C3                  <1> 	retn
  1761                              <1> 
  1762                              <1> loc_run_cmd_failed:
  1763                              <1> 	; 15/03/2016
  1764                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1765                              <1> 	; 07/12/2009 (CMD_INTR.ASM)	
  1766                              <1> 	; 29/11/2009
  1767                              <1> 
  1768 000056E8 E855000000          <1> 	call	restore_cdir_after_cmd_fail
  1769                              <1> 
  1770                              <1> loc_run_cmd_failed_cmp_al:
  1771                              <1> 	; End of Restore_CDIR code (29/11/2009)
  1772                              <1> 
  1773 000056ED 3C01                <1> 	cmp	al, 1
  1774 000056EF 74CC                <1> 	je	loc_cmd_failed
  1775                              <1> loc_run_dir_not_found:
  1776 000056F1 3C03                <1> 	cmp	al, 3
  1777 000056F3 750A                <1> 	jne	short loc_run_file_notfound_msg
  1778                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1779 000056F5 BE[D1C00000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1780 000056FA E920E8FFFF          <1> 	jmp	print_msg
  1781                              <1> 
  1782                              <1> loc_run_file_notfound_msg:
  1783 000056FF 3C02                <1> 	cmp	al, 2 ; File not found
  1784 00005701 750A                <1> 	jne	short loc_run_file_drv_read_err
  1785                              <1> 
  1786                              <1> loc_print_file_notfound_msg: 
  1787 00005703 BE[E8C00000]        <1>         mov     esi, Msg_File_Not_Found
  1788                              <1> 	;call	proc_printmsg
  1789                              <1> 	;retn
  1790 00005708 E912E8FFFF          <1> 	jmp	print_msg
  1791                              <1> 
  1792                              <1> loc_run_file_drv_read_err:
  1793                              <1> 	; Err: 1Eh (Read fault)
  1794 0000570D 3C1E                <1> 	cmp	al, 1Eh ; Drive not ready or read error
  1795 0000570F 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1796                              <1> 	;
  1797 00005711 3C15                <1> 	cmp	al, 15h ; Drive not ready (or read error)
  1798 00005713 750A                <1> 	jne	short loc_run_file_toobig
  1799                              <1> 
  1800                              <1> loc_run_file_print_drv_read_err:
  1801 00005715 BE[8EC00000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1802 0000571A E900E8FFFF          <1> 	jmp	print_msg
  1803                              <1> 
  1804                              <1> loc_run_file_toobig:
  1805 0000571F 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1806 00005721 750A                <1> 	jne	short loc_run_misc_error
  1807 00005723 BE[30C10000]        <1> 	mov	esi, Msg_Insufficient_Memory
  1808 00005728 E9F2E7FFFF          <1> 	jmp	print_msg
  1809                              <1> 
  1810                              <1> 	; 15/03/2016
  1811                              <1> print_misc_error_msg:
  1812                              <1> loc_run_misc_error:
  1813                              <1> 	; AL = Error code
  1814 0000572D E87DC2FFFF          <1> 	call	bytetohex
  1815 00005732 66A3[64C10000]      <1>         mov     [error_code_hex], ax
  1816                              <1> 	
  1817 00005738 BE[47C10000]        <1> 	mov	esi, Msg_Error_Code 
  1818                              <1> 	;call	print_msg 
  1819                              <1> 	;retn
  1820                              <1> 
  1821 0000573D E9DDE7FFFF          <1> 	jmp	print_msg
  1822                              <1> 
  1823                              <1> restore_cdir_after_cmd_fail:
  1824                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1825 00005742 50                  <1> 	push	eax
  1826 00005743 8A3D[02D80000]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1827                              <1> 				; of the 'run' command.
  1828 00005749 3A3D[A2CF0000]      <1> 	cmp	bh, [Current_Drv]
  1829 0000574F 7409                <1> 	je	short loc_run_restore_cdir
  1830 00005751 88FA                <1> 	mov	dl, bh
  1831 00005753 E8CBF0FFFF          <1> 	call	change_current_drive 
  1832 00005758 EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1833                              <1> 
  1834                              <1> loc_run_restore_cdir:
  1835 0000575A 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1836 00005761 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1837 00005763 30DB                <1> 	xor	bl, bl
  1838 00005765 0FB7F3              <1> 	movzx	esi, bx
  1839 00005768 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1840 0000576E E862F1FFFF          <1> 	call	restore_current_directory
  1841                              <1> 
  1842                              <1> loc_run_err_pass_restore_cdir:
  1843 00005773 58                  <1> 	pop	eax
  1844 00005774 C3                  <1> 	retn
  1845                              <1> 
  1846                              <1> print_directory_list:
  1847                              <1> 	; 10/02/2016
  1848                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1849                              <1> 	; 06/12/2009 ('cmp_cmd_dir')	
  1850                              <1> 	;
  1851 00005775 66C705[44D90000]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1851 0000577D 08                  <1>
  1852 0000577E A0[A2CF0000]        <1> 	mov	al, [Current_Drv]
  1853 00005783 A2[02D80000]        <1> 	mov	[RUN_CDRV], al
  1854                              <1> get_dfname_fchar:
  1855 00005788 AC                  <1> 	lodsb
  1856 00005789 3C20                <1> 	cmp	al, 20h
  1857 0000578B 74FB                <1> 	je	short get_dfname_fchar
  1858 0000578D 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1859 00005793 3C2D                <1> 	cmp	al, '-'
  1860 00005795 7542                <1> 	jne	short loc_print_dir_call_flt
  1861                              <1> get_next_attr_char:
  1862 00005797 AC                  <1> 	lodsb
  1863 00005798 3C20                <1> 	cmp	al, 20h
  1864 0000579A 74FB                <1> 	je	short get_next_attr_char
  1865 0000579C 0F821BFFFFFF        <1>         jb      loc_cmd_failed
  1866 000057A2 24DF                <1> 	and	al, 0DFh
  1867 000057A4 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1868 000057A6 7512                <1> 	jne	short pass_only_directories
  1869 000057A8 AC                  <1> 	lodsb
  1870 000057A9 3C20                <1> 	cmp	al, 20h
  1871 000057AB 0F870CFFFFFF        <1>         ja      loc_cmd_failed
  1872 000057B1 800D[44D90000]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1873 000057B8 EB18                <1> 	jmp	short get_dfname_fchar_attr
  1874                              <1> pass_only_directories:
  1875 000057BA 3C46                <1> 	cmp	al, 'F'	; files only ?
  1876 000057BC 0F85B0000000        <1>         jne     check_attr_s
  1877 000057C2 AC                  <1> 	lodsb
  1878 000057C3 3C20                <1> 	cmp	al, 20h
  1879 000057C5 0F87F2FEFFFF        <1>         ja      loc_cmd_failed
  1880 000057CB 800D[45D90000]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1881                              <1> get_dfname_fchar_attr:
  1882 000057D2 AC                  <1> 	lodsb
  1883 000057D3 3C20                <1> 	cmp	al, 20h
  1884 000057D5 74FB                <1> 	je	short get_dfname_fchar_attr
  1885 000057D7 725E                <1> 	jb	short loc_print_dir_call_all
  1886                              <1> 
  1887                              <1> loc_print_dir_call_flt:
  1888 000057D9 4E                  <1> 	dec	esi
  1889 000057DA BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  1890 000057DF E8D5250000          <1> 	call	parse_path_name
  1891 000057E4 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1892 000057E6 3C01                <1> 	cmp	al, 1
  1893 000057E8 0F87FAFEFFFF        <1>         ja      loc_run_cmd_failed
  1894                              <1> 
  1895                              <1> loc_print_dir_change_drv_1:
  1896 000057EE 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  1897                              <1> loc_print_dir_change_drv_2:
  1898 000057F4 3A15[02D80000]      <1> 	cmp	dl, [RUN_CDRV]
  1899 000057FA 740B                <1> 	je	short loc_print_dir_change_directory 
  1900 000057FC E822F0FFFF          <1> 	call	change_current_drive
  1901 00005801 0F82E1FEFFFF        <1>         jc      loc_run_cmd_failed
  1902                              <1> loc_print_dir_change_directory:
  1903 00005807 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1904 0000580E 761D                <1> 	jna	short pass_print_dir_change_directory
  1905                              <1> 
  1906 00005810 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  1907 00005816 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  1908 0000581B 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1909 0000581D E8831F0000          <1> 	call	change_current_directory
  1910 00005822 0F82C0FEFFFF        <1>         jc      loc_run_cmd_failed
  1911                              <1> 
  1912                              <1> loc_print_dir_change_prompt_dir_string:
  1913 00005828 E8981E0000          <1> 	call	change_prompt_dir_string
  1914                              <1> 
  1915                              <1> pass_print_dir_change_directory:
  1916 0000582D BE[88D90000]        <1> 	mov	esi, FindFile_Name
  1917 00005832 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1918 00005835 7706                <1> 	ja	short loc_print_dir_call
  1919                              <1> 
  1920                              <1> loc_print_dir_call_all:
  1921 00005837 C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1922                              <1> loc_print_dir_call:
  1923 0000583D E87E000000          <1> 	call	print_directory
  1924                              <1> 
  1925 00005842 8A15[02D80000]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1926 00005848 3A15[A2CF0000]      <1> 	cmp	dl, [Current_Drv]
  1927 0000584E 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1928 00005850 E8CEEFFFFF          <1> 	call	change_current_drive 
  1929 00005855 C3                  <1> 	retn
  1930                              <1> 
  1931                              <1> loc_print_dir_call_restore_cdir_retn:
  1932 00005856 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1933 0000585D 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  1934                              <1> 
  1935 0000585F BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1936 00005864 31C0                <1> 	xor	eax, eax
  1937 00005866 88D4                <1> 	mov	ah, dl
  1938 00005868 01C6                <1> 	add	esi, eax
  1939                              <1> 
  1940 0000586A E866F0FFFF          <1> 	call	restore_current_directory
  1941                              <1> 
  1942                              <1> pass_print_dir_call_restore_cdir_retn:
  1943 0000586F C3                  <1> 	retn
  1944                              <1> 
  1945                              <1> check_attr_s_cap:
  1946 00005870 24DF                <1> 	and	al, 0DFh
  1947                              <1> check_attr_s:
  1948 00005872 3C53                <1> 	cmp	al, 'S'
  1949 00005874 7514                <1> 	jne	short pass_attr_s
  1950 00005876 800D[44D90000]04    <1> 	or	byte [AttributesMask], 4 ; system
  1951 0000587D AC                  <1> 	lodsb
  1952 0000587E 3C20                <1> 	cmp	al, 20h
  1953 00005880 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  1954 00005886 72AF                <1> 	jb	short loc_print_dir_call_all
  1955 00005888 24DF                <1> 	and	al, 0DFh
  1956                              <1> pass_attr_s:
  1957 0000588A 3C48                <1> 	cmp	al, 'H'
  1958 0000588C 7514                <1> 	jne	short pass_attr_h
  1959 0000588E 800D[44D90000]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  1960                              <1> pass_attr_shr:
  1961 00005895 AC                  <1> 	lodsb
  1962 00005896 3C20                <1> 	cmp	al, 20h
  1963 00005898 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  1964 0000589E 7297                <1> 	jb	short loc_print_dir_call_all
  1965 000058A0 EBCE                <1> 	jmp	short check_attr_s_cap
  1966                              <1> 
  1967                              <1> pass_attr_h:
  1968 000058A2 3C52                <1> 	cmp	al, 'R'
  1969 000058A4 7509                <1> 	jne	short pass_attr_r
  1970 000058A6 800D[44D90000]01    <1> 	or	byte [AttributesMask], 1 ; read only
  1971 000058AD EBE6                <1> 	jmp	short pass_attr_shr
  1972                              <1> 
  1973                              <1> pass_attr_r:
  1974 000058AF 3C41                <1> 	cmp	al, 'A'
  1975 000058B1 0F8506FEFFFF        <1>         jne     loc_cmd_failed
  1976 000058B7 800D[44D90000]20    <1> 	or	byte [AttributesMask], 20h ; archive
  1977 000058BE EBD5                <1> 	jmp	short pass_attr_shr
  1978                              <1> 
  1979                              <1> print_directory:
  1980                              <1> 	; 11/02/2016
  1981                              <1> 	; 10/02/2016
  1982                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1983                              <1> 	; 30/10/2010 ('proc_print_directory')	
  1984                              <1> 	; 19/09/2009
  1985                              <1> 	; 2005 
  1986                              <1> 	; INPUT ->
  1987                              <1> 	;	ESI = Asciiz File/Dir Name Address
  1988                              <1> 
  1989 000058C0 56                  <1> 	push	esi
  1990                              <1> 
  1991 000058C1 29C0                <1> 	sub	eax, eax
  1992                              <1> 
  1993 000058C3 66A3[D0D90000]      <1> 	mov	word [Dir_Count], ax ; 0
  1994 000058C9 66A3[CED90000]      <1> 	mov 	word [File_Count], ax ; 0
  1995 000058CF A3[D2D90000]        <1> 	mov 	dword [Total_FSize], eax ; 0
  1996                              <1> 
  1997 000058D4 E85DE6FFFF          <1> 	call    clear_screen
  1998                              <1> 	
  1999 000058D9 31C9                <1> 	xor	ecx, ecx	
  2000 000058DB 8A2D[A2CF0000]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  2001 000058E1 A0[A3CF0000]        <1> 	mov     al, [Current_Dir_Drv] 
  2002 000058E6 A2[8CBF0000]        <1> 	mov     [Dir_Drive_Name], al
  2003 000058EB BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2004 000058F0 01CE                <1> 	add	esi, ecx
  2005                              <1> 
  2006 000058F2 E866F9FFFF          <1> 	call	move_volume_name_and_serial_no
  2007 000058F7 7306                <1> 	jnc	short print_dir_strlen_check
  2008                              <1> 
  2009 000058F9 5E                  <1> 	pop	esi
  2010                              <1> 	;call	beeper
  2011                              <1> 	;retn
  2012 000058FA E99EBFFFFF          <1> 	jmp	beeper  ; beep ! and return
  2013                              <1> 
  2014                              <1> print_dir_strlen_check:
  2015 000058FF BE[A5CF0000]        <1> 	mov	esi, Current_Dir_Root
  2016 00005904 BF[29C00000]        <1> 	mov	edi, Dir_Str_Root
  2017                              <1> 	
  2018                              <1> 	;xor	ecx, ecx
  2019 00005909 8A0D[01D00000]      <1>         mov     cl, [Current_Dir_StrLen]
  2020 0000590F FEC1                <1> 	inc	cl
  2021 00005911 80F940              <1> 	cmp	cl, 64
  2022 00005914 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2023 00005916 46                  <1> 	inc	esi
  2024 00005917 01CE                <1> 	add	esi, ecx
  2025 00005919 83EE40              <1> 	sub	esi, 64 
  2026 0000591C 47                  <1> 	inc	edi
  2027 0000591D B82E2E2E20          <1> 	mov	eax, '... ' 
  2028 00005922 AB                  <1> 	stosd
  2029                              <1>  
  2030                              <1> pass_print_dir_strlen_shorting:
  2031 00005923 F3A4                <1> 	rep	movsb
  2032                              <1> 
  2033 00005925 BE[7FBF0000]        <1> 	mov	esi, Dir_Drive_Str
  2034 0000592A E8F0E5FFFF          <1> 	call	print_msg
  2035                              <1> 
  2036 0000592F BE[DEBF0000]        <1> 	mov	esi, Vol_Serial_Header
  2037 00005934 E8E6E5FFFF          <1> 	call	print_msg
  2038                              <1> 
  2039 00005939 BE[1EC00000]        <1> 	mov	esi, Dir_Str_Header
  2040 0000593E E8DCE5FFFF          <1> 	call	print_msg
  2041                              <1> 	
  2042 00005943 BE[74CB0000]        <1> 	mov	esi, next2line
  2043 00005948 E8D2E5FFFF          <1> 	call	print_msg
  2044                              <1> 
  2045                              <1> loc_print_dir_first_file:
  2046 0000594D C605[E5D90000]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2047 00005954 66A1[44D90000]      <1> 	mov	ax, [AttributesMask]
  2048 0000595A 5E                  <1> 	pop	esi
  2049                              <1> 
  2050 0000595B E859020000          <1> 	call	find_first_file
  2051 00005960 0F826F010000        <1>         jc      loc_dir_ok
  2052                              <1> 	 
  2053                              <1> loc_dfname_use_this:
  2054                              <1> 	; bl =	File Attributes (bh = Long Name Entry Length)
  2055 00005966 F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2056 00005969 741B                <1> 	jz	short loc_not_dir
  2057                              <1> 
  2058 0000596B 66FF05[D0D90000]    <1> 	inc	word [Dir_Count]
  2059 00005972 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2060 00005974 BE[6AC10000]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2061 00005979 BF[81C10000]        <1> 	mov	edi, Dir_Or_FileSize
  2062                              <1> 	; move 10 bytes
  2063 0000597E A5                  <1> 	movsd
  2064 0000597F A5                  <1> 	movsd
  2065 00005980 66A5                <1> 	movsw	    	
  2066 00005982 89D6                <1> 	mov	esi, edx
  2067 00005984 EB36                <1> 	jmp     short loc_dir_attribute
  2068                              <1> 
  2069                              <1> loc_not_dir:
  2070 00005986 66FF05[CED90000]    <1> 	inc	word [File_Count]
  2071 0000598D 0105[D2D90000]      <1> 	add	[Total_FSize], eax
  2072                              <1> 
  2073 00005993 B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2074 00005998 89CF                <1> 	mov	edi, ecx
  2075 0000599A 81C7[81C10000]      <1> 	add	edi, Dir_Or_FileSize
  2076                              <1> loc_dir_rdivide:
  2077 000059A0 29D2                <1> 	sub	edx, edx
  2078 000059A2 F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2079 000059A4 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2080 000059A7 4F                  <1> 	dec	edi
  2081 000059A8 8817                <1> 	mov     [edi], dl
  2082 000059AA 21C0                <1> 	and	eax, eax
  2083 000059AC 75F2                <1> 	jnz	short loc_dir_rdivide
  2084                              <1> 
  2085                              <1> loc_dir_fill_space:
  2086 000059AE 81FF[81C10000]      <1> 	cmp     edi, Dir_Or_FileSize
  2087 000059B4 7606                <1> 	jna     short loc_dir_attribute
  2088 000059B6 4F                  <1> 	dec     edi
  2089 000059B7 C60720              <1> 	mov     byte [edi], 20h
  2090 000059BA EBF2                <1> 	jmp     short loc_dir_fill_space
  2091                              <1> 
  2092                              <1> loc_dir_attribute:
  2093 000059BC C705[8CC10000]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2093 000059C4 2020                <1>
  2094                              <1> 
  2095 000059C6 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2096 000059C9 7207                <1> 	jb	short loc_dir_pass_arch
  2097 000059CB C605[8FC10000]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2098                              <1> 
  2099                              <1> loc_dir_pass_arch:
  2100 000059D2 80E307              <1> 	and	bl, 7
  2101 000059D5 7428                <1> 	jz	short loc_dir_file_name
  2102 000059D7 88DF                <1> 	mov	bh, bl
  2103 000059D9 80E303              <1> 	and	bl, 3
  2104 000059DC 38DF                <1> 	cmp	bh, bl
  2105 000059DE 7607                <1> 	jna	short loc_dir_pass_s
  2106 000059E0 C605[8CC10000]53    <1> 	mov	byte [File_Attribute], 'S'
  2107                              <1> 
  2108                              <1> loc_dir_pass_s:
  2109 000059E7 80E302              <1> 	and     bl,2
  2110 000059EA 7407                <1> 	jz      short loc_dir_pass_h
  2111 000059EC C605[8DC10000]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2112                              <1> loc_dir_pass_h:
  2113 000059F3 80E701              <1> 	and     bh,1
  2114 000059F6 7407                <1> 	jz      short loc_dir_file_name
  2115 000059F8 C605[8EC10000]52    <1> 	mov     byte [File_Attribute+2], 'R'
  2116                              <1> loc_dir_file_name:
  2117                              <1> 	;mov     bx, [esi+18h] ; Date
  2118                              <1> 	;mov     dx, [esi+16h] ; Time
  2119 000059FF 8B5E16              <1> 	mov	ebx, [esi+16h]
  2120 00005A02 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2121 00005A04 BF[74C10000]        <1> 	mov     edi, File_Name
  2122                              <1> 	; move 8 bytes
  2123 00005A09 A5                  <1> 	movsd
  2124 00005A0A A5                  <1> 	movsd
  2125 00005A0B C60720              <1> 	mov	byte [edi], 20h
  2126 00005A0E 47                  <1> 	inc	edi
  2127                              <1> 	; move 3 bytes
  2128 00005A0F 66A5                <1> 	movsw
  2129 00005A11 A4                  <1> 	movsb
  2130 00005A12 89CE                <1> 	mov	esi, ecx
  2131                              <1> 
  2132                              <1> Dir_Time_start:
  2133                              <1> 	;mov	ax, dx		; Time
  2134 00005A14 6689D8              <1> 	mov	ax, bx
  2135 00005A17 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2136 00005A1B 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2137 00005A1F D40A                <1> 	aam			; Q([AL]/10)->AH
  2138                              <1> 				; R([AL]/10)->AL
  2139                              <1> 				; [AL]+[AH]= Minute as BCD
  2140 00005A21 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2141 00005A25 86E0                <1> 	xchg	ah, al
  2142 00005A27 66A3[9FC10000]      <1> 	mov	[File_Minute], ax
  2143                              <1> 
  2144                              <1> 	;mov	al, dh
  2145 00005A2D 88F8                <1> 	mov	al, bh
  2146 00005A2F C0E803              <1> 	shr	al, 3		; shift right 3 times
  2147 00005A32 D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2148 00005A34 660D3030            <1> 	or	ax, '00'
  2149 00005A38 86E0                <1> 	xchg	ah, al
  2150 00005A3A 66A3[9CC10000]      <1> 	mov     [File_Hour], ax
  2151                              <1> 
  2152 00005A40 C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2153                              <1> 	
  2154                              <1> Dir_Date_start:
  2155 00005A43 6689D8              <1> 	mov	ax, bx		; Date
  2156 00005A46 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2157 00005A4A D40A                <1> 	aam			; Q([AL]/10)->AH
  2158                              <1> 				; R([AL]/10)->AL
  2159                              <1> 				; [AL]+[AH]= Day as BCD
  2160 00005A4C 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2161 00005A50 86C4                <1> 	xchg	al, ah
  2162                              <1> 
  2163 00005A52 66A3[91C10000]      <1> 	mov	[File_Day], ax
  2164                              <1> 
  2165 00005A58 6689D8              <1> 	mov	ax, bx
  2166 00005A5B 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2167 00005A5F 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2168 00005A63 D40A                <1> 	aam
  2169 00005A65 660D3030            <1> 	or	ax, '00'
  2170 00005A69 86E0                <1> 	xchg	ah, al
  2171 00005A6B 66A3[94C10000]      <1> 	mov	[File_Month], ax
  2172                              <1> 
  2173 00005A71 6689D8              <1> 	mov	ax, bx
  2174 00005A74 66C1E809            <1> 	shr     ax, 9
  2175 00005A78 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2176 00005A7C 6605BC07            <1> 	add	ax, 1980
  2177                              <1> 
  2178 00005A80 B10A                <1> 	mov	cl, 10
  2179 00005A82 F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2180 00005A84 80CC30              <1> 	or	ah, '0'
  2181 00005A87 8825[9AC10000]      <1> 	mov	[File_Year+3], ah
  2182 00005A8D D40A                <1> 	aam
  2183 00005A8F 86E0                <1> 	xchg	ah, al
  2184 00005A91 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2185 00005A94 8825[99C10000]      <1> 	mov	[File_Year+2], ah
  2186 00005A9A D40A                <1> 	aam
  2187 00005A9C 86C4                <1> 	xchg	al, ah
  2188 00005A9E 660D3030            <1> 	or	ax, '00'
  2189 00005AA2 66A3[97C10000]      <1> 	mov	[File_Year], ax
  2190                              <1> 
  2191                              <1> loc_show_line:
  2192 00005AA8 56                  <1> 	push	esi
  2193 00005AA9 BE[74C10000]        <1> 	mov     esi, File_Name
  2194 00005AAE E86CE4FFFF          <1> 	call	print_msg
  2195 00005AB3 BE[76CB0000]        <1> 	mov	esi, nextline
  2196 00005AB8 E862E4FFFF          <1> 	call	print_msg
  2197 00005ABD 5E                  <1> 	pop	esi
  2198                              <1> 
  2199 00005ABE FE0D[E5D90000]      <1> 	dec	byte [PrintDir_RowCounter]
  2200 00005AC4 0F84D4000000        <1>         jz      pause_dir_scroll
  2201                              <1> 
  2202                              <1> loc_next_entry:
  2203 00005ACA E899010000          <1> 	call	find_next_file
  2204 00005ACF 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2205                              <1> 
  2206                              <1> loc_dir_ok:
  2207 00005AD5 B90A000000          <1> 	mov     ecx, 10
  2208 00005ADA 66A1[D0D90000]      <1> 	mov	ax, [Dir_Count]
  2209 00005AE0 BF[B5C10000]        <1> 	mov	edi, Decimal_Dir_Count
  2210 00005AE5 6639C8              <1> 	cmp	ax, cx ; 10
  2211 00005AE8 7216                <1> 	jb	short pass_ddc
  2212 00005AEA 47                  <1> 	inc	edi
  2213 00005AEB 6683F864            <1> 	cmp	ax, 100
  2214 00005AEF 720F                <1> 	jb	short pass_ddc
  2215 00005AF1 47                  <1> 	inc	edi
  2216 00005AF2 663DE803            <1> 	cmp	ax, 1000
  2217 00005AF6 7208                <1> 	jb	short pass_ddc
  2218 00005AF8 47                  <1> 	inc	edi
  2219 00005AF9 663D1027            <1> 	cmp	ax, 10000
  2220 00005AFD 7201                <1> 	jb	short pass_ddc
  2221 00005AFF 47                  <1> 	inc	edi
  2222                              <1> pass_ddc:
  2223 00005B00 886F01              <1> 	mov     [edi+1], ch ; 0
  2224                              <1> loc_ddc_rediv:
  2225 00005B03 31D2                <1> 	xor     edx, edx
  2226 00005B05 66F7F1              <1> 	div     cx	; 10
  2227 00005B08 80C230              <1> 	add     dl, '0'
  2228 00005B0B 8817                <1> 	mov     [edi], dl
  2229 00005B0D 4F                  <1> 	dec     edi
  2230 00005B0E 6609C0              <1> 	or	ax, ax
  2231 00005B11 75F0                <1> 	jnz	short loc_ddc_rediv
  2232                              <1> 
  2233 00005B13 66A1[CED90000]      <1> 	mov     ax, [File_Count]
  2234 00005B19 BF[A4C10000]        <1> 	mov     edi, Decimal_File_Count
  2235 00005B1E 6639C8              <1> 	cmp     ax, cx ; 10
  2236 00005B21 7216                <1> 	jb      short pass_dfc
  2237 00005B23 47                  <1> 	inc     edi
  2238 00005B24 6683F864            <1> 	cmp     ax, 100
  2239 00005B28 720F                <1> 	jb      short pass_dfc
  2240 00005B2A 47                  <1> 	inc     edi
  2241 00005B2B 663DE803            <1> 	cmp     ax, 1000
  2242 00005B2F 7208                <1> 	jb      short pass_dfc
  2243 00005B31 47                  <1> 	inc     edi
  2244 00005B32 663D1027            <1> 	cmp     ax, 10000
  2245 00005B36 7201                <1> 	jb      short pass_dfc
  2246 00005B38 47                  <1> 	inc     edi
  2247                              <1> pass_dfc:
  2248                              <1> 	;mov    cx, 10
  2249 00005B39 886F01              <1> 	mov     [edi+1], ch ; 00
  2250                              <1> loc_dfc_rediv:
  2251                              <1> 	;xor	dx, dx
  2252 00005B3C 30D2                <1> 	xor	dl, dl
  2253 00005B3E 66F7F1              <1> 	div	cx
  2254 00005B41 80C230              <1> 	add	dl, '0'
  2255 00005B44 8817                <1> 	mov	[edi], dl
  2256 00005B46 4F                  <1> 	dec	edi
  2257 00005B47 6609C0              <1> 	or	ax, ax
  2258 00005B4A 75F0                <1> 	jnz	short loc_dfc_rediv
  2259                              <1> 
  2260 00005B4C BF[E4D90000]        <1> 	mov     edi, TFS_Dec_End
  2261                              <1>         ;mov    byte [edi], 0
  2262 00005B51 A1[D2D90000]        <1> 	mov     eax, [Total_FSize]
  2263                              <1> 	;mov    ecx, 10
  2264                              <1> rediv_tfs_hex:
  2265                              <1> 	;sub	edx, edx
  2266 00005B56 28D2                <1> 	sub	dl, dl
  2267 00005B58 F7F1                <1> 	div	ecx
  2268 00005B5A 80C230              <1> 	add	dl, '0'
  2269 00005B5D 4F                  <1> 	dec     edi
  2270 00005B5E 8817                <1> 	mov     [edi], dl
  2271 00005B60 21C0                <1> 	and	eax, eax
  2272 00005B62 75F2                <1> 	jnz	short rediv_tfs_hex
  2273                              <1> 	
  2274 00005B64 893D[D6D90000]      <1> 	mov	[TFS_Dec_Begin], edi
  2275 00005B6A BE[A2C10000]        <1> 	mov	esi, Decimal_File_Count_Header
  2276 00005B6F E8ABE3FFFF          <1> 	call	print_msg
  2277 00005B74 BE[AAC10000]        <1> 	mov	esi, str_files
  2278 00005B79 E8A1E3FFFF          <1> 	call	print_msg
  2279 00005B7E BE[BBC10000]        <1> 	mov	esi, str_dirs
  2280 00005B83 E897E3FFFF          <1> 	call	print_msg
  2281 00005B88 8B35[D6D90000]      <1> 	mov	esi, [TFS_Dec_Begin]
  2282 00005B8E E88CE3FFFF          <1> 	call	print_msg
  2283 00005B93 BE[CCC10000]        <1> 	mov	esi, str_bytes
  2284 00005B98 E882E3FFFF          <1> 	call	print_msg
  2285                              <1> 
  2286 00005B9D C3                  <1> 	retn
  2287                              <1> 
  2288                              <1> pause_dir_scroll:
  2289 00005B9E 28E4                <1> 	sub	ah, ah           
  2290 00005BA0 E84AB0FFFF          <1> 	call	int16h
  2291 00005BA5 3C1B                <1> 	cmp	al, 1Bh
  2292 00005BA7 0F8428FFFFFF        <1>         je      loc_dir_ok
  2293 00005BAD C605[E5D90000]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2294 00005BB4 E911FFFFFF          <1>         jmp     loc_next_entry
  2295                              <1> 
  2296                              <1> find_first_file:
  2297                              <1> 	; 11/02/2015
  2298                              <1> 	; 10/02/2016
  2299                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2300                              <1> 	; 09/10/2011
  2301                              <1> 	; 17/09/2009
  2302                              <1> 	; 2005
  2303                              <1> 	; INPUT ->
  2304                              <1> 	;	ESI = ASCIIZ File/Dir Name Address (in Current Directory)
  2305                              <1> 	;	AL = Attributes AND mask (The AND result must be equal to AL)
  2306                              <1> 	;	      bit 0 = Read Only
  2307                              <1> 	;	      bir 1 = Hidden
  2308                              <1> 	;	      bit 2 = System
  2309                              <1> 	;	      bit 3 = Volume Label
  2310                              <1> 	;	      bit 4 = Directory
  2311                              <1> 	;	      bit 5 = Archive
  2312                              <1> 	;	      bit 6 = Reserved, must be 0
  2313                              <1> 	;	      bit 7 = Reserved, must be 0
  2314                              <1> 	;       AH = Attributes Negative AND mask (The AND result must be ZERO)
  2315                              <1> 	;
  2316                              <1> 	; OUTPUT ->
  2317                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2318                              <1> 	;	CF = 0 ->
  2319                              <1> 	;	     ESI = Directory Entry (FindFile_DirEntry) Location
  2320                              <1> 	;	     EDI = Directory Buffer Directory Entry Location
  2321                              <1> 	;	     EAX = File Size
  2322                              <1> 	;	      BL = Attributes of The File/Directory
  2323                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2324                              <1> 	;             DX > 0 : Ambiguous filename chars are used
  2325                              <1> 	;
  2326                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2327                              <1> 
  2328 00005BB9 66A3[96D90000]      <1> 	mov	[FindFile_AttributesMask], ax
  2329 00005BBF BF[98D90000]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2330 00005BC4 31C0                <1> 	xor	eax, eax
  2331 00005BC6 B90B000000          <1> 	mov	ecx, 11
  2332 00005BCB F3AB                <1> 	rep	stosd	; 44 bytes
  2333                              <1> 	;stosw		; +2 bytes 
  2334                              <1> 	    
  2335 00005BCD BF[88D90000]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2336 00005BD2 39FE                <1> 	cmp	esi, edi
  2337 00005BD4 7408                <1> 	je	short loc_fff_mfn_ok
  2338 00005BD6 89FA                <1> 	mov	edx, edi 
  2339                              <1> 	 ; move 13 bytes
  2340 00005BD8 A5                  <1> 	movsd
  2341 00005BD9 A5                  <1> 	movsd
  2342 00005BDA A5                  <1> 	movsd
  2343 00005BDB AA                  <1> 	stosb
  2344 00005BDC 89D6                <1> 	mov	esi, edx
  2345                              <1> loc_fff_mfn_ok:
  2346 00005BDE BF[37D90000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2347 00005BE3 E806210000          <1> 	call	convert_file_name
  2348 00005BE8 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2349                              <1> 
  2350 00005BEA 66A1[96D90000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2351                              <1> 	;xor	ecx, ecx
  2352 00005BF0 30C9                <1> 	xor	cl, cl  
  2353 00005BF2 E8021E0000          <1> 	call	locate_current_dir_file
  2354 00005BF7 726E                <1> 	jc	short loc_fff_retn
  2355                              <1> 	; EDI = Directory Entry
  2356                              <1> 	; EBX = Directory Buffer Entry Index/Number
  2357                              <1> 
  2358                              <1> loc_fff_fnf_ln_check:
  2359 00005BF9 30ED                <1> 	xor	ch, ch 
  2360 00005BFB 80F60F              <1> 	xor	dh, 0Fh
  2361 00005BFE 7408                <1> 	jz	short loc_fff_longname_yes
  2362 00005C00 882D[95D90000]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2363 00005C06 EB0C                <1> 	jmp	short loc_fff_longname_no
  2364                              <1> 
  2365                              <1> loc_fff_longname_yes:
  2366                              <1> 	;inc	byte [FindFile_LongNameYes]
  2367 00005C08 8A0D[A2D80000]      <1> 	mov	cl, [LFN_EntryLength]  
  2368 00005C0E 880D[95D90000]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2369                              <1> 
  2370                              <1> loc_fff_longname_no:
  2371                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2372 00005C14 66891D[C0D90000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2373 00005C1B 6689C2              <1> 	mov	dx, ax ; Ambigouos Filename chars used sign > 0
  2374                              <1> 
  2375 00005C1E A0[A2CF0000]        <1> 	mov	al, [Current_Drv]
  2376 00005C23 A2[46D90000]        <1> 	mov	[FindFile_Drv], al 
  2377                              <1> 
  2378 00005C28 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2379 00005C2D A3[B8D90000]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2380                              <1> 
  2381 00005C32 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
  2382 00005C37 A3[BCD90000]        <1> 	mov	[FindFile_DirCluster], eax
  2383                              <1> 
  2384 00005C3C 66FF05[C2D90000]    <1> 	inc	word [FindFile_MatchCounter]
  2385                              <1> 
  2386 00005C43 89FB                <1> 	mov	ebx, edi
  2387 00005C45 89FE                <1> 	mov	esi, edi
  2388 00005C47 BF[98D90000]        <1> 	mov	edi, FindFile_DirEntry
  2389 00005C4C 89F8                <1> 	mov	eax, edi
  2390 00005C4E B108                <1> 	mov	cl, 8
  2391 00005C50 F3A5                <1> 	rep	movsd
  2392 00005C52 89C6                <1> 	mov	esi, eax
  2393 00005C54 89DF                <1> 	mov	edi, ebx
  2394                              <1> 
  2395 00005C56 A1[B4D90000]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2396                              <1> 
  2397 00005C5B 8A1D[A3D90000]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2398 00005C61 8A3D[95D90000]      <1> 	mov	bh, [FindFile_LongNameYes]
  2399                              <1> 
  2400                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  2401                              <1> 	;mov	[FindFile_DirEntryNumber], cx
  2402                              <1> 	;mov	cx, [FindFile_DirEntryNumber]
  2403                              <1> 	; ecx = 0
  2404                              <1> 
  2405                              <1> loc_fff_retn:
  2406 00005C67 C3                  <1> 	retn
  2407                              <1> 
  2408                              <1> find_next_file:
  2409                              <1> 	; 10/02/2016
  2410                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2411                              <1> 	; 06/02/2011
  2412                              <1> 	; 17/09/2009
  2413                              <1> 	; 2005
  2414                              <1> 	; INPUT ->
  2415                              <1> 	;	NONE, Find First File Parameters
  2416                              <1> 	; OUTPUT ->
  2417                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2418                              <1> 	;	CF = 0 -> 
  2419                              <1> 	;	    ESI = Directory Entry (FindFile_DirEntry) Location
  2420                              <1> 	;	    EDI = Directory Buffer Directory Entry Location
  2421                              <1> 	;	    EAX = File Size
  2422                              <1> 	;	      BL = Attributes of The File/Directory
  2423                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2424                              <1> 	;             DX > 0 : Ambiguous filename chars are used 
  2425                              <1> 	;
  2426                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2427                              <1> 
  2428 00005C68 66833D[C2D90000]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2429 00005C70 7707                <1> 	ja	short loc_start_search_next_file
  2430                              <1> 
  2431                              <1> loc_fnf_stc_retn:
  2432 00005C72 F9                  <1> 	stc
  2433                              <1> loc_fnf_ax12h_retn:
  2434 00005C73 B812000000          <1> 	mov	eax, 12h ; 18, No More files
  2435                              <1> ;loc_fnf_retn:
  2436 00005C78 C3                  <1> 	retn
  2437                              <1> 
  2438                              <1> loc_start_search_next_file:
  2439 00005C79 668B1D[C0D90000]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2440 00005C80 6643                <1> 	inc	bx
  2441 00005C82 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2442 00005C89 7719                <1> 	ja	short loc_cont_search_next_file
  2443                              <1> 
  2444                              <1> loc_fnf_search:
  2445 00005C8B BE[37D90000]        <1> 	mov	esi, Dir_Entry_Name
  2446 00005C90 66A1[96D90000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2447 00005C96 6631C9              <1> 	xor	cx, cx
  2448 00005C99 E85D1E0000          <1> 	call	find_directory_entry
  2449 00005C9E 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2450                              <1> 
  2451                              <1> loc_cont_search_next_file:
  2452 00005CA4 31DB                <1> 	xor	ebx, ebx
  2453 00005CA6 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  2454 00005CAC BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2455 00005CB1 01DE                <1> 	add	esi, ebx
  2456                              <1> 
  2457 00005CB3 803D[A0CF0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2458 00005CBA 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2459 00005CBC 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2460 00005CC0 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2461 00005CC2 EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2462                              <1>  
  2463                              <1> loc_fnf_check_FAT_type:
  2464 00005CC4 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2465 00005CC8 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2466                              <1> 
  2467                              <1> loc_fnf_check_next_cluster:
  2468 00005CCA A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
  2469 00005CCF E8DC370000          <1> 	call	get_next_cluster
  2470 00005CD4 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2471 00005CD6 09C0                <1> 	or	eax, eax
  2472 00005CD8 7498                <1> 	jz	short loc_fnf_stc_retn
  2473                              <1> 	;mov	eax, 15h ;Drive not ready or read error
  2474 00005CDA F5                  <1>  	cmc	;stc
  2475                              <1> loc_fnf_retn:
  2476 00005CDB C3                  <1> 	retn
  2477                              <1> 
  2478                              <1> loc_fnf_load_next_dir_cluster:
  2479 00005CDC E8B5390000          <1> 	call	load_FAT_sub_directory
  2480 00005CE1 72F8                <1> 	jc	short loc_fnf_retn
  2481 00005CE3 6631DB              <1> 	xor	bx, bx
  2482 00005CE6 66891D[C0D90000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2483 00005CED EB9C                <1> 	jmp	short loc_fnf_search
  2484                              <1> 
  2485                              <1> get_and_print_longname:
  2486                              <1> 	; 13/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2487                              <1> 	; 24/01/2010
  2488                              <1> 	; 17/10/2009 (CMD_INTR.ASM, 'cmp_cmd_longname')
  2489                              <1> get_longname_fchar:
  2490 00005CEF 803E20              <1> 	cmp	byte [esi], 20h
  2491 00005CF2 7701                <1> 	ja	short loc_find_longname
  2492                              <1> 	;jb	short loc_longname_retn
  2493                              <1> 	;inc	esi
  2494                              <1> 	;je	short get_longname_fchar
  2495                              <1> ;loc_longname_retn:
  2496 00005CF4 C3                  <1> 	retn
  2497                              <1> loc_find_longname:
  2498 00005CF5 E868210000          <1> 	call	find_longname
  2499 00005CFA 7320                <1> 	jnc	short loc_print_longname
  2500                              <1> 	
  2501 00005CFC 08C0                <1> 	or	al, al
  2502 00005CFE 7412                <1> 	jz	short loc_longname_not_found
  2503                              <1> 	  
  2504 00005D00 3C15                <1> 	cmp	al, 15h
  2505 00005D02 0F84BCF7FFFF        <1> 	je	cd_drive_not_ready
  2506                              <1> 
  2507                              <1> loc_ln_file_dir_not_found:
  2508 00005D08 BE[FAC00000]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2509                              <1> 	;call	print_msg	
  2510                              <1>         ;retn
  2511 00005D0D E90DE2FFFF          <1> 	jmp	print_msg
  2512                              <1> 
  2513                              <1> loc_longname_not_found:
  2514 00005D12 BE[19C10000]        <1>         mov     esi, Msg_LongName_Not_Found
  2515                              <1> 	;call	print_msg	
  2516                              <1>         ;retn
  2517 00005D17 E903E2FFFF          <1> 	jmp	print_msg
  2518                              <1> 
  2519                              <1> loc_print_longname:
  2520                              <1> 	;mov	esi, LongFileName
  2521 00005D1C BF[A2D00000]        <1> 	mov	edi, TextBuffer
  2522 00005D21 57                  <1> 	push	edi 
  2523 00005D22 3C00                <1> 	cmp	al, 0
  2524 00005D24 7708                <1> 	ja	short loc_print_longname_1
  2525                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2526 00005D26 AC                  <1> 	lodsb
  2527 00005D27 AA                  <1> 	stosb  
  2528 00005D28 08C0                <1> 	or	al, al
  2529 00005D2A 75FA                <1> 	jnz	short loc_print_FS_longname
  2530 00005D2C EB07                <1> 	jmp	short loc_print_longname_2
  2531                              <1> 	;
  2532                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2533 00005D2E 66AD                <1> 	lodsw
  2534 00005D30 AA                  <1> 	stosb  
  2535 00005D31 08C0                <1> 	or	al, al
  2536 00005D33 75F9                <1> 	jnz	short loc_print_longname_1
  2537                              <1> 	;
  2538                              <1> loc_print_longname_2:	
  2539 00005D35 5E                  <1> 	pop	esi
  2540 00005D36 E8E4E1FFFF          <1> 	call	print_msg
  2541 00005D3B BE[76CB0000]        <1>   	mov	esi, nextline
  2542                              <1> 	;call	print_msg
  2543                              <1> 	;retn
  2544 00005D40 E9DAE1FFFF          <1> 	jmp	print_msg	
  2545                              <1> 
  2546                              <1> show_file:
  2547                              <1> 	; 18/02/2016
  2548                              <1> 	; 17/02/2016
  2549                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2550                              <1> 	; 13/09/2011 (CMD_INTR.ASM, 'cmp_cmd_show')
  2551                              <1> 	; 08/11/2009
  2552                              <1> 
  2553                              <1> loc_show_parse_path_name:
  2554 00005D45 BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  2555 00005D4A E86A200000          <1> 	call	parse_path_name
  2556 00005D4F 0F8268F9FFFF        <1> 	jc	loc_cmd_failed
  2557                              <1> 
  2558                              <1> loc_show_check_filename_exists:
  2559 00005D55 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  2560 00005D5A 803E20              <1> 	cmp	byte [esi], 20h
  2561 00005D5D 0F865AF9FFFF        <1> 	jna	loc_cmd_failed
  2562                              <1> 
  2563                              <1> 	; 15/02/2016 (invalid file name check)
  2564 00005D63 E805020000          <1> 	call	check_filename 	
  2565 00005D68 730A                <1> 	jnc	short loc_show_change_drv
  2566                              <1> 
  2567 00005D6A BE[E2C10000]        <1> 	mov	esi, Msg_invalid_name_chars
  2568 00005D6F E9ABE1FFFF          <1> 	jmp	print_msg
  2569                              <1>    
  2570                              <1> loc_show_change_drv:
  2571 00005D74 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  2572 00005D7A 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  2573 00005D80 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  2574 00005D86 38F2                <1> 	cmp	dl, dh
  2575 00005D88 740B                <1> 	je	short loc_show_change_directory
  2576 00005D8A E894EAFFFF          <1> 	call	change_current_drive
  2577                              <1> 	;jc	loc_file_rw_cmd_failed
  2578 00005D8F 0F8253F9FFFF        <1> 	jc	loc_run_cmd_failed
  2579                              <1> 
  2580                              <1> loc_show_change_directory:
  2581 00005D95 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2582 00005D9C 7618                <1> 	jna	short loc_findload_showfile
  2583                              <1> 
  2584 00005D9E FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2585 00005DA4 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  2586 00005DA9 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2587 00005DAB E8F5190000          <1> 	call	change_current_directory
  2588                              <1> 	;jc	loc_file_rw_cmd_failed
  2589 00005DB0 0F8232F9FFFF        <1> 	jc	loc_run_cmd_failed
  2590                              <1> 
  2591                              <1> ;loc_show_change_prompt_dir_string:
  2592                              <1> 	;call	change_prompt_dir_string
  2593                              <1> 
  2594                              <1> loc_findload_showfile:
  2595                              <1> 	; 15/02/2016
  2596 00005DB6 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  2597 00005DBB BF[37D90000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2598 00005DC0 E8291F0000          <1> 	call	convert_file_name
  2599 00005DC5 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2600                              <1> 
  2601 00005DC7 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2602                              <1> 	; Directory attribute : 10h
  2603                              <1> 	; Volume name attribute: 8h
  2604 00005DC9 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2605                              <1> 	;
  2606 00005DCB 6631C9              <1> 	xor	cx, cx  
  2607 00005DCE E8261C0000          <1> 	call	locate_current_dir_file
  2608                              <1> 	;jc	loc_file_rw_cmd_failed
  2609 00005DD3 0F820FF9FFFF        <1> 	jc	loc_run_cmd_failed
  2610                              <1> 
  2611                              <1> loc_show_load_file:
  2612                              <1> 	; EDI = Directory Entry
  2613 00005DD9 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2614 00005DDD C1E010              <1> 	shl	eax, 16
  2615 00005DE0 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2616 00005DE4 A3[F0D90000]        <1> 	mov	[Show_Cluster], eax
  2617 00005DE9 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2618 00005DEC 21C0                <1> 	and	eax, eax ; Empty file !
  2619 00005DEE 0F8491000000        <1>         jz      end_of_show_file 
  2620 00005DF4 A3[F4D90000]        <1> 	mov	[Show_FileSize], eax
  2621 00005DF9 31C0                <1> 	xor	eax, eax
  2622 00005DFB A3[F8D90000]        <1> 	mov	[Show_FilePointer], eax ; 0
  2623 00005E00 66A3[FCD90000]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2624 00005E06 29DB                <1> 	sub	ebx, ebx
  2625 00005E08 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  2626 00005E0E BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2627 00005E13 01DE                <1> 	add	esi, ebx
  2628 00005E15 8935[ECD90000]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2629                              <1> 
  2630 00005E1B 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2631 00005E1F 7713                <1> 	ja	short loc_show_calculate_cluster_size
  2632                              <1> 	; Singlix FS
  2633                              <1> 	; First Cluster Number is FDT number (in compatibility buffer)
  2634 00005E21 8B15[F0D90000]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2635 00005E27 8915[E8D90000]      <1> 	mov	[Show_FDT], edx
  2636 00005E2D 31C0                <1> 	xor	eax, eax
  2637 00005E2F A3[F0D90000]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2638                              <1> 				    ; (next time it will be 1)			
  2639                              <1> loc_show_calculate_cluster_size:
  2640 00005E34 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec] ; FAT 12-16-32 (512)
  2641                              <1> 	; BX = 512 = [esi+LD_FS_BytesPerSec] ; Singlix FS	
  2642 00005E38 8A4613              <1> 	mov	al, [esi+LD_BPB+BPB_SecPerClust] ; FAT 12-16-32 (<= 128)
  2643                              <1> 	; AL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  2644 00005E3B F7E3                <1> 	mul	ebx	
  2645                              <1> 
  2646                              <1> 	;cmp	eax, 65536 ; non-compatible (very big) cluster size
  2647                              <1> 	;ja	short end_of_show_file	
  2648 00005E3D 66A3[FED90000]      <1> 	mov	[Show_ClusterSize], ax
  2649                              <1> 
  2650                              <1> loc_start_show_file:
  2651 00005E43 BE[76CB0000]        <1> 	mov	esi, nextline
  2652 00005E48 E8D2E0FFFF          <1> 	call	print_msg
  2653                              <1> 
  2654 00005E4D A1[F0D90000]        <1> 	mov	eax, [Show_Cluster]
  2655 00005E52 C605[00DA0000]17    <1> 	mov	byte [Show_RowCount], 23
  2656                              <1> 
  2657                              <1> 	; 17/02/2016
  2658 00005E59 8B35[ECD90000]      <1> 	mov	esi, [Show_LDDDT]
  2659                              <1> 
  2660                              <1> loc_show_next_cluster:
  2661                              <1> 	; 15/02/2016
  2662 00005E5F BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2663                              <1> 	; ESI = Logical DOS drv description table address
  2664 00005E64 E86B380000          <1> 	call	read_cluster
  2665                              <1> 	;jc	loc_file_rw_cmd_failed
  2666 00005E69 0F8279F8FFFF        <1> 	jc	loc_run_cmd_failed
  2667                              <1> 
  2668 00005E6F 31DB                <1> 	xor 	ebx, ebx
  2669                              <1> loc_show_next_byte:
  2670 00005E71 803D[00DA0000]00    <1> 	cmp	byte [Show_RowCount], 0
  2671 00005E78 7521                <1> 	jne	short pass_show_wait_for_key
  2672 00005E7A 30E4                <1> 	xor	ah, ah
  2673 00005E7C E86EADFFFF          <1> 	call	int16h
  2674 00005E81 3C1B                <1> 	cmp	al, 1Bh
  2675 00005E83 750F                <1> 	jne	short pass_exit_show
  2676                              <1> end_of_show_file:
  2677                              <1> pass_show_file:
  2678 00005E85 BE[76CB0000]        <1> 	mov	esi, nextline
  2679 00005E8A E890E0FFFF          <1> 	call	print_msg
  2680 00005E8F E949010000          <1> 	jmp	loc_file_rw_restore_retn
  2681                              <1> 
  2682                              <1> pass_exit_show:
  2683 00005E94 C605[00DA0000]14    <1> 	mov	byte [Show_RowCount], 20
  2684                              <1> pass_show_wait_for_key:
  2685 00005E9B 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2686 00005EA1 8A03                <1> 	mov	al, [ebx]
  2687 00005EA3 0FB61D[08CF0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2688 00005EAA 3C0D                <1> 	cmp	al, 0Dh
  2689 00005EAC 0F858A000000        <1>         jne     loc_show_check_tab_space
  2690 00005EB2 FE0D[00DA0000]      <1> 	dec	byte [Show_RowCount]
  2691                              <1> pass_show_dec_rowcount:
  2692 00005EB8 B407                <1> 	mov	ah, 7 ; (light gray character color, black background)
  2693 00005EBA E800B9FFFF          <1> 	call	WRITE_TTY
  2694                              <1> loc_show_check_eof:
  2695 00005EBF FF05[F8D90000]      <1> 	inc	dword [Show_FilePointer]
  2696 00005EC5 A1[F8D90000]        <1> 	mov	eax, [Show_FilePointer]
  2697 00005ECA 3B05[F4D90000]      <1> 	cmp	eax, [Show_FileSize]
  2698 00005ED0 73B3                <1> 	jnb	short end_of_show_file
  2699 00005ED2 66FF05[FCD90000]    <1> 	inc	word [Show_ClusterPointer]
  2700 00005ED9 0FB71D[FCD90000]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2701                              <1> 
  2702                              <1> 	; 17/02/2016
  2703                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2704 00005EE0 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2705 00005EE5 758A                <1> 	jnz	short loc_show_next_byte
  2706                              <1> 
  2707                              <1> 	; 16/02/2016
  2708 00005EE7 8B35[ECD90000]      <1> 	mov	esi, [Show_LDDDT]
  2709                              <1> 	;
  2710 00005EED 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2711 00005EF1 7719                <1> 	ja	short loc_show_check_fat_cluster_size
  2712                              <1> 
  2713                              <1> 	; Singlix FS
  2714                              <1> 	; 1 sector, more... (cluster size = 1 sector)
  2715 00005EF3 A1[F0D90000]        <1> 	mov	eax, [Show_Cluster]
  2716 00005EF8 40                  <1> 	inc	eax
  2717 00005EF9 A3[F0D90000]        <1> 	mov	[Show_Cluster], eax
  2718                              <1> 
  2719 00005EFE 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2720 00005F01 0F856AFFFFFF        <1>         jnz	loc_show_next_byte
  2721 00005F07 E953FFFFFF          <1> 	jmp     loc_show_next_cluster
  2722                              <1> 	 
  2723                              <1> loc_show_check_fat_cluster_size:
  2724                              <1> 	; 17/02/2016
  2725 00005F0C 663B1D[FED90000]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2726 00005F13 0F8258FFFFFF        <1>         jb	loc_show_next_byte
  2727 00005F19 66C705[FCD90000]00- <1> 	mov	word [Show_ClusterPointer], 0
  2727 00005F21 00                  <1>
  2728                              <1> 
  2729 00005F22 A1[F0D90000]        <1> 	mov	eax, [Show_Cluster]
  2730                              <1> 	;mov	esi, [Show_LDDDT]
  2731                              <1> loc_show_get_next_cluster:
  2732 00005F27 E884350000          <1> 	call	get_next_cluster
  2733                              <1> 	;jc	loc_file_rw_cmd_failed
  2734 00005F2C 0F82B6F7FFFF        <1> 	jc	loc_run_cmd_failed
  2735                              <1> loc_show_update_ccluster:
  2736 00005F32 A3[F0D90000]        <1> 	mov	[Show_Cluster], eax			
  2737 00005F37 E923FFFFFF          <1>         jmp     loc_show_next_cluster
  2738                              <1> 
  2739                              <1> loc_show_check_tab_space:
  2740 00005F3C 3C09                <1> 	cmp	al, 09h
  2741 00005F3E 0F8574FFFFFF        <1>         jne     pass_show_dec_rowcount
  2742                              <1> loc_show_put_tab_space:
  2743                              <1> 	;movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2744 00005F44 E83CB6FFFF          <1> 	call	get_cpos
  2745                              <1> 	; dl = cursor column
  2746 00005F49 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2747                              <1> loc_show_put_space_chars:
  2748                              <1> 	;mov	al, 20h ; space
  2749                              <1> 	;mov 	ah, 7	; color attribute
  2750 00005F4C 66B82007            <1> 	mov	ax, 0720h ; 
  2751 00005F50 0FB61D[08CF0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2752 00005F57 6652                <1> 	push	dx
  2753 00005F59 E861B8FFFF          <1> 	call	WRITE_TTY
  2754 00005F5E 665A                <1> 	pop	dx
  2755                              <1> 	; 18/02/2016
  2756 00005F60 80FA07              <1> 	cmp	dl, 7
  2757 00005F63 0F8356FFFFFF        <1> 	jnb	loc_show_check_eof
  2758 00005F69 FEC2                <1> 	inc	dl
  2759 00005F6B EBDF                <1> 	jmp	short loc_show_put_space_chars
  2760                              <1> 
  2761                              <1> check_filename:
  2762                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2763                              <1> 	; 07/08/2010 (FILE.ASM, 'proc_check_filename')
  2764                              <1> 	; 10/07/2010
  2765                              <1> 	; Derived from 'proc_check_filename'
  2766                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2767                              <1> 	;
  2768                              <1> 	; INPUT -> 
  2769                              <1> 	;	ESI = Dot File Name Location
  2770                              <1> 	; OUTPUT ->
  2771                              <1> 	;	cf = 1 -> error code in AL
  2772                              <1> 	;	     AL = 0Bh -> Invalid file name   
  2773                              <1> 	;	cf = 0 -> valid file name
  2774                              <1> 	; 
  2775                              <1> 	;(EAX, ECX, EDI will be changed)
  2776                              <1> 
  2777                              <1> check_invalid_filename_chars:
  2778                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2779                              <1> 	; 10/07/2010 (FILE.ASM, 'proc_check_invalid_filename_chars')
  2780                              <1> 	; 10/02/2010
  2781                              <1> 	; Derived from 'proc_check_invalid_filename_chars'
  2782                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2783                              <1> 	;
  2784                              <1> 	; INPUT -> 
  2785                              <1> 	;	ESI = ASCIIZ FileName
  2786                              <1> 	; OUTPUT ->
  2787                              <1> 	;	cf = 1 -> invalid
  2788                              <1> 	;	cf = 0 -> valid
  2789                              <1> 	; 
  2790                              <1> 	;(EAX, ECX, ESI, EDI will be changed)
  2791                              <1>   
  2792 00005F6D 56                  <1> 	push	esi
  2793                              <1> 
  2794 00005F6E BF[CEBE0000]        <1>         mov     edi, invalid_fname_chars
  2795 00005F73 AC                  <1> 	lodsb
  2796                              <1> check_filename_next_char:
  2797 00005F74 B914000000          <1> 	mov	ecx, sizeInvFnChars
  2798 00005F79 BF[CEBE0000]        <1> 	mov	edi, invalid_fname_chars
  2799                              <1> loc_scan_invalid_filename_char:
  2800 00005F7E AE                  <1> 	scasb 
  2801 00005F7F 741F                <1> 	je	short loc_invalid_filename_stc 
  2802 00005F81 E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2803 00005F83 AC                  <1> 	lodsb
  2804 00005F84 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2805 00005F86 77EC                <1> 	ja	short check_filename_next_char
  2806                              <1> 
  2807                              <1> check_filename_dot:
  2808 00005F88 8B3424              <1> 	mov	esi, [esp]
  2809                              <1> 
  2810 00005F8B B421                <1> 	mov	ah, 21h
  2811 00005F8D B908000000          <1> 	mov	ecx, 8
  2812                              <1> loc_check_filename_next_char:
  2813 00005F92 AC                  <1> 	lodsb
  2814 00005F93 3C2E                <1> 	cmp	al, 2Eh
  2815 00005F95 7511                <1> 	jne	short pass_check_fn_dot_check
  2816                              <1> loc_check_filename_ext_0:
  2817 00005F97 AC                  <1> 	lodsb
  2818 00005F98 38E0                <1> 	cmp	al, ah ; 21h
  2819 00005F9A 7205                <1> 	jb	short loc_invalid_filename
  2820 00005F9C 3C2E                <1> 	cmp	al, 2Eh
  2821 00005F9E 7519                <1> 	jne	short loc_check_filename_ext_1
  2822                              <1> 
  2823                              <1> loc_invalid_filename_stc:
  2824                              <1> loc_check_fn_stc_rtn:
  2825 00005FA0 F9                  <1> 	stc
  2826                              <1> loc_invalid_filename:
  2827 00005FA1 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  2828                              <1> 	; Invalid file name chars
  2829                              <1> loc_check_fn_rtn:
  2830 00005FA6 5E                  <1> 	pop	esi
  2831 00005FA7 C3                  <1> 	retn
  2832                              <1> 
  2833                              <1> pass_check_fn_dot_check:
  2834 00005FA8 38E0                <1> 	cmp	al, ah ; 21h
  2835 00005FAA 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2836 00005FAC E2E4                <1> 	loop	loc_check_filename_next_char
  2837 00005FAE AC                  <1> 	lodsb
  2838 00005FAF 38E0                <1> 	cmp	al, ah ; 21h
  2839 00005FB1 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2840 00005FB3 3C2E                <1> 	cmp	al, 2Eh
  2841 00005FB5 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2842 00005FB7 EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2843                              <1> 
  2844                              <1> loc_check_filename_ext_1:
  2845 00005FB9 AC                  <1> 	lodsb
  2846 00005FBA 38E0                <1> 	cmp	al, ah ; 21h
  2847 00005FBC 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2848 00005FBE 3C2E                <1> 	cmp	al, 2Eh
  2849 00005FC0 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2850 00005FC2 AC                  <1> 	lodsb
  2851 00005FC3 38E0                <1> 	cmp	al, ah ; 21h
  2852 00005FC5 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2853 00005FC7 3C2E                <1> 	cmp	al, 2Eh
  2854 00005FC9 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2855 00005FCB AC                  <1> 	lodsb
  2856 00005FCC 38E0                <1> 	cmp	al, ah ; 21h
  2857 00005FCE 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2858                              <1> 
  2859                              <1> loc_check_fn_clc_rtn:
  2860 00005FD0 5E                  <1> 	pop	esi
  2861 00005FD1 F8                  <1> 	clc
  2862 00005FD2 C3                  <1> 	retn
  2863                              <1> 
  2864                              <1> loc_print_deleted_message:
  2865 00005FD3 BE[B7C20000]        <1> 	mov	esi, Msg_Deleted
  2866 00005FD8 E842DFFFFF          <1> 	call	print_msg
  2867                              <1> 
  2868                              <1> 	;clc
  2869                              <1> 
  2870                              <1> loc_file_rw_restore_retn:
  2871                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2872                              <1> 	; 28/02/2010 (CMD_INTR.ASM)
  2873                              <1> loc_file_rw_cmd_failed:
  2874 00005FDD 9C                  <1> 	pushf 
  2875 00005FDE E85FF7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2876 00005FE3 9D                  <1> 	popf
  2877 00005FE4 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2878 00005FE6 C3                  <1> 	retn
  2879                              <1> 
  2880                              <1> loc_permission_denied:
  2881                              <1> 	; 27/02/2016
  2882 00005FE7 BE[C4C20000]        <1> 	mov	esi, Msg_Permission_Denied
  2883 00005FEC E82EDFFFFF          <1> 	call	print_msg
  2884 00005FF1 EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2885                              <1> 
  2886                              <1> loc_file_rw_check_write_fault:
  2887 00005FF3 3C1D                <1> 	cmp	al, 1Dh ; Write Fault
  2888 00005FF5 0F85F2F6FFFF        <1>         jne     loc_run_cmd_failed_cmp_al
  2889 00005FFB BE[AFC00000]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2890                              <1> 	;call	print_msg
  2891                              <1> 	;retn
  2892 00006000 E91ADFFFFF          <1> 	jmp	print_msg
  2893                              <1> 
  2894                              <1> make_directory:
  2895                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2896                              <1> 	; 12/03/2011 (CMD_INTR.ASM, 'cmp_cmd_mkdir')
  2897                              <1> 	; 14/08/2010
  2898                              <1> 	; 10/07/2010
  2899                              <1> 	; 29/11/2009
  2900                              <1> 	;
  2901                              <1> get_mkdir_fchar:
  2902                              <1> 	; esi = directory name
  2903 00006005 803E20              <1> 	cmp	byte [esi], 20h
  2904 00006008 7701                <1>         ja	short loc_mkdir_parse_path_name
  2905                              <1> 
  2906                              <1> loc_mkdir_nodirname_retn:
  2907 0000600A C3                  <1> 	retn
  2908                              <1> 
  2909                              <1> loc_mkdir_parse_path_name:
  2910 0000600B BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  2911 00006010 E8A41D0000          <1>         call    parse_path_name
  2912 00006015 0F82A2F6FFFF        <1> 	jc	loc_cmd_failed
  2913                              <1> 
  2914                              <1> loc_mkdir_check_dirname_exists:
  2915 0000601B BE[88D90000]        <1> 	mov	esi, FindFile_Name
  2916 00006020 803E20              <1> 	cmp	byte [esi], 20h
  2917 00006023 0F8694F6FFFF        <1> 	jna	loc_cmd_failed
  2918 00006029 8935[04DA0000]      <1> 	mov	[DelFile_FNPointer], esi
  2919 0000602F E839FFFFFF          <1> 	call	check_filename
  2920 00006034 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  2921                              <1> 
  2922                              <1> loc_mkdir_drv:
  2923 00006036 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  2924 0000603C 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  2925                              <1> 	
  2926 00006042 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  2927 00006048 38F2                <1> 	cmp	dl, dh
  2928 0000604A 7407                <1> 	je	short loc_mkdir_change_directory
  2929                              <1> 
  2930 0000604C E8D2E7FFFF          <1> 	call	change_current_drive
  2931 00006051 728A                <1> 	jc	loc_file_rw_cmd_failed
  2932                              <1> 
  2933                              <1> loc_mkdir_change_directory:
  2934 00006053 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2935 0000605A 7614                <1> 	jna	short loc_mkdir_find_directory
  2936                              <1> 
  2937 0000605C FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2938 00006062 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  2939 00006067 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2940 00006069 E837170000          <1> 	call	change_current_directory
  2941 0000606E 722E                <1> 	jc	short loc_mkdir_check_error_code
  2942                              <1> 
  2943                              <1> ;loc_mkdir_change_prompt_dir_string:
  2944                              <1> 	;call	change_prompt_dir_string
  2945                              <1> 
  2946                              <1> loc_mkdir_find_directory:
  2947                              <1> 	;mov	esi, FindFile_Name
  2948 00006070 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  2949                              <1> 	;xor	eax, eax
  2950 00006076 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  2951 00006079 E83BFBFFFF          <1> 	call	find_first_file
  2952 0000607E 721E                <1> 	jc	short loc_mkdir_check_error_code
  2953                              <1> 
  2954                              <1> loc_mkdir_directory_found:
  2955 00006080 BE[0FC20000]        <1> 	mov	esi, Msg_Name_Exists
  2956 00006085 E895DEFFFF          <1> 	call	print_msg
  2957                              <1> 
  2958 0000608A E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  2959                              <1> 
  2960                              <1> loc_mkdir_invalid_dir_name_chars:
  2961 0000608F BE[E2C10000]        <1> 	mov	esi, Msg_invalid_name_chars
  2962 00006094 E886DEFFFF          <1> 	call	print_msg
  2963                              <1> 
  2964 00006099 E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  2965                              <1> 
  2966                              <1> loc_mkdir_check_error_code:
  2967 0000609E 3C02                <1> 	cmp	al, 2
  2968                              <1> 	;je	short loc_mkdir_directory_not_found
  2969 000060A0 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  2970 000060A2 F9                  <1> 	stc
  2971 000060A3 E935FFFFFF          <1>         jmp     loc_file_rw_cmd_failed
  2972                              <1> 
  2973                              <1> loc_mkdir_directory_not_found:
  2974                              <1> loc_mkdir_ask_for_yes_no:
  2975 000060A8 BE[30C20000]        <1> 	mov	esi, Msg_DoYouWantMkdir
  2976 000060AD E86DDEFFFF          <1> 	call	print_msg
  2977 000060B2 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  2978 000060B8 E862DEFFFF          <1> 	call	print_msg
  2979 000060BD BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  2980 000060C2 E858DEFFFF          <1> 	call	print_msg
  2981                              <1> 
  2982 000060C7 C605[59C20000]20    <1> 	mov	byte [Y_N_nextline], 20h
  2983                              <1> 
  2984                              <1> loc_mkdir_ask_again:
  2985 000060CE 30E4                <1> 	xor	ah, ah
  2986 000060D0 E81AABFFFF          <1> 	call	int16h
  2987 000060D5 3C1B                <1> 	cmp	al, 1Bh
  2988                              <1> 	;je	short loc_do_not_make_directory
  2989 000060D7 7447                <1> 	je	short loc_mkdir_y_n_escape
  2990 000060D9 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  2991 000060DB 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  2992 000060DD 7404                <1> 	je	short loc_mkdir_yes_make_directory
  2993 000060DF 3C4E                <1> 	cmp	al, 'N' ; 'no'
  2994 000060E1 75EB                <1> 	jne	short loc_mkdir_ask_again
  2995                              <1> 
  2996                              <1> loc_do_not_make_directory:
  2997                              <1> loc_mkdir_yes_make_directory:
  2998 000060E3 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  2999 000060E8 6650                <1> 	push	ax
  3000 000060EA BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  3001 000060EF E82BDEFFFF          <1> 	call	print_msg
  3002 000060F4 6658                <1> 	pop	ax
  3003                              <1> 	;cmp	al, 'Y' ; 'yes'
  3004                              <1> 	;cmc
  3005                              <1>         ;jnc	loc_file_rw_restore_retn
  3006 000060F6 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3007 000060F8 0F84DFFEFFFF        <1>         je	loc_file_rw_restore_retn  
  3008                              <1> 
  3009                              <1> loc_mkdir_call_make_sub_directory:
  3010 000060FE 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3011 00006104 B110                <1> 	mov	cl, 10h ; Directory attributes 
  3012 00006106 E8AD1D0000          <1> 	call	make_sub_directory
  3013                              <1> loc_rename_file_ok: ; 06/03/2016
  3014 0000610B 0F82CCFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  3015                              <1> move_source_file_to_destination_OK:
  3016 00006111 BE[5DC20000]        <1> 	mov	esi, Msg_OK
  3017 00006116 E804DEFFFF          <1> 	call	print_msg
  3018 0000611B E9BDFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3019                              <1> 
  3020                              <1> loc_mkdir_y_n_escape:
  3021 00006120 B04E                <1> 	mov	al, 'N' ; 'no'
  3022 00006122 EBBF                <1> 	jmp	short loc_do_not_make_directory
  3023                              <1> 
  3024                              <1> delete_directory:
  3025                              <1> 	; 06/03/2016
  3026                              <1> 	; 01/03/2016
  3027                              <1> 	; 29/02/2016
  3028                              <1> 	; 28/02/2016
  3029                              <1> 	; 27/02/2016
  3030                              <1> 	; 26/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3031                              <1> 	; 16/10/2010 (CMD_INTR.ASM, 'cmp_cmd_rmdir')
  3032                              <1> 	; 05/06/2010
  3033                              <1> 	;
  3034                              <1> get_rmdir_fchar:
  3035                              <1> 	; esi = directory name
  3036 00006124 803E20              <1> 	cmp	byte [esi], 20h
  3037 00006127 7701                <1>         ja	short loc_rmdir_parse_path_name
  3038                              <1> 
  3039                              <1> loc_rmdir_nodirname_retn:
  3040 00006129 C3                  <1> 	retn
  3041                              <1> 
  3042                              <1> loc_rmdir_parse_path_name:
  3043 0000612A BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  3044 0000612F E8851C0000          <1> 	call	parse_path_name
  3045 00006134 0F8283F5FFFF        <1> 	jc	loc_cmd_failed
  3046                              <1> 
  3047                              <1> loc_rmdir_check_dirname_exists:
  3048 0000613A BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3049 0000613F 803E20              <1> 	cmp	byte [esi], 20h
  3050 00006142 0F8675F5FFFF        <1> 	jna	loc_cmd_failed
  3051 00006148 8935[04DA0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3052                              <1> 
  3053                              <1> loc_rmdir_drv:
  3054 0000614E 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  3055 00006154 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  3056                              <1> 
  3057 0000615A 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  3058 00006160 38F2                <1> 	cmp	dl, dh
  3059 00006162 740B                <1> 	je	short loc_rmdir_change_directory
  3060                              <1> 
  3061 00006164 E8BAE6FFFF          <1> 	call	change_current_drive
  3062 00006169 0F826EFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3063                              <1> 
  3064                              <1> loc_rmdir_change_directory:
  3065 0000616F 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3066 00006176 7614                <1> 	jna	short loc_rmdir_find_directory
  3067                              <1> 
  3068 00006178 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3069 0000617E BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  3070 00006183 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3071 00006185 E81B160000          <1> 	call	change_current_directory
  3072 0000618A 7211                <1> 	jc	short loc_rmdir_check_error_code
  3073                              <1> 
  3074                              <1> ;loc_rmdir_change_prompt_dir_string:
  3075                              <1> 	;call	change_prompt_dir_string
  3076                              <1> 
  3077                              <1> loc_rmdir_find_directory:
  3078                              <1> 	;mov	esi, FindFile_Name
  3079 0000618C 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3080 00006192 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3081 00006196 E81EFAFFFF          <1> 	call	find_first_file
  3082 0000619B 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3083                              <1> 
  3084                              <1> loc_rmdir_check_error_code:
  3085 0000619D 3C02                <1> 	cmp	al, 2
  3086 0000619F 740B                <1> 	je	short loc_rmdir_directory_not_found
  3087 000061A1 F9                  <1> 	stc
  3088 000061A2 E936FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3089                              <1> 
  3090                              <1> loc_rmdir_ambgfn_check:
  3091 000061A7 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3092 000061AA 740F                <1> 	jz	short loc_rmdir_directory_found
  3093                              <1> 
  3094                              <1> loc_rmdir_directory_not_found:
  3095 000061AC BE[D1C00000]        <1> 	mov	esi, Msg_Dir_Not_Found
  3096 000061B1 E869DDFFFF          <1> 	call	print_msg
  3097                              <1> 
  3098 000061B6 E922FEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3099                              <1> 
  3100                              <1> loc_rmdir_directory_found:
  3101 000061BB 80E307              <1> 	and	bl, 07h ; Attributes
  3102 000061BE 0F8523FEFFFF        <1> 	jnz	loc_permission_denied
  3103                              <1> 
  3104                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3105                              <1>        ;mov	bh, [LongName_EntryLength]
  3106 000061C4 883D[0EDA0000]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3107                              <1> 	; edi = Directory Entry Offset (DirBuff)
  3108                              <1> 	; esi = Directory Entry (FFF Structure)
  3109                              <1> 	;mov	[DelFile_DirEntryAddr], edi ; not required
  3110                              <1> 	;mov	ax, [edi+20] ; First Cluster High Word
  3111                              <1>         ;shl	eax, 16
  3112                              <1> 	;mov	ax, [edi+26] ; First Cluster Low Word
  3113                              <1> 	; ROOT Dir First Cluster = 0
  3114                              <1>         ;cmp	eax, 2
  3115                              <1> 	;jb	loc_update_direntry_1
  3116                              <1> 
  3117                              <1> pass_rmdir_fc_check:
  3118 000061CA 57                  <1> 	push	edi ; * (29/02/2016)
  3119                              <1> 
  3120 000061CB BE[63C20000]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3121 000061D0 E84ADDFFFF          <1> 	call	print_msg
  3122 000061D5 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3123 000061DB E83FDDFFFF          <1> 	call	print_msg
  3124 000061E0 BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  3125 000061E5 E835DDFFFF          <1> 	call	print_msg
  3126                              <1> 
  3127                              <1> loc_rmdir_ask_again:
  3128 000061EA 30E4                <1> 	xor	ah, ah
  3129 000061EC E8FEA9FFFF          <1> 	call	int16h
  3130 000061F1 3C1B                <1> 	cmp	al, 1Bh
  3131                              <1> 	;je	short loc_do_not_delete_directory
  3132 000061F3 0F8498000000        <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3133 000061F9 24DF                <1> 	and	al, 0DFh
  3134 000061FB A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  3135 00006200 3C59                <1> 	cmp	al, 'Y'
  3136 00006202 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3137 00006204 3C4E                <1> 	cmp	al, 'N'
  3138 00006206 75E2                <1> 	jne	short loc_rmdir_ask_again
  3139                              <1> 
  3140                              <1> loc_do_not_delete_directory:
  3141                              <1> loc_rmdir_yes_delete_directory:
  3142 00006208 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  3143 0000620D 6650                <1> 	push	ax
  3144 0000620F BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  3145 00006214 E806DDFFFF          <1> 	call	print_msg
  3146 00006219 6658                <1> 	pop	ax
  3147 0000621B 5F                  <1> 	pop	edi ; * (29/02/2016)
  3148                              <1> 	;cmp	al, 'Y' ; 'yes'
  3149                              <1> 	;cmc
  3150                              <1>         ;jnc	loc_file_rw_restore_retn
  3151 0000621C 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3152 0000621E 0F84B9FDFFFF        <1>         je	loc_file_rw_restore_retn  
  3153                              <1> 
  3154                              <1> loc_rmdir_delete_short_name_check_dir_empty:
  3155                              <1> 	; EDI = Directory buffer entry offset/address 
  3156 00006224 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3157 00006228 C1E010              <1>         shl	eax, 16
  3158 0000622B 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3159                              <1> 
  3160 0000622F A3[08DA0000]        <1> 	mov 	[DelFile_FCluster], eax
  3161                              <1> 
  3162                              <1> 	;mov	bx, [DirBuff_EntryCounter]
  3163 00006234 668B1D[C0D90000]    <1> 	mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3164 0000623B 66891D[0CDA0000]    <1> 	mov	[DelFile_EntryCounter], bx
  3165                              <1> 
  3166 00006242 29DB                <1>     	sub	ebx, ebx
  3167 00006244 8A3D[46D90000]      <1> 	mov	bh, [FindFile_Drv]
  3168 0000624A BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3169 0000624F 01DE                <1> 	add	esi, ebx
  3170                              <1> 
  3171 00006251 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3172 00006257 743F                <1> 	je	short loc_rmdir_delete_fs_directory
  3173                              <1> 
  3174                              <1> 	;cmp	byte [esi+LD_FATType], 1
  3175                              <1> 	;jnb	short loc_rmdir_get__last_cluster_0
  3176                              <1> 	;mov	eax, 0Bh ; Invalid Format
  3177                              <1> 	;jmp	loc_file_rw_cmd_failed
  3178                              <1>   
  3179                              <1> ;loc_rmdir_get_last_cluster_0:
  3180 00006259 8B15[D1D70000]      <1> 	mov	edx, [DirBuff_Cluster]
  3181 0000625F 8915[38DA0000]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3182                              <1> 
  3183 00006265 893D[34DA0000]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3184                              <1> 
  3185                              <1> 	; 01/03/2016
  3186 0000626B C705[C1D70000]0000- <1> 	mov	dword [FAT_ClusterCounter], 0 ; Reset
  3186 00006273 0000                <1>
  3187                              <1> 
  3188                              <1> loc_rmdir_get_last_cluster:
  3189 00006275 E8313A0000          <1> 	call	get_last_cluster
  3190 0000627A 0F82B8000000        <1>         jc      loc_rmdir_cmd_failed
  3191                              <1> 	
  3192 00006280 3B05[08DA0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3193 00006286 752F                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3194                              <1> 
  3195 00006288 C605[33DA0000]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3196 0000628F EB2D                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3197                              <1> 
  3198                              <1> loc_rmdir_y_n_escape:
  3199 00006291 B04E                <1> 	mov	al, 'N' ; 'no'
  3200 00006293 E970FFFFFF          <1>         jmp     loc_do_not_delete_directory
  3201                              <1> 
  3202                              <1> loc_rmdir_delete_fs_directory:
  3203 00006298 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3204 0000629C 0F8545FDFFFF        <1> 	jne	loc_permission_denied
  3205                              <1> 
  3206 000062A2 E81B140000          <1> 	call	delete_fs_directory
  3207 000062A7 0F8326FDFFFF        <1> 	jnc	loc_print_deleted_message
  3208                              <1> 
  3209 000062AD 09C0                <1> 	or	eax, eax
  3210 000062AF 745D                <1> 	jz	loc_rmdir_directory_not_empty_2         
  3211 000062B1 F9                  <1> 	stc
  3212 000062B2 E926FDFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3213                              <1>  
  3214                              <1> loc_rmdir_multi_dir_clusters:
  3215 000062B7 C605[33DA0000]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3216                              <1> 
  3217                              <1> pass_rmdir_multi_dir_clusters:
  3218 000062BE A3[3CDA0000]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3219 000062C3 890D[40DA0000]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3220                              <1> 
  3221                              <1> loc_rmdir_load_fat_sub_directory:
  3222 000062C9 E8C8330000          <1> 	call	load_FAT_sub_directory
  3223 000062CE 7268                <1> 	jc	loc_rmdir_cmd_failed
  3224                              <1> 
  3225                              <1> loc_rmdir_find_last_dir_entry:
  3226 000062D0 56                  <1> 	push	esi
  3227 000062D1 BE[2AD90000]        <1> 	mov	esi, Dir_File_Name
  3228 000062D6 C6062A              <1> 	mov	byte [esi], '*'
  3229 000062D9 C646082A            <1> 	mov	byte [esi+8], '*'
  3230 000062DD 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3231                              <1> loc_rmdir_find_last_dir_entry_next:
  3232 000062DF 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3233 000062E3 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3234 000062E6 E810180000          <1> 	call	find_directory_entry
  3235 000062EB 7271                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3236 000062ED 83FB01              <1> 	cmp	ebx, 1
  3237 000062F0 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3238                              <1> loc_rmdir_dot_entry_check:
  3239 000062F2 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3240 000062F5 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3241 000062F7 08DB                <1> 	or	bl, bl
  3242 000062F9 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3243 000062FB 807F0120            <1> 	cmp	byte [edi+1], 20h
  3244 000062FF EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3245                              <1> 
  3246                              <1> loc_rmdir_dotdot_entry_check:
  3247 00006301 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3248                              <1> pass_rmdir_dot_entry_check:	
  3249 00006307 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3250 00006309 FEC3                <1> 	inc	bl
  3251 0000630B EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3252                              <1> 
  3253                              <1> 
  3254                              <1> loc_rmdir_directory_not_empty_1:
  3255 0000630D 58                  <1> 	pop	eax ; pushed esi 
  3256                              <1> 
  3257                              <1> loc_rmdir_directory_not_empty_2:
  3258 0000630E BE[84C20000]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3259 00006313 E807DCFFFF          <1> 	call	print_msg
  3260                              <1> 	; 01/03/2016
  3261 00006318 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3262 0000631D 09C0                <1> 	or	eax, eax ; 0 ?
  3263 0000631F 0F84B8FCFFFF        <1> 	jz	loc_file_rw_restore_retn
  3264                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3265                              <1> 
  3266 00006325 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3267                              <1> 	           ; BL = 1 -> add free clusters
  3268 00006329 E8FE370000          <1> 	call	calculate_fat_freespace
  3269 0000632E 09C9                <1> 	or	ecx, ecx
  3270 00006330 0F84A7FCFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3271                              <1> 	; ecx > 0 -> Error (Recalculation is neeeded)
  3272 00006336 EB0E                <1> 	jmp	short loc_rmdir_cmd_return
  3273                              <1> 
  3274                              <1> 
  3275                              <1> loc_rmdir_cmd_failed:
  3276 00006338 833D[C1D70000]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3277 0000633F 0F8298FCFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3278 00006345 F9                  <1> 	stc
  3279                              <1> loc_rmdir_cmd_return:
  3280                              <1> 	; 01/03/2016
  3281 00006346 9C                  <1> 	pushf
  3282                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3283 00006347 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3284                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3285 0000634B 50                  <1> 	push	eax
  3286 0000634C E8DB370000          <1> 	call	calculate_fat_freespace	
  3287 00006351 58                  <1> 	pop	eax
  3288 00006352 9D                  <1> 	popf
  3289 00006353 0F8284FCFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3290 00006359 E97FFCFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3291                              <1> 
  3292                              <1> 
  3293                              <1> loc_rmdir_empty_dir_cluster:
  3294 0000635E 5E                  <1> 	pop	esi
  3295                              <1> 
  3296                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3297 0000635F 803D[33DA0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3298 00006366 761D                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3299                              <1> 
  3300 00006368 A1[40DA0000]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3301                              <1> 	;xor	ecx, ecx
  3302 0000636D 49                  <1> 	dec	ecx ; FFFFFFFFh
  3303 0000636E E867340000          <1> 	call	update_cluster
  3304 00006373 7310                <1> 	jnc	short loc_rmdir_unlink_dir_last_cluster
  3305                              <1> 
  3306                              <1> loc_rmdir_unlink_stc_retn:
  3307                              <1> 	; 01/03/2016
  3308 00006375 83F801              <1> 	cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3309 00006378 F5                  <1> 	cmc 
  3310 00006379 72BD                <1> 	jc	short loc_rmdir_cmd_failed
  3311 0000637B EB1D                <1> 	jmp	short loc_rmdir_save_fat_buffer 
  3312                              <1> 	
  3313                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3314 0000637D B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  3315 00006382 F9                  <1> 	stc
  3316 00006383 EBB3                <1> 	jmp	short loc_rmdir_cmd_failed
  3317                              <1>  
  3318                              <1> loc_rmdir_unlink_dir_last_cluster:
  3319 00006385 A1[3CDA0000]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3320 0000638A 31C9                <1> 	xor	ecx, ecx ; 0
  3321 0000638C E849340000          <1> 	call	update_cluster
  3322 00006391 73EA                <1> 	jnc	short loc_rmdir_unlink_stc_retn_0Bh
  3323                              <1> 	; Because of it is the last cluster
  3324                              <1> 	; 'update_cluster' must return with eocc error 
  3325 00006393 09C0                <1> 	or	eax, eax
  3326 00006395 7403                <1> 	jz	short loc_rmdir_save_fat_buffer ; eocc	
  3327 00006397 F9                  <1> 	stc
  3328 00006398 EB9E                <1>         jmp     short loc_rmdir_cmd_failed
  3329                              <1> 	 
  3330                              <1> loc_rmdir_save_fat_buffer:
  3331 0000639A 803D[B9D70000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3332 000063A1 7525                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3333 000063A3 E8EF360000          <1> 	call	save_fat_buffer
  3334 000063A8 728E                <1> 	jc	short loc_rmdir_cmd_failed
  3335                              <1> 
  3336                              <1> 	; 01/03/2016
  3337 000063AA 803D[33DA0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3338 000063B1 7615                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3339                              <1> 
  3340 000063B3 A1[08DA0000]        <1> 	mov	eax, [DelFile_FCluster]
  3341 000063B8 E9B8FEFFFF          <1>         jmp     loc_rmdir_get_last_cluster
  3342                              <1> 
  3343                              <1> loc_rmdir_delete_short_name_invalid_data:
  3344 000063BD B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  3345 000063C2 F9                  <1> 	stc
  3346 000063C3 E970FFFFFF          <1>         jmp     loc_rmdir_cmd_failed
  3347                              <1> 
  3348                              <1> loc_rmdir_calculate_FAT_freespace:
  3349 000063C8 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3350 000063CD 66BB01FF            <1> 	mov	bx, 0FF01h
  3351                              <1> 	; BL = 1 -> Add EAX to free space count
  3352                              <1> 	; BH = FFh ->
  3353                              <1> 	; ESI = Logical DOS Drive Description Table address
  3354 000063D1 E856370000          <1> 	call	calculate_fat_freespace
  3355                              <1> 
  3356 000063D6 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3357 000063D8 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3358                              <1> 
  3359                              <1> loc_rmdir_recalculate_FAT_freespace:
  3360 000063DA 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3361 000063DE E849370000          <1> 	call	calculate_fat_freespace
  3362                              <1> 	          
  3363                              <1> loc_rmdir_delete_short_name_continue:
  3364 000063E3 A1[38DA0000]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3365 000063E8 83F802              <1> 	cmp	eax, 2
  3366 000063EB 730D                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3367 000063ED E819320000          <1> 	call	load_FAT_root_directory
  3368 000063F2 0F82E5FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3369 000063F8 EB0B                <1> 	jmp	short loc_rmdir_del_short_name_ld_chk_fclust
  3370                              <1> 
  3371                              <1> loc_rmdir_del_short_name_load_sub_dir:	
  3372 000063FA E897320000          <1> 	call	load_FAT_sub_directory
  3373 000063FF 0F82D8FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3374                              <1> 
  3375                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3376 00006405 0FB73D[34DA0000]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3377 0000640C 81C700000800        <1> 	add	edi, Directory_Buffer
  3378                              <1> 
  3379 00006412 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3380 00006416 C1E010              <1> 	shl	eax, 16
  3381 00006419 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3382                              <1>         ; Not necessary... 
  3383 0000641D 3B05[08DA0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3384 00006423 7598                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3385                              <1> 	;
  3386 00006425 C607E5              <1> 	mov	byte [edi], 0E5h ; 'Deleted' sign
  3387                              <1> 	; 27/02/2016
  3388                              <1> 	; TRDOS v1 has a bug here! it does not set
  3389                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3390                              <1> 	; 'save_directory_buffer' would not save the change ! 
  3391 00006428 C605[CCD70000]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3392                              <1> 	;
  3393 0000642F E8E91D0000          <1> 	call	save_directory_buffer
  3394 00006434 0F82A3FBFFFF        <1> 	jc	loc_file_rw_cmd_failed 
  3395                              <1> 
  3396                              <1> loc_rmdir_del_long_name:
  3397 0000643A 0FB615[0EDA0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3398 00006441 08D2                <1> 	or	dl, dl
  3399 00006443 7414                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3400                              <1>              
  3401 00006445 0FB705[0CDA0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3402 0000644C 29D0                <1> 	sub	eax, edx
  3403 0000644E 0F8289FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3404                              <1>  
  3405                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3406 00006454 E8241F0000          <1> 	call	delete_longname
  3407                              <1> 	;jc	short loc_file_rw_cmd_failed
  3408                              <1> 
  3409                              <1> loc_rmdir_update_parent_dir_lmdt:
  3410 00006459 E85A1E0000          <1> 	call	update_parent_dir_lmdt
  3411                              <1> 	;jc	short loc_file_rw_cmd_failed
  3412                              <1> 
  3413                              <1> loc_rmdir_ok:
  3414 0000645E BE[5DC20000]        <1> 	mov	esi, Msg_OK
  3415 00006463 E8B7DAFFFF          <1> 	call	print_msg
  3416 00006468 E970FBFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3417                              <1> 
  3418                              <1> 
  3419                              <1> delete_file:
  3420                              <1> 	; 29/02/2016
  3421                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3422                              <1> 	; 09/08/2010 (CMD_INTR.ASM, 'cmp_cmd_del')
  3423                              <1> 	; 28/02/2010
  3424                              <1> 
  3425                              <1> get_delfile_fchar:
  3426                              <1> 	; esi = file name
  3427 0000646D 803E20              <1> 	cmp	byte [esi], 20h
  3428 00006470 7701                <1>         ja	short loc_delfile_parse_path_name
  3429                              <1> 
  3430                              <1> loc_delfile_nofilename_retn:
  3431 00006472 C3                  <1> 	retn
  3432                              <1> 
  3433                              <1> loc_delfile_parse_path_name:
  3434 00006473 BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  3435 00006478 E83C190000          <1> 	call	parse_path_name
  3436 0000647D 0F823AF2FFFF        <1> 	jc	loc_cmd_failed
  3437                              <1> 
  3438                              <1> loc_delfile_check_filename_exists:
  3439 00006483 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3440 00006488 803E20              <1> 	cmp	byte [esi], 20h
  3441 0000648B 0F862CF2FFFF        <1> 	jna	loc_cmd_failed
  3442 00006491 8935[04DA0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3443                              <1> 
  3444                              <1> loc_delfile_drv:
  3445 00006497 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  3446 0000649D 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  3447 000064A3 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  3448 000064A9 38F2                <1> 	cmp	dl, dh
  3449 000064AB 740B                <1> 	je	short loc_delfile_change_directory
  3450                              <1> 
  3451 000064AD E871E3FFFF          <1> 	call	change_current_drive
  3452 000064B2 0F8225FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3453                              <1> 
  3454                              <1> loc_delfile_change_directory:
  3455 000064B8 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3456 000064BF 7618                <1> 	jna	short loc_delfile_find
  3457                              <1> 
  3458 000064C1 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3459 000064C7 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  3460 000064CC 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3461 000064CE E8D2120000          <1> 	call	change_current_directory
  3462 000064D3 0F8204FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3463                              <1> 
  3464                              <1> ;loc_delfile_change_prompt_dir_string:
  3465                              <1> 	;call	change_prompt_dir_string
  3466                              <1> 
  3467                              <1> loc_delfile_find:
  3468                              <1> 	;mov	esi, FindFile_Name
  3469 000064D9 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3470 000064DF 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3471 000064E3 E8D1F6FFFF          <1> 	call	find_first_file
  3472 000064E8 0F82EFFAFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3473                              <1> 
  3474                              <1> loc_delfile_ambgfn_check:
  3475 000064EE 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3476 000064F1 740B                <1> 	jz	short loc_delfile_found
  3477                              <1> 
  3478                              <1> loc_file_not_found:
  3479 000064F3 B802000000          <1> 	mov	eax, 2 ; File not found sign
  3480 000064F8 F9                  <1> 	stc
  3481 000064F9 E9DFFAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3482                              <1> 
  3483                              <1> loc_delfile_found:
  3484 000064FE 80E307              <1> 	and	bl, 07h ; Attributes
  3485 00006501 0F85E0FAFFFF        <1>         jnz     loc_permission_denied
  3486                              <1> 
  3487                              <1> ;loc_delfile_found_save_lnel:
  3488                              <1> ;	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3489                              <1> 
  3490                              <1> loc_delfile_ask_for_delete:
  3491 00006507 57                  <1> 	push	edi ; * (29/02/2016)
  3492                              <1> 
  3493 00006508 BE[9BC20000]        <1> 	mov	esi, Msg_DoYouWantDelete
  3494 0000650D E80DDAFFFF          <1> 	call	print_msg
  3495 00006512 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3496 00006518 E802DAFFFF          <1> 	call	print_msg
  3497 0000651D BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  3498 00006522 E8F8D9FFFF          <1> 	call	print_msg
  3499                              <1> 
  3500                              <1> loc_delfile_ask_again:
  3501 00006527 30E4                <1> 	xor	ah, ah
  3502 00006529 E8C1A6FFFF          <1> 	call	int16h
  3503 0000652E 3C1B                <1> 	cmp	al, 1Bh
  3504                              <1> 	;je	short loc_do_not_delete_file
  3505 00006530 7457                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3506 00006532 24DF                <1> 	and	al, 0DFh
  3507 00006534 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  3508 00006539 3C59                <1> 	cmp	al, 'Y'
  3509 0000653B 7404                <1> 	je	short loc_yes_delete_file
  3510 0000653D 3C4E                <1> 	cmp	al, 'N'
  3511 0000653F 75E6                <1> 	jne	short loc_delfile_ask_again
  3512                              <1> 
  3513                              <1> loc_do_not_delete_file:
  3514                              <1> loc_yes_delete_file:
  3515 00006541 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  3516 00006546 6650                <1> 	push	ax
  3517 00006548 BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  3518 0000654D E8CDD9FFFF          <1> 	call	print_msg
  3519 00006552 6658                <1> 	pop	ax
  3520 00006554 5F                  <1> 	pop	edi ; * (29/02/2016)
  3521                              <1> 	;cmp	al, 'Y' ; 'yes'
  3522                              <1> 	;cmc
  3523                              <1>         ;jnc	loc_file_rw_restore_retn
  3524 00006555 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3525 00006557 0F8480FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3526                              <1> 
  3527                              <1> loc_delete_file:
  3528 0000655D 8A3D[46D90000]      <1> 	mov	bh, [FindFile_Drv]
  3529                              <1> 	;mov	bl, [DelFile_LNEL]
  3530 00006563 8A1D[95D90000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3531                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3532 00006569 668B0D[C0D90000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3533                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3534 00006570 E8F21F0000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3535 00006575 0F8358FAFFFF        <1> 	jnc	loc_print_deleted_message
  3536                              <1> 
  3537 0000657B 3C05                <1> 	cmp	al, 05h
  3538 0000657D 0F8464FAFFFF        <1> 	je	loc_permission_denied
  3539 00006583 F9                  <1> 	stc
  3540 00006584 E954FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3541                              <1> 
  3542                              <1> loc_delfile_y_n_escape:
  3543 00006589 B04E                <1> 	mov	al, 'N' ; 'no'
  3544 0000658B EBB4                <1> 	jmp	short loc_do_not_delete_file
  3545                              <1> 
  3546                              <1> set_file_attributes:
  3547                              <1> 	; 06/03/2016
  3548                              <1> 	; 04/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3549                              <1> 	; 10/07/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_attrib')
  3550                              <1> 	; 23/05/2010 
  3551                              <1> 	; 17/12/2000 (P2000.ASM)
  3552                              <1> 
  3553                              <1> 	; esi = file or directory name
  3554 0000658D 6631C0              <1> 	xor	ax, ax
  3555 00006590 66A3[ECC20000]      <1> 	mov	[Attr_Chars], ax
  3556 00006596 A2[5CDA0000]        <1> 	mov	[Attributes], al
  3557                              <1> 
  3558                              <1> get_attrib_fchar:
  3559                              <1> 	; esi = file name
  3560 0000659B 8A06                <1> 	mov	al, [esi]
  3561 0000659D 3C20                <1> 	cmp	al, 20h
  3562 0000659F 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3563                              <1> 
  3564                              <1> loc_scan_attrib_params:
  3565 000065A1 3C2D                <1> 	cmp	al, '-'
  3566 000065A3 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3567 000065A9 7408                <1> 	je	short loc_attr_space
  3568                              <1> 
  3569 000065AB 3C2B                <1> 	cmp	al, '+'
  3570 000065AD 0F850AF1FFFF        <1> 	jne	loc_cmd_failed
  3571                              <1> 
  3572                              <1> loc_attr_space:
  3573 000065B3 8A6601              <1> 	mov	ah, [esi+1]
  3574 000065B6 80FC20              <1>  	cmp	ah, 20h
  3575 000065B9 770A                <1> 	ja	short pass_attr_space
  3576 000065BB 0F82FCF0FFFF        <1> 	jb	loc_cmd_failed
  3577 000065C1 46                  <1> 	inc	esi
  3578 000065C2 EBEF                <1> 	jmp	short loc_attr_space
  3579                              <1> 
  3580                              <1> loc_attr_file_nofilename_retn:
  3581 000065C4 C3                  <1> 	retn
  3582                              <1> 
  3583                              <1> pass_attr_space:
  3584 000065C5 80E4DF              <1> 	and	ah, 0DFh
  3585 000065C8 80FC53              <1> 	cmp	ah, 'S'
  3586 000065CB 0F87ECF0FFFF        <1> 	ja	loc_cmd_failed
  3587 000065D1 7204                <1> 	jb	short pass_attr_system
  3588 000065D3 B404                <1> 	mov	ah, 04h   ; System
  3589 000065D5 EB21                <1> 	jmp	short pass_attr_archive
  3590                              <1> 
  3591                              <1> pass_attr_system:
  3592 000065D7 80FC48              <1> 	cmp	ah, 'H'
  3593 000065DA 7706                <1> 	ja	short pass_attr_hidden
  3594 000065DC 7213                <1> 	jb	short pass_attr_read_only
  3595 000065DE B402                <1> 	mov	ah, 02h    ; Hidden
  3596 000065E0 EB16                <1> 	jmp	short pass_attr_archive
  3597                              <1> 
  3598                              <1> pass_attr_hidden:
  3599 000065E2 80FC52              <1> 	cmp	ah, 'R'
  3600 000065E5 0F87D2F0FFFF        <1> 	ja	loc_cmd_failed
  3601 000065EB 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3602 000065ED B401                <1> 	mov	ah, 01h
  3603 000065EF EB07                <1> 	jmp	short pass_attr_archive
  3604                              <1> 
  3605                              <1> pass_attr_read_only:
  3606 000065F1 80FC41              <1> 	cmp	ah, 'A'
  3607 000065F4 753B                <1> 	jne	short loc_chk_attr_enter
  3608 000065F6 B420                <1> 	mov	ah, 20h    ; Archive
  3609                              <1> 
  3610                              <1> pass_attr_archive:
  3611 000065F8 3C2D                <1> 	cmp	al, '-'
  3612 000065FA 7508                <1> 	jne	short pass_reducing_attributes
  3613 000065FC 0825[ECC20000]      <1> 	or	[Attr_Chars], ah
  3614 00006602 EB06                <1> 	jmp	short loc_change_attributes_inc
  3615                              <1> 
  3616                              <1> pass_reducing_attributes:
  3617 00006604 0825[EDC20000]      <1> 	or	[Attr_Chars+1], ah
  3618                              <1> 
  3619                              <1> loc_change_attributes_inc:
  3620 0000660A 46                  <1> 	inc	esi
  3621 0000660B 8A6601              <1> 	mov	ah, [esi+1]
  3622 0000660E 80FC20              <1> 	cmp	ah, 20h
  3623 00006611 7227                <1> 	jb	short pass_change_attr
  3624 00006613 74F5                <1> 	je	short loc_change_attributes_inc
  3625 00006615 80FC2D              <1> 	cmp	ah, '-'
  3626 00006618 770D                <1> 	ja	short loc_chk_next_attr_char1
  3627 0000661A 7405                <1> 	je	short loc_chk_next_attr_char0
  3628 0000661C 80FC2B              <1> 	cmp	ah, '+'
  3629 0000661F 7506                <1> 	jne	short loc_chk_next_attr_char1
  3630                              <1> 
  3631                              <1> loc_chk_next_attr_char0:
  3632 00006621 46                  <1> 	inc	esi
  3633 00006622 668B06              <1> 	mov	ax, [esi]
  3634 00006625 EB9E                <1> 	jmp	short pass_attr_space
  3635                              <1> 
  3636                              <1> loc_chk_next_attr_char1:
  3637 00006627 803E2D              <1> 	cmp	byte [esi], '-'
  3638 0000662A 7799                <1> 	ja	short pass_attr_space
  3639 0000662C E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3640                              <1> 
  3641                              <1> loc_chk_attr_enter:
  3642 00006631 80FC0D              <1> 	cmp	ah, 0Dh
  3643 00006634 0F8583F0FFFF        <1> 	jne	loc_cmd_failed
  3644                              <1> 
  3645                              <1> pass_change_attr:
  3646 0000663A A0[ECC20000]        <1> 	mov	al, [Attr_Chars]
  3647 0000663F F6D0                <1> 	not	al
  3648 00006641 2005[5CDA0000]      <1> 	and	[Attributes], al
  3649 00006647 A0[EDC20000]        <1> 	mov	al, [Attr_Chars+1]
  3650 0000664C 0805[5CDA0000]      <1> 	or	[Attributes], al
  3651                              <1> 
  3652                              <1> loc_show_attributes:
  3653 00006652 BE[76CB0000]        <1> 	mov	esi, nextline
  3654 00006657 E8C3D8FFFF          <1> 	call	print_msg
  3655                              <1> 
  3656                              <1> loc_show_attributes_no_nextline:
  3657 0000665C C705[ECC20000]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3657 00006664 524D                <1>
  3658 00006666 66C705[F0C20000]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3658 0000666E 4C                  <1>
  3659 0000666F BE[ECC20000]        <1> 	mov	esi, Attr_Chars
  3660 00006674 A0[5CDA0000]        <1> 	mov	al, [Attributes]
  3661 00006679 A804                <1> 	test	al, 04h
  3662 0000667B 7406                <1> 	jz	short pass_put_attr_s
  3663 0000667D 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3664 00006682 46                  <1> 	inc	esi
  3665                              <1> 
  3666                              <1> pass_put_attr_s:
  3667 00006683 A802                <1> 	test	al, 02h
  3668 00006685 7406                <1> 	jz	short pass_put_attr_h
  3669 00006687 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3670 0000668C 46                  <1> 	inc	esi
  3671                              <1> 
  3672                              <1> pass_put_attr_h:
  3673 0000668D A801                <1> 	test	al, 01h
  3674 0000668F 7406                <1> 	jz	short pass_put_attr_r
  3675 00006691 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3676 00006696 46                  <1> 	inc	esi
  3677                              <1> 
  3678                              <1> pass_put_attr_r:
  3679 00006697 3C20                <1> 	cmp	al, 20h
  3680 00006699 7205                <1> 	jb	short pass_put_attr_a
  3681 0000669B 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3682                              <1> 
  3683                              <1> pass_put_attr_a:
  3684 000066A0 BE[DFC20000]        <1> 	mov	esi, Str_Attributes
  3685 000066A5 E875D8FFFF          <1> 	call	print_msg
  3686 000066AA BE[76CB0000]        <1> 	mov	esi, nextline
  3687 000066AF E86BD8FFFF          <1> 	call	print_msg
  3688 000066B4 E924F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3689                              <1> 
  3690                              <1> loc_attr_file_check_fname_fchar:
  3691 000066B9 46                  <1> 	inc	esi
  3692 000066BA 803E20              <1> 	cmp	byte [esi], 20h
  3693 000066BD 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3694 000066BF 0F8275FFFFFF        <1>         jb      pass_change_attr
  3695                              <1> 		   
  3696                              <1> loc_attr_file_parse_path_name:
  3697 000066C5 BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  3698 000066CA E8EA160000          <1> 	call	parse_path_name
  3699 000066CF 0F82E8EFFFFF        <1> 	jc	loc_cmd_failed
  3700                              <1> 
  3701                              <1> loc_attr_file_check_filename_exists:
  3702 000066D5 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3703 000066DA 803E20              <1> 	cmp	byte [esi], 20h
  3704 000066DD 0F86DAEFFFFF        <1> 	jna	loc_cmd_failed
  3705 000066E3 8935[04DA0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3706                              <1> 
  3707                              <1> loc_attr_file_drv:
  3708 000066E9 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  3709 000066EF 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  3710                              <1> 
  3711 000066F5 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  3712 000066FB 38F2                <1> 	cmp	dl, dh
  3713 000066FD 740B                <1> 	je	short loc_attr_file_change_directory
  3714                              <1> 
  3715 000066FF E81FE1FFFF          <1> 	call	change_current_drive
  3716 00006704 0F82D3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3717                              <1> 
  3718                              <1> loc_attr_file_change_directory:
  3719 0000670A 803D[47D90000]20    <1>         cmp     byte [FindFile_Directory], 20h
  3720 00006711 7618                <1> 	jna	short loc_attr_file_find
  3721                              <1> 
  3722 00006713 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3723                              <1> 	
  3724 00006719 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  3725 0000671E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3726 00006720 E880100000          <1> 	call	change_current_directory
  3727 00006725 0F82B2F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3728                              <1> 
  3729                              <1> ;loc_attr_file_change_prompt_dir_string:
  3730                              <1> 	;call	change_prompt_dir_string
  3731                              <1> 
  3732                              <1> loc_attr_file_find:
  3733                              <1> 	;mov	esi, FindFile_Name
  3734 0000672B 8B35[04DA0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3735 00006731 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3736 00006735 E87FF4FFFF          <1> 	call	find_first_file
  3737 0000673A 0F829DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3738                              <1> 
  3739                              <1> loc_attr_file_ambgfn_check:
  3740 00006740 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3741                              <1> 	;	(Note: It was BX in TRDOS v1)
  3742                              <1> 	;jz	short loc_attr_file_found
  3743 00006743 0F85AAFDFFFF        <1>         jnz     loc_file_not_found ; 06/03/2016 
  3744                              <1> 
  3745                              <1> 	;mov	eax, 2 ; File not found sign
  3746                              <1> 	;stc
  3747                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3748                              <1> 
  3749                              <1> loc_attr_file_found:
  3750                              <1> 	; EDI = Directory buffer entry offset/address
  3751                              <1> 	; BL = File (or Directory) Attributes 
  3752                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3753                              <1> 	; mov	bl, [EDI+0Bh]
  3754                              <1> 	
  3755 00006749 66833D[ECC20000]00  <1> 	cmp	word [Attr_Chars], 0
  3756 00006751 770B                <1> 	ja	short loc_attr_file_change_attributes
  3757 00006753 881D[5CDA0000]      <1> 	mov	[Attributes], bl
  3758 00006759 E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3759                              <1> 
  3760                              <1> loc_attr_file_change_attributes:
  3761 0000675E A0[ECC20000]        <1> 	mov	al, [Attr_Chars]
  3762 00006763 F6D0                <1> 	not	al
  3763 00006765 20C3                <1> 	and	bl, al
  3764 00006767 A0[EDC20000]        <1> 	mov	al, [Attr_Chars+1]
  3765 0000676C 08C3                <1> 	or	bl, al
  3766                              <1> 
  3767 0000676E 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3768 00006774 741D                <1> 	je	short loc_attr_file_fs_check
  3769                              <1> 
  3770 00006776 881D[5CDA0000]      <1> 	mov	[Attributes], bl
  3771 0000677C 885F0B              <1> 	mov	[edi+0Bh], bl    ; Attributes (New!)
  3772                              <1> 
  3773                              <1> 	; 04/03/2016
  3774                              <1> 	; TRDOS v1 has a bug here! it does not set
  3775                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3776                              <1> 	; 'save_directory_buffer' would not save the new attributes ! 
  3777                              <1> 	
  3778 0000677F C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3779                              <1> 
  3780 00006786 E8921A0000          <1> 	call 	save_directory_buffer
  3781 0000678B 0F824CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3782                              <1> 
  3783 00006791 EB33                <1> 	jmp	short loc_print_attr_changed_message
  3784                              <1> 
  3785                              <1> loc_attr_file_fs_check:
  3786 00006793 29C0                <1> 	sub	eax, eax
  3787 00006795 8A25[CAD70000]      <1>         mov     ah, [DirBuff_DRV]
  3788 0000679B BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3789 000067A0 01C6                <1>         add     esi, eax
  3790 000067A2 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3791 000067A6 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3792 000067A8 66B80D00            <1> 	mov	ax, 0Dh ; Invalid Data
  3793 000067AC E92CF8FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3794                              <1> 
  3795                              <1> loc_attr_file_change_fs_file_attributes:
  3796                              <1> 	; BL = New MS-DOS File Attributes
  3797 000067B1 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3798 000067B3 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3799 000067B5 E89C050000          <1> 	call	change_fs_file_attributes
  3800 000067BA 0F821DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3801                              <1> 
  3802 000067C0 881D[5CDA0000]      <1> 	mov	[Attributes], bl 
  3803                              <1> 
  3804                              <1> loc_print_attr_changed_message:
  3805 000067C6 BE[DAC20000]        <1> 	mov	esi, Msg_New
  3806 000067CB E84FD7FFFF          <1> 	call	print_msg
  3807 000067D0 E987FEFFFF          <1> 	jmp	loc_show_attributes_no_nextline
  3808                              <1> 
  3809                              <1> rename_file:
  3810                              <1> 	; 08/03/2016
  3811                              <1> 	; 06/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3812                              <1> 	; 20/11/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_rename')
  3813                              <1> 	; 16/11/2010 
  3814                              <1> 
  3815                              <1> get_rename_source_fchar:
  3816                              <1> 	; esi = file name
  3817 000067D5 803E20              <1> 	cmp	byte [esi], 20h
  3818 000067D8 7614                <1>         jna	short loc_rename_nofilename_retn
  3819                              <1> 
  3820 000067DA 8935[80DA0000]      <1> 	mov	[SourceFilePath], esi
  3821                              <1> 
  3822                              <1> rename_scan_source_file:
  3823 000067E0 46                  <1> 	inc	esi
  3824 000067E1 803E20              <1> 	cmp	byte [esi], 20h
  3825 000067E4 7409                <1> 	je	short rename_scan_destination_file_1
  3826                              <1> 	;jb	short loc_rename_nofilename_retn
  3827 000067E6 0F82D1EEFFFF        <1> 	jb	loc_cmd_failed
  3828 000067EC EBF2                <1> 	jmp	short rename_scan_source_file
  3829                              <1> 
  3830                              <1> loc_rename_nofilename_retn: ; 08/03/2016
  3831 000067EE C3                  <1> 	retn
  3832                              <1> 
  3833                              <1> rename_scan_destination_file_1:
  3834 000067EF C60600              <1> 	mov	byte [esi], 0
  3835                              <1> 
  3836                              <1> rename_scan_destination_file_2:
  3837 000067F2 46                  <1> 	inc	esi  
  3838 000067F3 803E20              <1> 	cmp	byte [esi], 20h
  3839 000067F6 74FA                <1> 	je	short rename_scan_destination_file_2
  3840                              <1> 	;jb	short loc_rename_nofilename_retn
  3841 000067F8 0F82BFEEFFFF        <1> 	jb	loc_cmd_failed
  3842                              <1> 
  3843 000067FE 8935[84DA0000]      <1> 	mov	[DestinationFilePath], esi
  3844                              <1> 
  3845                              <1> rename_scan_destination_file_3:
  3846 00006804 46                  <1> 	inc	esi  
  3847 00006805 803E20              <1> 	cmp	byte [esi], 20h
  3848 00006808 77FA                <1> 	ja	short rename_scan_destination_file_3
  3849                              <1> 
  3850 0000680A C60600              <1> 	mov	byte [esi], 0
  3851                              <1> 
  3852                              <1> loc_rename_save_current_drive:
  3853 0000680D 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  3854 00006813 8835[02D80000]      <1> 	mov	byte [RUN_CDRV], dh
  3855                              <1> 
  3856                              <1> loc_rename_sf_parse_path_name:
  3857 00006819 8B35[80DA0000]      <1> 	mov	esi, [SourceFilePath] 
  3858 0000681F BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  3859 00006824 E890150000          <1> 	call	parse_path_name
  3860 00006829 0F828EEEFFFF        <1> 	jc	loc_cmd_failed
  3861                              <1> 
  3862                              <1> loc_rename_sf_check_filename_exists:
  3863 0000682F BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3864 00006834 803E20              <1> 	cmp	byte [esi], 20h
  3865 00006837 0F8680EEFFFF        <1> 	jna	loc_cmd_failed
  3866                              <1> 
  3867                              <1> 	;mov	[DelFile_FNPointer], esi 
  3868                              <1> 
  3869                              <1> loc_rename_sf_drv:
  3870                              <1> 	;mov	dh, [Current_Drv]
  3871                              <1> 	;mov	[RUN_CDRV], dh
  3872                              <1> 
  3873 0000683D 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  3874 00006843 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  3875 00006845 740B                <1> 	je	short rename_sf_change_directory
  3876                              <1> 
  3877 00006847 E8D7DFFFFF          <1> 	call	change_current_drive
  3878 0000684C 0F828BF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3879                              <1> 
  3880                              <1> rename_sf_change_directory:
  3881 00006852 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3882 00006859 7618                <1> 	jna	short rename_sf_find
  3883                              <1> 
  3884 0000685B FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3885 00006861 BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  3886 00006866 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3887 00006868 E8380F0000          <1> 	call	change_current_directory
  3888 0000686D 0F826AF7FFFF        <1>  	jc	loc_file_rw_cmd_failed
  3889                              <1> 
  3890                              <1> ;rename_sf_change_prompt_dir_string:
  3891                              <1> 	;call	change_prompt_dir_string
  3892                              <1> 
  3893                              <1> rename_sf_find:
  3894                              <1> 	;mov	esi, [DelFile_FNPointer]
  3895 00006873 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3896                              <1> 
  3897 00006878 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3898 0000687C E838F3FFFF          <1> 	call	find_first_file
  3899 00006881 0F8256F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3900                              <1> 
  3901                              <1> loc_rename_sf_ambgfn_check:
  3902 00006887 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3903                              <1> 	;	(Note: It was BX in TRDOS v1)
  3904                              <1> 	;jz	short loc_rename_sf_found
  3905 0000688A 0F8563FCFFFF        <1> 	jnz	loc_file_not_found
  3906                              <1> 
  3907                              <1> 	;mov	eax, 2 ; File not found sign
  3908                              <1> 	;stc
  3909                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3910                              <1> 
  3911                              <1> loc_rename_sf_found:
  3912                              <1> 	; EDI = Directory buffer entry offset/address
  3913                              <1> 	; BL = File (or Directory) Attributes 
  3914                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3915                              <1> 	; mov	bl, [EDI+0Bh]
  3916                              <1> 
  3917 00006890 F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  3918 00006893 0F854EF7FFFF        <1> 	jnz	loc_permission_denied
  3919                              <1> 	
  3920 00006899 BE[46D90000]        <1>         mov     esi, FindFile_Drv
  3921 0000689E BF[88DA0000]        <1>         mov     edi, SourceFile_Drv
  3922 000068A3 B920000000          <1> 	mov	ecx, 32
  3923 000068A8 F3A5                <1> 	rep	movsd
  3924                              <1> 
  3925                              <1> loc_rename_df_parse_path_name:
  3926 000068AA 8B35[84DA0000]      <1> 	mov	esi, [DestinationFilePath]
  3927 000068B0 BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  3928 000068B5 E8FF140000          <1> 	call	parse_path_name
  3929 000068BA 7219                <1> 	jc	short loc_rename_df_cmd_failed
  3930                              <1> 
  3931                              <1> 	;mov	dh, [RUN_CDRV]
  3932 000068BC 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  3933                              <1> 
  3934                              <1> 	; 'rename' command is valid only for same dos drive and same dir!
  3935                              <1> 	; ('move' command must be used if source file and destination file
  3936                              <1> 	; directories are not same!) 
  3937 000068C2 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  3938 000068C8 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  3939 000068CA 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  3940                              <1> 
  3941                              <1> rename_df_check_dirname_exists:
  3942 000068CC 803D[47D90000]00    <1> 	cmp	byte [FindFile_Directory], 0
  3943 000068D3 760B                <1> 	jna	short rename_df_check_filename_exists
  3944                              <1> 
  3945                              <1> 	; different source file and destination file directories !
  3946                              <1> loc_rename_df_cmd_failed:
  3947                              <1> loc_rename_df_found:
  3948 000068D5 B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  3949 000068DA F9                  <1> 	stc
  3950 000068DB E9FDF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3951                              <1> 	  
  3952                              <1> rename_df_check_filename_exists:
  3953 000068E0 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3954 000068E5 E883F6FFFF          <1> 	call	check_filename
  3955 000068EA 0F829FF7FFFF        <1> 	jc	loc_mkdir_invalid_dir_name_chars
  3956                              <1> 
  3957                              <1> 	;mov	[DelFile_FNPointer], esi 
  3958                              <1> 	;cmp	byte [esi], 20h
  3959                              <1> 	;ja	short loc_rename_df_find
  3960                              <1> 
  3961                              <1> 	;mov	dh, [Current_Drv] ; dh has not been changed
  3962                              <1> 
  3963                              <1> rename_df_drv_check_writable:
  3964 000068F0 0FB6F6              <1> 	movzx	esi, dh
  3965                              <1> 	;movzx	esi, byte [Current_Drv]
  3966 000068F3 81C600010900        <1> 	add	esi, Logical_DOSDisks
  3967                              <1> 
  3968 000068F9 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  3969 000068FB 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  3970                              <1> 
  3971 000068FE 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  3972 00006901 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  3973                              <1> 
  3974 00006903 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected
  3975 00006908 8B1D[84DA0000]      <1> 	mov	ebx, [DestinationFilePath] 
  3976 0000690E E9CAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3977                              <1> 
  3978                              <1> rename_df_compare_sf_df_name:
  3979 00006913 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3980 00006918 BF[CADA0000]        <1> 	mov	edi, SourceFile_Name
  3981 0000691D B90C000000          <1> 	mov	ecx, 12
  3982                              <1> rename_df_compare_sf_df_name_next: 
  3983 00006922 AC                  <1> 	lodsb
  3984 00006923 AE                  <1> 	scasb
  3985 00006924 7506                <1> 	jne	short loc_rename_df_find
  3986 00006926 08C0                <1> 	or	al, al
  3987 00006928 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  3988 0000692A E2F6                <1> 	loop	rename_df_compare_sf_df_name_next 
  3989                              <1> 
  3990                              <1> loc_rename_df_find:
  3991                              <1> 	;mov	esi, [DelFile_FNPointer]
  3992 0000692C BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3993                              <1> 
  3994 00006931 6631C0              <1> 	xor	ax, ax ; Any
  3995 00006934 E880F2FFFF          <1> 	call	find_first_file
  3996 00006939 739A                <1> 	jnc	short loc_rename_df_found
  3997                              <1> 
  3998                              <1> loc_rename_df_check_error_code:
  3999                              <1> 	;cmp	eax, 2
  4000 0000693B 3C02                <1> 	cmp	al, 2 ; Not found error
  4001 0000693D 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  4002 0000693F F9                  <1> 	stc
  4003 00006940 E998F6FFFF          <1> 	jmp loc_file_rw_cmd_failed
  4004                              <1> 
  4005                              <1> ;loc_rename_df_found:
  4006                              <1> ;	mov	eax, 1 ;Bad command or file name error
  4007                              <1> ;	stc
  4008                              <1> ;	jmp	loc_file_rw_cmd_failed
  4009                              <1> 
  4010                              <1> rename_df_move_find_struct_to_dest:
  4011 00006945 BE[46D90000]        <1>         mov     esi, FindFile_Drv
  4012 0000694A BF[08DB0000]        <1>         mov     edi, DestinationFile_Drv
  4013 0000694F B920000000          <1> 	mov	ecx, 32
  4014 00006954 F3A5                <1> 	rep	movsd
  4015                              <1> 
  4016                              <1> loc_rename_df_process_q_sf:
  4017                              <1> 	;mov	ecx, 12
  4018 00006956 B10C                <1> 	mov	cl, 12
  4019 00006958 BE[CADA0000]        <1>  	mov	esi, SourceFile_Name
  4020 0000695D BF[1BC30000]        <1> 	mov	edi, Rename_OldName
  4021                              <1> rename_df_process_q_nml_1_sf:
  4022 00006962 AC                  <1> 	lodsb
  4023 00006963 3C20                <1>         cmp	al, 20h
  4024 00006965 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4025 00006967 AA                  <1> 	stosb
  4026 00006968 E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4027                              <1> 
  4028                              <1> rename_df_process_q_nml_2_sf:
  4029 0000696A C60700              <1> 	mov	byte [edi], 0
  4030                              <1> 
  4031                              <1> loc_rename_df_process_q_df:
  4032                              <1> 	;mov	ecx, 12
  4033 0000696D B10C                <1> 	mov	cl, 12
  4034 0000696F BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  4035 00006974 BF[2CC30000]        <1> 	mov	edi, Rename_NewName
  4036                              <1> rename_df_process_q_nml_1_df:
  4037 00006979 AC                  <1> 	lodsb
  4038 0000697A 3C20                <1> 	cmp	al, 20h
  4039 0000697C 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4040 0000697E AA                  <1> 	stosb
  4041 0000697F E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4042                              <1> 
  4043                              <1> loc_rename_df_process_q_nml_2_df:
  4044 00006981 C60700              <1> 	mov	byte [edi], 0
  4045                              <1> 
  4046                              <1> loc_rename_confirmation_question:
  4047 00006984 BE[F3C20000]        <1> 	mov	esi, Msg_DoYouWantRename
  4048 00006989 E891D5FFFF          <1> 	call	print_msg
  4049                              <1> 
  4050 0000698E A0[E5DA0000]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4051 00006993 2410                <1> 	and	al, 10h
  4052 00006995 750C                <1> 	jnz	short rename_confirmation_question_dir
  4053                              <1> 
  4054                              <1> rename_confirmation_question_file:
  4055 00006997 BE[0AC30000]        <1> 	mov	esi, Rename_File
  4056 0000699C E87ED5FFFF          <1> 	call	print_msg 
  4057 000069A1 EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4058                              <1> 
  4059                              <1> rename_confirmation_question_dir:
  4060 000069A3 BE[10C30000]        <1> 	mov	esi, Rename_Directory
  4061 000069A8 E872D5FFFF          <1> 	call	print_msg
  4062                              <1> 
  4063                              <1> rename_confirmation_question_as:
  4064 000069AD BE[1BC30000]        <1> 	mov	esi, Rename_OldName
  4065 000069B2 E868D5FFFF          <1> 	call	print_msg
  4066 000069B7 BE[28C30000]        <1> 	mov	esi, Msg_File_rename_as
  4067 000069BC E85ED5FFFF          <1> 	call	print_msg
  4068 000069C1 BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  4069 000069C6 E854D5FFFF          <1> 	call	print_msg
  4070                              <1> 
  4071                              <1> loc_rename_ask_again:
  4072 000069CB 30E4                <1> 	xor	ah, ah
  4073 000069CD E81DA2FFFF          <1> 	call	int16h
  4074 000069D2 3C1B                <1> 	cmp	al, 1Bh
  4075 000069D4 740F                <1> 	je	short loc_do_not_rename_file
  4076 000069D6 24DF                <1> 	and	al, 0DFh
  4077 000069D8 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  4078 000069DD 3C59                <1> 	cmp	al, 'Y'
  4079 000069DF 7404                <1> 	je	short loc_yes_rename_file
  4080 000069E1 3C4E                <1> 	cmp	al, 'N'
  4081 000069E3 75E6                <1> 	jne	short loc_rename_ask_again
  4082                              <1> 
  4083                              <1> loc_do_not_rename_file:
  4084                              <1> loc_yes_rename_file:
  4085 000069E5 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  4086 000069EA 6650                <1> 	push	ax
  4087 000069EC BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  4088 000069F1 E829D5FFFF          <1> 	call	print_msg
  4089 000069F6 6658                <1> 	pop	ax
  4090                              <1> 	;cmp	al, 'Y' ; 'yes'
  4091                              <1> 	;cmc
  4092                              <1>         ;jnc	loc_file_rw_restore_retn
  4093 000069F8 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4094 000069FA 0F84DDF5FFFF        <1>         je	loc_file_rw_restore_retn  
  4095                              <1> 
  4096 00006A00 BE[2CC30000]        <1> 	mov	esi, Rename_NewName
  4097 00006A05 668B0D[02DB0000]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4098 00006A0C 66A1[EEDA0000]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4099 00006A12 66C1E010            <1> 	shl	ax, 16
  4100 00006A16 66A1[F4DA0000]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4101                              <1> 
  4102 00006A1C 0FB61D[D7DA0000]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4103 00006A23 E8DB1B0000          <1>    	call	rename_directory_entry
  4104 00006A28 E9DEF6FFFF          <1> 	jmp	loc_rename_file_ok	
  4105                              <1> ;loc_rename_file_ok:
  4106                              <1> ;	jc	loc_run_cmd_failed
  4107                              <1> ;	mov	esi, Msg_OK
  4108                              <1> ;	call	proc_printmsg
  4109                              <1> ;	jmp	loc_file_rw_restore_retn
  4110                              <1> 
  4111                              <1> move_file:
  4112                              <1> 	; 11/03/2016
  4113                              <1> 	; 09/03/2016
  4114                              <1> 	; 08/03/2016 (TRDOS 386 =  TRDOS v2.0)
  4115                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_move')
  4116                              <1> 	; 23/04/2011
  4117                              <1> 
  4118                              <1> get_move_source_fchar:
  4119                              <1> 	; esi = file name
  4120 00006A2D 803E20              <1> 	cmp	byte [esi], 20h
  4121 00006A30 7614                <1>         jna	short loc_move_nofilename_retn
  4122                              <1> 
  4123 00006A32 8935[80DA0000]      <1> 	mov	[SourceFilePath], esi
  4124                              <1> 
  4125                              <1> move_scan_source_file:
  4126 00006A38 46                  <1> 	inc	esi
  4127 00006A39 803E20              <1> 	cmp	byte [esi], 20h
  4128 00006A3C 7409                <1>         je      short move_scan_destination_1
  4129                              <1> 	;jb	short loc_move_nofilename_retn
  4130 00006A3E 0F8279ECFFFF        <1> 	jb	loc_cmd_failed
  4131 00006A44 EBF2                <1> 	jmp	short move_scan_source_file
  4132                              <1> 
  4133                              <1> loc_move_nofilename_retn:
  4134 00006A46 C3                  <1> 	retn
  4135                              <1> 
  4136                              <1> move_scan_destination_1:
  4137 00006A47 C60600              <1> 	mov	byte [esi], 0
  4138                              <1> 
  4139                              <1> move_scan_destination_2:
  4140 00006A4A 46                  <1> 	inc	esi  
  4141 00006A4B 803E20              <1> 	cmp	byte [esi], 20h
  4142 00006A4E 74FA                <1> 	je	short move_scan_destination_2
  4143                              <1> 	;jb	short loc_move_nofilename_retn
  4144 00006A50 0F8267ECFFFF        <1> 	jb	loc_cmd_failed
  4145                              <1> 
  4146 00006A56 8935[84DA0000]      <1> 	mov	[DestinationFilePath], esi
  4147                              <1> 
  4148                              <1> move_scan_destination_3:
  4149 00006A5C 46                  <1> 	inc	esi  
  4150 00006A5D 803E20              <1> 	cmp	byte [esi], 20h
  4151 00006A60 77FA                <1> 	ja	short move_scan_destination_3
  4152 00006A62 C60600              <1> 	mov	byte [esi], 0
  4153                              <1> 
  4154                              <1> loc_move_scan_destination_OK:
  4155 00006A65 8B35[80DA0000]      <1> 	mov	esi, [SourceFilePath]
  4156 00006A6B 8B3D[84DA0000]      <1> 	mov	edi, [DestinationFilePath]
  4157                              <1> 
  4158 00006A71 B001                <1> 	mov	al, 1  ; move procedure Phase 1
  4159 00006A73 E8081C0000          <1> 	call	move_source_file_to_destination_file
  4160 00006A78 7328                <1> 	jnc	short move_source_file_to_destination_question
  4161                              <1> 
  4162                              <1> loc_move_cmd_failed_1:
  4163 00006A7A 08C0                <1> 	or	al, al
  4164 00006A7C 0F843BECFFFF        <1> 	jz	loc_cmd_failed 
  4165 00006A82 3C11                <1> 	cmp	al, 11h
  4166 00006A84 740D                <1> 	je	short loc_msg_not_same_device   
  4167 00006A86 3C05                <1> 	cmp	al, 05h
  4168 00006A88 0F855AECFFFF        <1> 	jne	loc_run_cmd_failed
  4169                              <1> 
  4170 00006A8E E954F5FFFF          <1> 	jmp	loc_permission_denied
  4171                              <1> 
  4172                              <1> 	;mov	esi, Msg_Permission_denied
  4173                              <1> 	;call	print_msg
  4174                              <1> 	;jmp	loc_file_rw_restore_retn
  4175                              <1> 
  4176                              <1> loc_msg_not_same_device:
  4177 00006A93 BE[39C30000]        <1> 	mov	esi, msg_not_same_drv 
  4178 00006A98 E882D4FFFF          <1> 	call	print_msg
  4179 00006A9D E93BF5FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4180                              <1> 
  4181                              <1> move_source_file_to_destination_question:
  4182 00006AA2 A0[88DA0000]        <1>         mov     al, [SourceFile_Drv]
  4183 00006AA7 0441                <1> 	add	al, 'A'
  4184 00006AA9 A2[9BC30000]        <1> 	mov	[msg_source_file_drv], al
  4185 00006AAE A0[08DB0000]        <1>         mov     al, [DestinationFile_Drv]
  4186 00006AB3 0441                <1> 	add	al, 'A'
  4187 00006AB5 A2[BAC30000]        <1> 	mov	[msg_destination_file_drv], al
  4188                              <1> 
  4189 00006ABA 57                  <1> 	push	edi ; *
  4190                              <1> 
  4191 00006ABB BE[7FC30000]        <1> 	mov	esi, msg_source_file
  4192 00006AC0 E85AD4FFFF          <1> 	call	print_msg
  4193 00006AC5 BE[89DA0000]        <1> 	mov	esi, SourceFile_Directory
  4194 00006ACA 803E20              <1> 	cmp	byte [esi], 20h
  4195 00006ACD 7605                <1> 	jna	short msftdfq_sfn
  4196 00006ACF E84BD4FFFF          <1> 	call	print_msg
  4197                              <1> msftdfq_sfn:
  4198 00006AD4 BE[CADA0000]        <1> 	mov	esi, SourceFile_Name
  4199 00006AD9 E841D4FFFF          <1> 	call	print_msg
  4200 00006ADE BE[9EC30000]        <1> 	mov	esi, msg_destination_file
  4201 00006AE3 E837D4FFFF          <1> 	call	print_msg
  4202 00006AE8 BE[09DB0000]        <1> 	mov	esi, DestinationFile_Directory
  4203 00006AED 803E20              <1> 	cmp	byte [esi], 20h
  4204 00006AF0 7605                <1> 	jna	short msftdfq_dfn
  4205 00006AF2 E828D4FFFF          <1> 	call	print_msg
  4206                              <1> msftdfq_dfn:
  4207 00006AF7 BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  4208 00006AFC E81ED4FFFF          <1> 	call	print_msg
  4209 00006B01 BE[BDC30000]        <1> 	mov	esi, msg_copy_nextline
  4210 00006B06 E814D4FFFF          <1> 	call	print_msg
  4211 00006B0B BE[BDC30000]        <1> 	mov	esi, msg_copy_nextline
  4212 00006B10 E80AD4FFFF          <1> 	call	print_msg
  4213                              <1> 
  4214                              <1> loc_move_ask_for_new_file_yes_no:
  4215 00006B15 BE[4BC30000]        <1> 	mov	esi, Msg_DoYouWantMoveFile
  4216 00006B1A E800D4FFFF          <1> 	call	print_msg
  4217 00006B1F BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  4218 00006B24 E8F6D3FFFF          <1> 	call	print_msg
  4219                              <1> loc_move_ask_for_new_file_again:
  4220 00006B29 30E4                <1> 	xor	ah, ah
  4221 00006B2B E8BFA0FFFF          <1> 	call	int16h
  4222 00006B30 3C1B                <1> 	cmp	al, 1Bh
  4223                              <1> 	;je	short loc_do_not_move_file
  4224 00006B32 744F                <1> 	je	short loc_move_y_n_escape
  4225 00006B34 24DF                <1> 	and	al, 0DFh
  4226 00006B36 A2[59C20000]        <1>         mov     [Y_N_nextline], al
  4227 00006B3B 3C59                <1> 	cmp	al, 'Y'
  4228 00006B3D 7404                <1> 	je	short loc_yes_move_file
  4229 00006B3F 3C4E                <1> 	cmp	al, 'N'
  4230 00006B41 75E6                <1> 	jne	short loc_move_ask_for_new_file_again
  4231                              <1> 
  4232                              <1> loc_do_not_move_file:
  4233                              <1> loc_yes_move_file:
  4234 00006B43 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  4235 00006B48 6650                <1> 	push	ax
  4236 00006B4A BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  4237 00006B4F E8CBD3FFFF          <1> 	call	print_msg
  4238 00006B54 6658                <1> 	pop	ax
  4239 00006B56 5F                  <1> 	pop	edi ; *
  4240                              <1> 	;cmp	al, 'Y' ; 'yes'
  4241                              <1> 	;cmc
  4242                              <1>         ;jnc	loc_file_rw_restore_retn
  4243 00006B57 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4244 00006B59 0F847EF4FFFF        <1>         je	loc_file_rw_restore_retn
  4245                              <1> 
  4246                              <1> loc_move_yes_move_file:
  4247 00006B5F B002                <1> 	mov	al, 2 ; move procedure Phase 2
  4248 00006B61 E81A1B0000          <1> 	call	move_source_file_to_destination_file
  4249                              <1> 	;jc	short loc_move_cmd_failed_2
  4250 00006B66 0F83A5F5FFFF        <1>         jnc     move_source_file_to_destination_OK
  4251                              <1> 
  4252                              <1> ;move_source_file_to_destination_OK:
  4253                              <1> ;	mov	esi, Msg_OK
  4254                              <1> ;	call	print_msg
  4255                              <1> ;	jmp	loc_file_rw_restore_retn
  4256                              <1> 
  4257                              <1> loc_move_cmd_failed_2:
  4258 00006B6C 3C27                <1> 	cmp	al, 27h
  4259 00006B6E 0F8574EBFFFF        <1> 	jne	loc_run_cmd_failed
  4260                              <1> 
  4261 00006B74 BE[64C30000]        <1> 	mov	esi, msg_insufficient_disk_space
  4262 00006B79 E8A1D3FFFF          <1> 	call	print_msg
  4263                              <1> 
  4264 00006B7E E95AF4FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4265                              <1> 
  4266                              <1> loc_move_y_n_escape:
  4267 00006B83 B04E                <1> 	mov	al, 'N' ; 'no'
  4268 00006B85 EBBC                <1> 	jmp	short loc_do_not_move_file
  4269                              <1> 
  4270                              <1> copy_file:
  4271                              <1> 	; 24/03/2016
  4272                              <1> 	; 21/03/2016
  4273                              <1> 	; 15/03/2016 (TRDOS 386 =  TRDOS v2.0)
  4274                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_copy')
  4275                              <1> 	; 01/08/2010
  4276                              <1> 
  4277                              <1> get_copy_source_fchar:
  4278                              <1> 	; esi = file name
  4279 00006B87 803E20              <1> 	cmp	byte [esi], 20h
  4280 00006B8A 7614                <1>         jna     short loc_copy_nofilename_retn
  4281                              <1> 
  4282 00006B8C 8935[80DA0000]      <1> 	mov	[SourceFilePath], esi
  4283                              <1> 
  4284                              <1> copy_scan_source_file:
  4285 00006B92 46                  <1> 	inc	esi  
  4286 00006B93 803E20              <1> 	cmp	byte [esi], 20h
  4287 00006B96 7409                <1> 	je	short copy_scan_destination_1
  4288                              <1> 	;jb	short loc_copy_nofilename_retn
  4289 00006B98 0F821FEBFFFF        <1> 	jb	loc_cmd_failed
  4290 00006B9E EBF2                <1> 	jmp	short copy_scan_source_file
  4291                              <1> 
  4292                              <1> loc_copy_nofilename_retn:
  4293 00006BA0 C3                  <1> 	retn
  4294                              <1> 
  4295                              <1> copy_scan_destination_1:
  4296 00006BA1 C60600              <1> 	mov	byte [esi], 0
  4297                              <1> 
  4298                              <1> copy_scan_destination_2:
  4299 00006BA4 46                  <1> 	inc	esi  
  4300 00006BA5 803E20              <1> 	cmp	byte [esi], 20h
  4301 00006BA8 74FA                <1> 	je	short copy_scan_destination_2
  4302                              <1> 	;jb	short loc_copy_nofilename_retn
  4303 00006BAA 0F820DEBFFFF        <1> 	jb	loc_cmd_failed
  4304                              <1> 
  4305 00006BB0 8935[84DA0000]      <1> 	mov	[DestinationFilePath], esi
  4306                              <1> 
  4307                              <1> copy_scan_destination_3:
  4308 00006BB6 46                  <1> 	inc	esi  
  4309 00006BB7 803E20              <1> 	cmp	byte [esi], 20h
  4310 00006BBA 77FA                <1> 	ja	short copy_scan_destination_3
  4311 00006BBC C60600              <1> 	mov	byte [esi], 0
  4312                              <1> 
  4313                              <1> loc_copy_save_current_drive:
  4314 00006BBF 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  4315 00006BC5 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  4316                              <1> 
  4317                              <1> copy_source_file_to_destination_phase_1:
  4318 00006BCB 8B35[80DA0000]      <1> 	mov	esi, [SourceFilePath]
  4319 00006BD1 8B3D[84DA0000]      <1> 	mov	edi, [DestinationFilePath]
  4320                              <1> 
  4321 00006BD7 B001                <1> 	mov	al, 1  ; copy procedure Phase 1
  4322 00006BD9 E82D1D0000          <1> 	call	copy_source_file_to_destination_file
  4323 00006BDE 732B                <1> 	jnc	short copy_source_file_to_destination_question
  4324                              <1> 
  4325                              <1> loc_copy_cmd_failed_1:
  4326                              <1> 	; 18/03/2016 (restore current drive and directory)
  4327 00006BE0 08C0                <1> 	or	al, al
  4328 00006BE2 7507                <1> 	jnz	short loc_copy_cmd_failed_2
  4329                              <1> 
  4330 00006BE4 FEC0                <1>         inc     al ; mov al, 1 ; Bad command or file name !
  4331 00006BE6 E9FDEAFFFF          <1> 	jmp	loc_run_cmd_failed
  4332                              <1> 
  4333                              <1> loc_copy_cmd_failed_2:
  4334 00006BEB 3C27                <1> 	cmp	al, 27h ; Insufficient disk space 
  4335 00006BED 740D                <1> 	je	short loc_file_write_insuff_disk_space_msg
  4336                              <1>  
  4337 00006BEF 3C05                <1> 	cmp	al, 05h
  4338 00006BF1 0F85F1EAFFFF        <1> 	jne	loc_run_cmd_failed
  4339                              <1> 	
  4340 00006BF7 E9EBF3FFFF          <1> 	jmp	loc_permission_denied
  4341                              <1> 
  4342                              <1> loc_file_write_insuff_disk_space_msg:
  4343 00006BFC BE[64C30000]        <1> 	mov	esi, msg_insufficient_disk_space
  4344 00006C01 E819D3FFFF          <1> 	call	print_msg
  4345 00006C06 E9D2F3FFFF          <1>         jmp     loc_file_rw_restore_retn 
  4346                              <1> 
  4347                              <1> copy_source_file_to_destination_question:
  4348 00006C0B 57                  <1> 	push	edi ; *
  4349                              <1> 
  4350                              <1> 	; dh = source file attributes
  4351                              <1> 	; dl > 0 -> destination file found
  4352 00006C0C 20D2                <1> 	and	dl, dl            
  4353 00006C0E 7449                <1> 	jz	short copy_source_file_to_destination_pass_owrq
  4354                              <1> 
  4355                              <1> loc_copy_ask_for_owr_yes_no:
  4356 00006C10 BE[C0C30000]        <1> 	mov	esi, Msg_DoYouWantOverWriteFile
  4357 00006C15 E805D3FFFF          <1> 	call	print_msg
  4358 00006C1A BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  4359 00006C1F E8FBD2FFFF          <1> 	call	print_msg
  4360 00006C24 BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  4361 00006C29 E8F1D2FFFF          <1> 	call	print_msg
  4362                              <1> 
  4363                              <1> loc_copy_ask_for_owr_again:
  4364 00006C2E 30E4                <1> 	xor	ah, ah
  4365 00006C30 E8BA9FFFFF          <1> 	call	int16h
  4366 00006C35 3C1B                <1> 	cmp	al, 1Bh
  4367                              <1>         ;je     loc_do_not_copy_file
  4368 00006C37 7419                <1>         je      short loc_copy_y_n_escape
  4369 00006C39 24DF                <1> 	and	al, 0DFh
  4370 00006C3B A2[59C20000]        <1>         mov     [Y_N_nextline], al
  4371 00006C40 3C59                <1> 	cmp	al, 'Y'
  4372 00006C42 0F84B1000000        <1>         je      loc_yes_copy_file
  4373 00006C48 3C4E                <1> 	cmp	al, 'N'
  4374 00006C4A 0F84A9000000        <1>         je      loc_do_not_copy_file
  4375 00006C50 EBDC                <1> 	jmp	short loc_copy_ask_for_owr_again
  4376                              <1> 
  4377                              <1> loc_copy_y_n_escape:
  4378 00006C52 B04E                <1> 	mov	al, 'N' ; 'no'
  4379 00006C54 E9A0000000          <1>         jmp     loc_do_not_copy_file
  4380                              <1> 
  4381                              <1> copy_source_file_to_destination_pass_owrq:
  4382 00006C59 A0[88DA0000]        <1> 	mov     al, [SourceFile_Drv]
  4383 00006C5E 0441                <1> 	add	al, 'A'
  4384 00006C60 A2[9BC30000]        <1> 	mov	[msg_source_file_drv], al
  4385 00006C65 A0[08DB0000]        <1>         mov     al, [DestinationFile_Drv]
  4386 00006C6A 0441                <1> 	add	al, 'A'
  4387 00006C6C A2[BAC30000]        <1> 	mov	[msg_destination_file_drv], al
  4388                              <1> 
  4389 00006C71 BE[7FC30000]        <1> 	mov	esi, msg_source_file
  4390 00006C76 E8A4D2FFFF          <1> 	call	print_msg
  4391 00006C7B BE[89DA0000]        <1> 	mov	esi, SourceFile_Directory
  4392 00006C80 803E20              <1> 	cmp	byte [esi], 20h
  4393 00006C83 7605                <1> 	jna	short csftdfq_sfn
  4394 00006C85 E895D2FFFF          <1> 	call	print_msg
  4395                              <1> csftdfq_sfn:
  4396 00006C8A BE[CADA0000]        <1> 	mov	esi, SourceFile_Name
  4397 00006C8F E88BD2FFFF          <1> 	call	print_msg
  4398 00006C94 BE[9EC30000]        <1> 	mov	esi, msg_destination_file
  4399 00006C99 E881D2FFFF          <1> 	call	print_msg
  4400 00006C9E BE[09DB0000]        <1> 	mov	esi, DestinationFile_Directory
  4401 00006CA3 803E20              <1> 	cmp	byte [esi], 20h
  4402 00006CA6 7605                <1> 	jna	short csftdfq_dfn
  4403 00006CA8 E872D2FFFF          <1> 	call	print_msg
  4404                              <1> csftdfq_dfn:
  4405 00006CAD BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  4406 00006CB2 E868D2FFFF          <1> 	call	print_msg
  4407 00006CB7 BE[BDC30000]        <1> 	mov	esi, msg_copy_nextline
  4408 00006CBC E85ED2FFFF          <1> 	call	print_msg
  4409 00006CC1 BE[BDC30000]        <1> 	mov	esi, msg_copy_nextline
  4410 00006CC6 E854D2FFFF          <1> 	call	print_msg
  4411                              <1> 
  4412                              <1> loc_copy_ask_for_new_file_yes_no:
  4413 00006CCB BE[DFC30000]        <1> 	mov	esi, Msg_DoYouWantCopyFile
  4414 00006CD0 E84AD2FFFF          <1> 	call	print_msg
  4415 00006CD5 BE[4FC20000]        <1> 	mov	esi, Msg_YesNo
  4416 00006CDA E840D2FFFF          <1> 	call	print_msg
  4417                              <1> 
  4418                              <1> loc_copy_ask_for_new_file_again:
  4419 00006CDF 30E4                <1> 	xor	ah, ah
  4420 00006CE1 E8099FFFFF          <1> 	call	int16h
  4421 00006CE6 3C1B                <1> 	cmp	al, 1Bh
  4422 00006CE8 740F                <1> 	je	short loc_do_not_copy_file
  4423 00006CEA 24DF                <1> 	and	al, 0DFh
  4424 00006CEC A2[59C20000]        <1>         mov     [Y_N_nextline], al
  4425 00006CF1 3C59                <1> 	cmp	al, 'Y'
  4426 00006CF3 7404                <1> 	je	short loc_yes_copy_file
  4427 00006CF5 3C4E                <1> 	cmp	al, 'N'
  4428 00006CF7 75E6                <1> 	jne	short loc_copy_ask_for_new_file_again
  4429                              <1> 
  4430                              <1> loc_do_not_copy_file:
  4431                              <1> loc_yes_copy_file:
  4432 00006CF9 A2[59C20000]        <1> 	mov	[Y_N_nextline], al
  4433 00006CFE 6650                <1> 	push	ax
  4434 00006D00 BE[59C20000]        <1> 	mov	esi, Y_N_nextline
  4435 00006D05 E815D2FFFF          <1> 	call	print_msg
  4436 00006D0A 6658                <1> 	pop	ax
  4437 00006D0C 5F                  <1> 	pop	edi ; *
  4438                              <1> 	;cmp	al, 'Y' ; 'yes'
  4439                              <1> 	;cmc
  4440                              <1>         ;jnc	loc_file_rw_restore_retn
  4441 00006D0D 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4442 00006D0F 0F84C8F2FFFF        <1>         je	loc_file_rw_restore_retn
  4443                              <1> 
  4444                              <1> copy_source_file_to_destination_pass_q:
  4445 00006D15 B002                <1> 	mov	al, 2  ; copy procedure Phase 2
  4446 00006D17 E8EF1B0000          <1> 	call	copy_source_file_to_destination_file
  4447                              <1> 	;jc	short loc_file_write_check_disk_space_err
  4448                              <1> 
  4449                              <1> 	; 24/03/2016
  4450 00006D1C 6651                <1> 	push	cx
  4451 00006D1E BE[BDC30000]        <1> 	mov	esi, msg_copy_nextline
  4452 00006D23 E8F7D1FFFF          <1> 	call	print_msg
  4453                              <1> 	;pop	cx
  4454 00006D28 6658                <1> 	pop	ax
  4455                              <1> 
  4456                              <1> 	;or	cl, cl
  4457 00006D2A 08C0                <1> 	or	al, al
  4458 00006D2C 7419                <1> 	jz	short copy_source_file_to_destination_OK
  4459                              <1> 	
  4460                              <1> 	; 18/03/2016
  4461                              <1> 	;cmp	cl, 1Dh ; write error
  4462 00006D2E 3C1D                <1> 	cmp	al, 1Dh
  4463 00006D30 7506                <1> 	jne	short copy_source_file_to_destination_not_OK
  4464                              <1> 	;
  4465                              <1> 	;mov	al, cl ; error number (write fault!)
  4466 00006D32 F9                  <1> 	stc
  4467 00006D33 E9A5F2FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4468                              <1> 
  4469                              <1> copy_source_file_to_destination_not_OK:
  4470 00006D38 BE[F8C30000]        <1> 	mov	esi, Msg_read_file_error_before_EOF
  4471 00006D3D E8DDD1FFFF          <1> 	call	print_msg
  4472 00006D42 E996F2FFFF          <1> 	jmp	loc_file_rw_restore_retn	      
  4473                              <1>  
  4474                              <1> copy_source_file_to_destination_OK:
  4475 00006D47 BE[5DC20000]        <1> 	mov	esi, Msg_OK
  4476 00006D4C E8CED1FFFF          <1> 	call	print_msg
  4477                              <1> 
  4478 00006D51 E987F2FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4479                              <1> 
  4480                              <1> ;loc_file_write_check_disk_space_err:
  4481                              <1> 	;cmp	al, 27h ; Insufficient disk space 
  4482                              <1> 	;je	loc_file_write_insuff_disk_space_msg
  4483                              <1>         ;jb	loc_file_rw_cmd_failed
  4484                              <1> 
  4485                              <1> 	;call	print_misc_error_msg ; 15/03/2016
  4486                              <1>         ;jmp	loc_file_rw_restore_retn 
  4487                              <1> 
  4488                              <1> change_fs_file_attributes:
  4489                              <1> 	; 04/03/2016 ; Temporary
  4490                              <1> 	; AL = File or directory attributes
  4491                              <1> 	; AH = 0 -> Attributes are in MS-DOS format
  4492                              <1> 	; AH > 0 -> Attributes are in SINGLIX format
  4493                              <1> 	;push	ebx
  4494                              <1> 	; ... do somethings here ...
  4495                              <1> 	;pop	ebx
  4496                              <1> 	; BL = File or directory attributes
  4497 00006D56 C3                  <1> 	retn
  4498                              <1> 
  4499                              <1> set_get_env:
  4500                              <1> 	; 11/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4501                              <1> 	; 02/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_set')
  4502                              <1> 	; 2005 - 28/08/2011 
  4503                              <1> get_setenv_fchar:
  4504                              <1> 	; esi = environment variable/string
  4505 00006D57 8A06                <1> 	mov	al, [esi]
  4506 00006D59 3C20                <1> 	cmp	al, 20h
  4507 00006D5B 771E                <1> 	ja	short loc_find_env
  4508                              <1> 
  4509 00006D5D BE00300900          <1> 	mov	esi, Env_Page
  4510                              <1> loc_print_setline:
  4511 00006D62 803E00              <1> 	cmp	byte [esi], 0
  4512 00006D65 7613                <1> 	jna	short loc_setenv_retn
  4513 00006D67 E8B3D1FFFF          <1> 	call	print_msg
  4514 00006D6C 56                  <1> 	push	esi
  4515 00006D6D BE[76CB0000]        <1> 	mov	esi, nextline
  4516 00006D72 E8A8D1FFFF          <1> 	call	print_msg 
  4517 00006D77 5E                  <1> 	pop	esi
  4518 00006D78 EBE8                <1> 	jmp	short loc_print_setline   
  4519                              <1> 
  4520                              <1> loc_setenv_retn: 
  4521 00006D7A C3                  <1> 	retn
  4522                              <1> 
  4523                              <1> loc_find_env:
  4524 00006D7B 3C3D                <1> 	cmp	al, '='
  4525 00006D7D 0F843AE9FFFF        <1> 	je	loc_cmd_failed
  4526                              <1> 
  4527 00006D83 56                  <1> 	push	esi
  4528                              <1> loc_repeat_env_equal_check:
  4529 00006D84 46                  <1> 	inc	esi
  4530 00006D85 803E3D              <1> 	cmp	byte [esi], '='
  4531 00006D88 7431                <1> 	je	short pass_env_equal_check
  4532 00006D8A 803E20              <1> 	cmp	byte [esi], 20h
  4533 00006D8D 73F5                <1> 	jnb	short loc_repeat_env_equal_check
  4534 00006D8F C60600              <1> 	mov	byte [esi], 0 
  4535 00006D92 5E                  <1> 	pop	esi
  4536 00006D93 BF[A2D00000]        <1> 	mov	edi, TextBuffer ; out buffer
  4537 00006D98 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4538 00006D9D 30C0                <1> 	xor	al, al ; 0 -> use [ESI]
  4539 00006D9F E89E000000          <1> 	call	get_environment_string
  4540 00006DA4 72D4                <1> 	jc	short loc_setenv_retn
  4541                              <1> 
  4542 00006DA6 BE[A2D00000]        <1> 	mov	esi, TextBuffer
  4543 00006DAB E86FD1FFFF          <1> 	call	print_msg
  4544 00006DB0 BE[76CB0000]        <1> 	mov	esi, nextline
  4545 00006DB5 E865D1FFFF          <1> 	call	print_msg
  4546                              <1> 
  4547 00006DBA C3                  <1> 	retn 
  4548                              <1>               
  4549                              <1> pass_env_equal_check:
  4550 00006DBB 46                  <1> 	inc	esi
  4551 00006DBC 803E20              <1> 	cmp	byte [esi], 20h
  4552 00006DBF 73FA                <1> 	jnb	short pass_env_equal_check
  4553 00006DC1 C60600              <1> 	mov	byte [esi], 0	
  4554                              <1> 
  4555                              <1> loc_call_set_env_string:
  4556 00006DC4 5E                  <1> 	pop	esi
  4557 00006DC5 E83B010000          <1> 	call	set_environment_string
  4558 00006DCA 73AE                <1> 	jnc	short loc_setenv_retn
  4559                              <1> 
  4560                              <1> loc_set_cmd_failed:
  4561 00006DCC 3C08                <1> 	cmp	al, 08h
  4562 00006DCE 0F85E9E8FFFF        <1> 	jne	loc_cmd_failed
  4563                              <1> 
  4564 00006DD4 BE[38C40000]        <1> 	mov	esi, Msg_No_Set_Space
  4565 00006DD9 E841D1FFFF          <1> 	call	print_msg
  4566                              <1> 
  4567 00006DDE C3                  <1> 	retn
  4568                              <1> 
  4569                              <1> set_get_path:
  4570                              <1> 	; 11/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4571                              <1> 	; 03/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_path')
  4572                              <1> 	; 2005
  4573                              <1> get_path_fchar:
  4574                              <1>  	; esi = path
  4575 00006DDF 803E20              <1> 	cmp	byte [esi], 20h
  4576 00006DE2 7737                <1> 	ja	short loc_set_path
  4577                              <1> 
  4578 00006DE4 BE00300900          <1> 	mov	esi, Env_Page
  4579                              <1> loc_print_path:
  4580 00006DE9 803E00              <1> 	cmp	byte [esi], 0
  4581 00006DEC 762C                <1> 	jna	short loc_path_retn
  4582                              <1> 
  4583 00006DEE BE[92BE0000]        <1> 	mov	esi, Cmd_Path ; 'PATH' address
  4584 00006DF3 BF[A2D00000]        <1> 	mov	edi, TextBuffer ; oout buffer
  4585 00006DF8 30C0                <1> 	xor	al, al  ; use [ESI]
  4586 00006DFA B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4587 00006DFF E83E000000          <1> 	call	get_environment_string
  4588 00006E04 7214                <1> 	jc	short loc_path_retn
  4589                              <1> 
  4590 00006E06 BE[A2D00000]        <1> 	mov	esi, TextBuffer
  4591 00006E0B E80FD1FFFF          <1> 	call	print_msg
  4592 00006E10 BE[76CB0000]        <1> 	mov	esi, nextline
  4593 00006E15 E805D1FFFF          <1> 	call	print_msg   
  4594                              <1> 
  4595                              <1> loc_path_retn: 
  4596 00006E1A C3                  <1> 	retn
  4597                              <1> 
  4598                              <1> loc_set_path:
  4599 00006E1B 56                  <1> 	push	esi 
  4600                              <1> loc_set_path_find_end:
  4601 00006E1C 46                  <1> 	inc	esi
  4602 00006E1D 803E20              <1> 	cmp	byte [esi], 20h
  4603 00006E20 73FA                <1> 	jnb	short loc_set_path_find_end
  4604 00006E22 C60600              <1> 	mov	byte [esi], 0 
  4605                              <1> loc_set_path_header: 
  4606 00006E25 5E                  <1> 	pop	esi	  
  4607 00006E26 4E                  <1> 	dec	esi
  4608 00006E27 C6063D              <1> 	mov	byte [esi], '='
  4609 00006E2A 4E                  <1> 	dec	esi
  4610 00006E2B C60648              <1> 	mov	byte [esi], 'H'
  4611 00006E2E 4E                  <1> 	dec	esi
  4612 00006E2F C60654              <1> 	mov	byte [esi], 'T'
  4613 00006E32 4E                  <1> 	dec	esi
  4614 00006E33 C60641              <1> 	mov	byte [esi], 'A'
  4615 00006E36 4E                  <1> 	dec	esi
  4616 00006E37 C60650              <1> 	mov	byte [esi], 'P'   
  4617                              <1> 
  4618                              <1> loc_path_call_set_env_string:
  4619 00006E3A E8C6000000          <1> 	call	set_environment_string
  4620 00006E3F 728B                <1>         jc	short loc_set_cmd_failed
  4621                              <1> 
  4622 00006E41 C3                  <1> 	retn              
  4623                              <1> 
  4624                              <1> get_environment_string:
  4625                              <1> 	; 12/04/2016
  4626                              <1> 	; 11/04/2016
  4627                              <1> 	; 05/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4628                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4629                              <1> 	; 28/08/2011
  4630                              <1> 	; INPUT->
  4631                              <1> 	;	EDI = Output buffer
  4632                              <1> 	;	CX = Buffer length (<= ENV_PAGE_SIZE)
  4633                              <1> 	;
  4634                              <1> 	;	AL > 0 = AL = String sequence number
  4635                              <1> 	;	AL = 0 -> ESI = ASCIIZ Set word 
  4636                              <1> 	;		(environment variable)
  4637                              <1> 	; OUTPUT ->
  4638                              <1> 	;	ESI is not changed
  4639                              <1> 	;	EDI is not changed
  4640                              <1> 	;	EAX = String length (with zero tail)
  4641                              <1> 	;	EDX = Environment variables page address
  4642                              <1> 	;	CF = 1 -> Not found (EAX not valid)
  4643                              <1> 	;
  4644                              <1> 	; (Modified registers: EAX, EDX) 
  4645                              <1> 
  4646 00006E42 BA00300900          <1> 	mov	edx, Env_Page
  4647 00006E47 803A00              <1> 	cmp	byte [edx], 0
  4648 00006E4A 7474                <1> 	jz	short get_env_string_with_word_stc_retn
  4649                              <1> 
  4650 00006E4C 66890D[0CDC0000]    <1> 	mov	[env_var_length], cx
  4651                              <1> 
  4652 00006E53 51                  <1> 	push	ecx ; *
  4653 00006E54 56                  <1> 	push	esi ; **
  4654                              <1> 
  4655 00006E55 08C0                <1> 	or	al, al
  4656 00006E57 7449                <1> 	jz	short get_env_string_with_word
  4657                              <1> 
  4658                              <1> get_env_string_with_seq_number:
  4659 00006E59 B101                <1> 	mov	cl, 1
  4660 00006E5B 88C5                <1> 	mov	ch, al
  4661 00006E5D 31C0                <1> 	xor	eax, eax
  4662 00006E5F 89D6                <1> 	mov	esi, edx ; Env_Page
  4663                              <1> 
  4664                              <1> get_env_string_seq_number_check:
  4665 00006E61 38CD                <1> 	cmp	ch, cl
  4666 00006E63 7726                <1> 	ja	short get_env_string_seq_number_next
  4667                              <1> 
  4668                              <1> get_env_string_move_to_buff:
  4669 00006E65 57                  <1> 	push	edi ; ***
  4670                              <1> 
  4671 00006E66 29D2                <1> 	sub	edx, edx
  4672                              <1> 
  4673                              <1> get_env_string_seq_number_repeat1:
  4674 00006E68 42                  <1> 	inc	edx
  4675 00006E69 AC                  <1> 	lodsb
  4676 00006E6A AA                  <1> 	stosb
  4677                              <1> 
  4678 00006E6B 66FF0D[0CDC0000]    <1> 	dec	word [env_var_length]
  4679 00006E72 7508                <1> 	jnz	short get_env_string_seq_number_repeat3
  4680                              <1> 
  4681                              <1> get_env_string_seq_number_repeat2:
  4682 00006E74 20C0                <1> 	and	al, al
  4683 00006E76 7408                <1> 	jz	short get_env_string_seq_number_ok
  4684 00006E78 42                  <1> 	inc	edx
  4685 00006E79 AC                  <1> 	lodsb
  4686 00006E7A EBF8                <1> 	jmp	short get_env_string_seq_number_repeat2
  4687                              <1> 
  4688                              <1> get_env_string_seq_number_repeat3:
  4689 00006E7C 08C0                <1> 	or	al, al
  4690 00006E7E 75E8                <1> 	jnz	short get_env_string_seq_number_repeat1
  4691                              <1> 
  4692                              <1> get_env_string_seq_number_ok:
  4693 00006E80 5F                  <1> 	pop	edi ; ***
  4694 00006E81 89D0                <1> 	mov	eax, edx ; Length of the environment string
  4695                              <1> 			 ; (ASCIIZ, includes ZERO tail)
  4696 00006E83 BA00300900          <1> 	mov	edx, Env_Page
  4697                              <1> 
  4698                              <1> get_env_string_stc_retn:
  4699 00006E88 5E                  <1> 	pop	esi ; **
  4700 00006E89 59                  <1> 	pop	ecx ; *
  4701 00006E8A C3                  <1> 	retn   
  4702                              <1> 	
  4703                              <1> get_env_string_seq_number_next:
  4704 00006E8B AC                  <1> 	lodsb
  4705 00006E8C 08C0                <1> 	or	al, al
  4706 00006E8E 75FB                <1> 	jnz	short get_env_string_seq_number_next
  4707                              <1> 
  4708 00006E90 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; +512 (+4096)
  4709 00006E96 F5                  <1> 	cmc
  4710 00006E97 72EF                <1> 	jc	short get_env_string_stc_retn
  4711                              <1> 
  4712 00006E99 AC                  <1> 	lodsb
  4713 00006E9A 3C01                <1> 	cmp	al, 1
  4714 00006E9C 72EA                <1> 	jb	short get_env_string_stc_retn
  4715 00006E9E FEC1                <1> 	inc	cl
  4716 00006EA0 EBBF                <1> 	jmp	short get_env_string_seq_number_check
  4717                              <1> 
  4718                              <1> get_env_string_with_word:
  4719 00006EA2 31C9                <1> 	xor	ecx, ecx
  4720                              <1> 
  4721                              <1> get_env_string_calc_word_length:
  4722 00006EA4 AC                  <1> 	lodsb 
  4723 00006EA5 3C20                <1> 	cmp	al, 20h
  4724 00006EA7 7211                <1> 	jb	short get_env_string_calc_word_length_ok
  4725                              <1> 	;inc	cx
  4726 00006EA9 FEC1                <1> 	inc	cl
  4727                              <1> 
  4728 00006EAB 3C61                <1> 	cmp	al, 'a'
  4729 00006EAD 72F5                <1> 	jb	short get_env_string_calc_word_length
  4730 00006EAF 3C7A                <1> 	cmp	al, 'z'
  4731 00006EB1 77F1                <1> 	ja	short get_env_string_calc_word_length
  4732 00006EB3 24DF                <1> 	and	al, 0DFh
  4733 00006EB5 8846FF              <1> 	mov	[esi-1], al
  4734 00006EB8 EBEA                <1> 	jmp	short get_env_string_calc_word_length
  4735                              <1> 	
  4736                              <1> get_env_string_calc_word_length_ok:
  4737 00006EBA 08C9                <1> 	or	cl, cl
  4738 00006EBC 7506                <1> 	jnz	short get_env_string_calc_word_length_save
  4739                              <1>      
  4740 00006EBE 5E                  <1> 	pop	esi ; **
  4741                              <1> 
  4742                              <1> get_env_string_stc_retn1:
  4743 00006EBF 59                  <1> 	pop	ecx ; *
  4744                              <1>         
  4745                              <1> get_env_string_with_word_stc_retn:
  4746 00006EC0 31C0                <1> 	xor	eax, eax  
  4747 00006EC2 F9                  <1> 	stc
  4748 00006EC3 C3                  <1> 	retn
  4749                              <1>   
  4750                              <1> get_env_string_calc_word_length_save:
  4751 00006EC4 871C24              <1> 	xchg	ebx, [esp] ; **
  4752 00006EC7 89DE                <1> 	mov	esi, ebx 
  4753                              <1> 		; Start of the env string (to be searched)
  4754                              <1> 
  4755 00006EC9 57                  <1> 	push	edi ; ***
  4756 00006ECA 89D7                <1> 	mov	edi, edx ; Env_Page
  4757                              <1> 
  4758                              <1> get_env_string_compare:
  4759 00006ECC 57                  <1> 	push	edi ; ****
  4760 00006ECD 51                  <1> 	push	ecx ; ***** ; Variable name length
  4761                              <1> 
  4762                              <1> get_env_string_compare_rep:
  4763 00006ECE AC                  <1> 	lodsb
  4764 00006ECF AE                  <1> 	scasb
  4765 00006ED0 7511                <1> 	jne	short get_env_string_compare_next1
  4766 00006ED2 E2FA                <1> 	loop	get_env_string_compare_rep
  4767                              <1> 	
  4768 00006ED4 803F3D              <1> 	cmp	byte [edi], '='
  4769 00006ED7 750A                <1> 	jne	short get_env_string_compare_next1
  4770                              <1>  
  4771 00006ED9 59                  <1> 	pop	ecx ; *****
  4772 00006EDA 5F                  <1> 	pop	edi ; ****
  4773 00006EDB 89FE                <1> 	mov	esi, edi
  4774 00006EDD 5F                  <1> 	pop	edi ; ***
  4775 00006EDE 871C24              <1> 	xchg	ebx, [esp] ; **
  4776 00006EE1 EB82                <1> 	jmp	short get_env_string_move_to_buff
  4777                              <1> 
  4778                              <1> get_env_string_compare_next1:
  4779 00006EE3 89FE                <1> 	mov	esi, edi
  4780 00006EE5 59                  <1> 	pop	ecx ; *****
  4781 00006EE6 5F                  <1> 	pop	edi ; ****
  4782                              <1> get_env_string_compare_next2:
  4783 00006EE7 81FEFF310900        <1> 	cmp	esi, Env_Page + Env_Page_Size - 1 ; +511 (+4095)
  4784 00006EED 7310                <1> 	jnb	short get_env_string_compare_not_ok
  4785 00006EEF 20C0                <1> 	and	al, al
  4786 00006EF1 AC                  <1> 	lodsb
  4787 00006EF2 75F3                <1> 	jnz	short get_env_string_compare_next2
  4788 00006EF4 08C0                <1> 	or	al, al
  4789 00006EF6 7407                <1> 	jz	short get_env_string_compare_not_ok
  4790 00006EF8 4E                  <1> 	dec	esi ; 12/04/2016
  4791 00006EF9 89F7                <1> 	mov	edi, esi
  4792 00006EFB 89DE                <1> 	mov	esi, ebx
  4793 00006EFD EBCD                <1> 	jmp	short get_env_string_compare
  4794                              <1> 
  4795                              <1> get_env_string_compare_not_ok:
  4796 00006EFF 5F                  <1> 	pop	edi ; ***
  4797 00006F00 89DE                <1> 	mov	esi, ebx
  4798 00006F02 5B                  <1> 	pop	ebx ; **
  4799 00006F03 EBBA                <1> 	jmp	short get_env_string_stc_retn1
  4800                              <1> 
  4801                              <1> set_environment_string:
  4802                              <1> 	; 13/04/2016
  4803                              <1> 	; 12/04/2016
  4804                              <1> 	; 11/04/2016
  4805                              <1> 	; 06/04/2016
  4806                              <1> 	; 05/04/2016 (TRDOS 386 = TRDOS v2.0)
  4807                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4808                              <1> 	; 29/08/2011
  4809                              <1> 	; 29/08/2011
  4810                              <1> 	; INPUT->
  4811                              <1> 	;	ESI = ASCIIZ environment string
  4812                              <1> 	; OUTPUT ->
  4813                              <1> 	;	ESI is not changed
  4814                              <1> 	;	CF = 1 -> Could not set, 
  4815                              <1> 	;	     insufficient environment space
  4816                              <1> 	;
  4817                              <1> 	; (EAX, EDX will be changed) 
  4818                              <1> 	;
  4819                              <1> 	;    (EAX = Start address of the env string if > 0)	
  4820                              <1> 	;    (EDX = Environment string length)	
  4821                              <1> 
  4822 00006F05 56                  <1> 	push 	esi ; *
  4823                              <1> 
  4824 00006F06 31C0                <1> 	xor	eax, eax
  4825                              <1> 
  4826                              <1> set_env_chk_validation1:
  4827 00006F08 FEC4                <1> 	inc	ah ; variable (string) length
  4828 00006F0A AC                  <1> 	lodsb
  4829 00006F0B 3C3D                <1> 	cmp	al, '='
  4830 00006F0D 7415                <1> 	je	short set_env_chk_validation2
  4831 00006F0F 3C20                <1> 	cmp	al, 20h
  4832 00006F11 720F                <1> 	jb	short set_env_string_stc
  4833                              <1> 
  4834                              <1> 	; 06/04/2016
  4835 00006F13 3C61                <1> 	cmp	al, 'a'
  4836 00006F15 72F1                <1> 	jb	short set_env_chk_validation1
  4837 00006F17 3C7A                <1> 	cmp	al, 'z'
  4838 00006F19 77ED                <1> 	ja	short set_env_chk_validation1
  4839 00006F1B 2C20                <1> 	sub	al, 'a'-'A'
  4840 00006F1D 8846FF              <1> 	mov	[esi-1], al
  4841 00006F20 EBE6                <1> 	jmp	short set_env_chk_validation1
  4842                              <1> 
  4843                              <1> set_env_string_stc:
  4844 00006F22 5E                  <1> 	pop	esi ; *
  4845                              <1> 	;stc
  4846 00006F23 C3                  <1> 	retn 
  4847                              <1> 	   
  4848                              <1> set_env_chk_validation2:
  4849 00006F24 51                  <1> 	push	ecx ; **
  4850 00006F25 53                  <1> 	push	ebx ; *** 
  4851 00006F26 57                  <1> 	push	edi ; ****
  4852                              <1> 
  4853                              <1> 	; 12/04/2016
  4854 00006F27 8B5C240C            <1> 	mov	ebx, [esp+12]
  4855                              <1> 
  4856                              <1> set_env_chk_validation2w:
  4857 00006F2B 89F7                <1> 	mov	edi, esi
  4858 00006F2D 4F                  <1> 	dec	edi
  4859                              <1> 
  4860 00006F2E 807FFF20            <1> 	cmp	byte [edi-1], 20h
  4861 00006F32 771A                <1> 	ja	short set_env_chk_validation2z
  4862                              <1> 	
  4863 00006F34 56                  <1> 	push	esi
  4864 00006F35 89FE                <1> 	mov	esi, edi
  4865 00006F37 4E                  <1> 	dec	esi
  4866                              <1> 
  4867                              <1> set_env_chk_validation2x:
  4868 00006F38 4E                  <1> 	dec	esi
  4869                              <1> 
  4870 00006F39 39DE                <1> 	cmp	esi, ebx
  4871 00006F3B 7207                <1> 	jb	short set_env_chk_validation2y
  4872                              <1> 
  4873 00006F3D 4F                  <1> 	dec	edi
  4874                              <1> 
  4875 00006F3E 8A06                <1> 	mov	al, [esi]
  4876 00006F40 8807                <1> 	mov	[edi], al
  4877                              <1> 
  4878 00006F42 EBF4                <1> 	jmp	short set_env_chk_validation2x
  4879                              <1> 
  4880                              <1> set_env_chk_validation2y:
  4881 00006F44 5E                  <1> 	pop	esi
  4882                              <1> 
  4883                              <1> 	;mov	byte [ebx], 20h
  4884                              <1> 	
  4885 00006F45 43                  <1> 	inc 	ebx
  4886 00006F46 895C240C            <1> 	mov	[esp+12], ebx
  4887                              <1> 
  4888 00006F4A FECC                <1> 	dec 	ah ; 13/04/2016
  4889                              <1> 
  4890 00006F4C EBDD                <1> 	jmp	short set_env_chk_validation2w
  4891                              <1> 	
  4892                              <1> set_env_chk_validation2z:	
  4893 00006F4E BA00300900          <1> 	mov	edx, Env_Page
  4894 00006F53 89D7                <1> 	mov	edi, edx
  4895                              <1> 
  4896                              <1> set_env_chk_validation3:
  4897 00006F55 AC                  <1> 	lodsb
  4898 00006F56 3C20                <1> 	cmp	al, 20h
  4899 00006F58 74FB                <1> 	je	short set_env_chk_validation3
  4900                              <1> 
  4901 00006F5A 9C                  <1> 	pushf
  4902                              <1> 
  4903                              <1> 	; 12/04/2016
  4904                              <1> set_env_chk_validation3n:
  4905 00006F5B 3C61                <1> 	cmp	al, 'a'
  4906 00006F5D 720C                <1> 	jb	short set_env_chk_validation3c
  4907 00006F5F 3C7A                <1> 	cmp	al, 'z'
  4908 00006F61 7705                <1> 	ja	short set_env_chk_validation3x
  4909 00006F63 2C20                <1> 	sub	al, 'a'-'A'
  4910 00006F65 8846FF              <1> 	mov	[esi-1], al
  4911                              <1> 
  4912                              <1> set_env_chk_validation3x:
  4913 00006F68 AC                  <1> 	lodsb
  4914 00006F69 EBF0                <1> 	jmp	short set_env_chk_validation3n
  4915                              <1> 
  4916                              <1> set_env_chk_validation3c:
  4917 00006F6B 3C20                <1> 	cmp	al, 20h
  4918 00006F6D 73F9                <1> 	jnb	short set_env_chk_validation3x
  4919                              <1> 		
  4920 00006F6F 803F00              <1> 	cmp	byte [edi], 0
  4921 00006F72 7731                <1> 	ja	short set_env_chk_validation4
  4922                              <1> 
  4923 00006F74 9D                  <1> 	popf
  4924 00006F75 7228                <1> 	jb	short set_env_string_nothing
  4925                              <1> 
  4926 00006F77 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)
  4927                              <1> 
  4928 00006F7C 89DE                <1> 	mov	esi, ebx ; 12/04/2016
  4929                              <1> 
  4930                              <1> set_env_string_copy_to_envb:
  4931 00006F7E AC                  <1> 	lodsb
  4932 00006F7F 3C20                <1> 	cmp	al, 20h
  4933 00006F81 720A                <1> 	jb	short set_env_string_copy_to_envb_z
  4934 00006F83 AA                  <1> 	stosb
  4935 00006F84 E2F8                <1> 	loop	set_env_string_copy_to_envb
  4936                              <1> 
  4937                              <1> 	; 11/04/2016
  4938 00006F86 89D7                <1> 	mov	edi, edx ; Env_Page
  4939 00006F88 B900020000          <1> 	mov	ecx, Env_Page_Size 
  4940                              <1> 
  4941                              <1> set_env_string_copy_to_envb_z:
  4942 00006F8D 52                  <1> 	push	edx  ; Start address of the variable
  4943 00006F8E BA00020000          <1> 	mov	edx, Env_Page_Size
  4944 00006F93 29CA                <1> 	sub	edx, ecx ; variable (string) length
  4945                              <1> 
  4946 00006F95 28C0                <1> 	sub	al, al ; 0
  4947 00006F97 F3AA                <1>  	rep	stosb ; clear remain bytes of the env page
  4948                              <1> 
  4949 00006F99 58                  <1> 	pop	eax  ; Start address of the variable
  4950                              <1> 
  4951                              <1> set_env_string_allocate_envb_retn:  ; stc or clc return
  4952 00006F9A 5F                  <1> 	pop	edi ; ****
  4953 00006F9B 5B                  <1> 	pop	ebx ; ***
  4954 00006F9C 59                  <1> 	pop	ecx ; **
  4955 00006F9D 5E                  <1> 	pop	esi ; *	
  4956 00006F9E C3                  <1> 	retn
  4957                              <1> 
  4958                              <1> set_env_string_nothing:
  4959 00006F9F 31C0                <1> 	xor	eax, eax
  4960 00006FA1 31D2                <1> 	xor	edx, edx ; 11/04/2016
  4961 00006FA3 EBF5                <1> 	jmp	short set_env_string_allocate_envb_retn
  4962                              <1> 
  4963                              <1> set_env_chk_validation4:
  4964                              <1> 	; 11/04/2016
  4965 00006FA5 9D                  <1> 	popf
  4966                              <1> 
  4967 00006FA6 89D6                <1> 	mov	esi, edx  ; Env_Page
  4968                              <1> 
  4969                              <1> set_env_chk_validation5:	
  4970 00006FA8 89DF                <1> 	mov	edi, ebx  ; ASCIIZ environment string address	
  4971 00006FAA 0FB6CC              <1> 	movzx	ecx, ah ; Variable (string) length (with '=')
  4972                              <1> 
  4973                              <1> set_env_chk_validation5_loop:
  4974 00006FAD AC                  <1> 	lodsb
  4975 00006FAE AE                  <1> 	scasb
  4976 00006FAF 750A                <1> 	jne	short set_env_chk_validation6
  4977 00006FB1 E2FA                <1> 	loop	set_env_chk_validation5_loop
  4978                              <1> 
  4979 00006FB3 3C3D                <1> 	cmp	al, '='
  4980 00006FB5 0F8483000000        <1>         je      set_env_change_variable
  4981                              <1> 
  4982                              <1> set_env_chk_validation6:
  4983 00006FBB 08C0                <1> 	or	al, al ; 0
  4984 00006FBD 7403                <1> 	jz	short set_env_chk_validation7
  4985                              <1> 
  4986 00006FBF AC                  <1> 	lodsb
  4987 00006FC0 EBF9                <1> 	jmp	short set_env_chk_validation6
  4988                              <1> 
  4989                              <1> set_env_chk_validation7:
  4990 00006FC2 88E1                <1> 	mov	cl, ah
  4991 00006FC4 01F1                <1> 	add	ecx, esi
  4992 00006FC6 81F9FF310900        <1> 	cmp	ecx, Env_Page + Env_Page_Size - 1 
  4993                              <1> 		; 511 (4095) 
  4994                              <1> 		; strlen + '=' + 0
  4995 00006FCC 72DA                <1> 	jb	short set_env_chk_validation5
  4996                              <1> 
  4997                              <1> set_env_chk_validation8: ; variable not found
  4998 00006FCE 0FB6F4              <1> 	movzx	esi, ah  ; variable name length (with '=') 
  4999 00006FD1 01DE                <1> 	add	esi, ebx ; position just after of the '='
  5000                              <1> 
  5001                              <1> set_env_chk_validation8_loop:
  5002 00006FD3 AC                  <1> 	lodsb
  5003 00006FD4 3C20                <1> 	cmp	al, 20h
  5004 00006FD6 74FB                <1> 	je	short set_env_chk_validation8_loop	
  5005 00006FD8 72C5                <1> 	jb	short set_env_string_nothing
  5006                              <1> 
  5007                              <1> set_env_chk_validation9:
  5008 00006FDA AC                  <1> 	lodsb
  5009 00006FDB 3C20                <1> 	cmp	al, 20h
  5010 00006FDD 73FB                <1> 	jnb	short set_env_chk_validation9
  5011                              <1> 
  5012                              <1> 	; End of ASCIIZ environment string
  5013                              <1> 
  5014                              <1> set_env_add_variable:
  5015 00006FDF 29DE                <1> 	sub	esi, ebx ; variable+definition length
  5016                              <1> 	
  5017 00006FE1 56                  <1> 	push	esi ; *****
  5018                              <1> 
  5019 00006FE2 89D6                <1> 	mov	esi, edx ; Environment page address
  5020                              <1> 
  5021 00006FE4 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)	
  5022                              <1> 
  5023                              <1> set_env_add_variable_loop:
  5024 00006FE9 AC                  <1> 	lodsb
  5025 00006FEA 20C0                <1> 	and	al, al		
  5026 00006FEC 7406                <1> 	jz	short set_env_add_variable_chk1 ; 0
  5027 00006FEE E2F9                <1> 	loop	set_env_add_variable_loop
  5028                              <1> 
  5029                              <1> 	; 11/04/2016
  5030 00006FF0 884EFF              <1> 	mov	[esi-1], cl ; 0
  5031 00006FF3 41                  <1> 	inc	ecx
  5032                              <1> 	
  5033                              <1> set_env_add_variable_chk1: 
  5034 00006FF4 49                  <1> 	dec	ecx
  5035 00006FF5 7408                <1> 	jz	short set_env_add_variable_nspc
  5036 00006FF7 AC                  <1> 	lodsb
  5037 00006FF8 08C0                <1> 	or 	al, al
  5038 00006FFA 740C                <1> 	jz	short set_env_add_variable_chk2 ; 00
  5039 00006FFC 49                  <1> 	dec	ecx
  5040 00006FFD 75EA                <1> 	jnz	short set_env_add_variable_loop
  5041                              <1> 
  5042                              <1> set_env_add_variable_nspc: ; no space on environment page
  5043 00006FFF 58                  <1> 	pop	eax ; *****
  5044 00007000 B808000000          <1> 	mov	eax, 08h ; No space for new environment string
  5045 00007005 F9                  <1> 	stc
  5046 00007006 EB92                <1>         jmp     short set_env_string_allocate_envb_retn
  5047                              <1> 
  5048                              <1> set_env_add_variable_chk2:
  5049 00007008 8B0C24              <1> 	mov	ecx, [esp] ; *****
  5050 0000700B 4E                  <1> 	dec	esi ; beginning address of the new variable
  5051 0000700C 89F0                <1> 	mov	eax, esi
  5052 0000700E 01C8                <1> 	add	eax, ecx ; string length (with CR)
  5053 00007010 81C200020000        <1> 	add	edx, Env_Page_Size ; 512 (4096)
  5054 00007016 39D0                <1> 	cmp	eax, edx 
  5055 00007018 77E5                <1> 	ja	short set_env_add_variable_nspc
  5056 0000701A 49                  <1> 	dec	ecx ; except CR at the end
  5057 0000701B 89CA                <1> 	mov	edx, ecx ; 12/04/2016
  5058 0000701D 89F7                <1> 	mov	edi, esi
  5059 0000701F 893C24              <1> 	mov	[esp], edi ; ***** ; Start address of new variable
  5060 00007022 89DE                <1> 	mov	esi, ebx ; ASCIIZ environment string address
  5061 00007024 F3A4                <1> 	rep	movsb
  5062 00007026 28C0                <1> 	sub	al, al
  5063 00007028 AA                  <1> 	stosb
  5064 00007029 58                  <1> 	pop	eax ; ***** ; Beginning address of new variable			
  5065 0000702A 81FF00320900        <1>         cmp     edi, Env_Page + Env_Page_Size ; 12/04/2016
  5066 00007030 0F8364FFFFFF        <1>         jnb     set_env_string_allocate_envb_retn ; OK !
  5067 00007036 880F                <1> 	mov	[edi], cl ; 0
  5068 00007038 F8                  <1> 	clc	; 13/04/2016
  5069 00007039 E95CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5070                              <1> 
  5071                              <1> set_env_change_variable:
  5072                              <1> 	; 06/04/2016
  5073                              <1> 	; esi = Variable's address in environment page (after '=')
  5074                              <1> 	; edi = ASCIIZ environment string address (after '=')
  5075                              <1> 
  5076                              <1> 	; ah = variable length from start to the '='
  5077 0000703E 8825[0CDC0000]      <1> 	mov	[env_var_length], ah
  5078                              <1> 
  5079 00007044 28C9                <1> 	sub	cl, cl ; ecx = 0
  5080                              <1> 
  5081 00007046 57                  <1> 	push	edi ; *****
  5082                              <1> 
  5083 00007047 89F7                <1> 	mov	edi, esi ; 11/04/2016
  5084                              <1> 
  5085                              <1> set_env_change_variable_calc1:
  5086 00007049 AC                  <1> 	lodsb
  5087 0000704A 08C0                <1> 	or	al, al
  5088 0000704C 7403                <1> 	jz	short set_env_change_variable_calc2
  5089                              <1> 
  5090 0000704E 41                  <1> 	inc	ecx ; length of environment string (after the '=')
  5091                              <1> 
  5092 0000704F EBF8                <1> 	jmp	short set_env_change_variable_calc1	
  5093                              <1> 
  5094                              <1> set_env_change_variable_calc2:
  5095 00007051 8B3424              <1> 	mov	esi, [esp] ; ASCIIZ environment string address
  5096                              <1> 	
  5097 00007054 29D2                <1> 	sub	edx, edx
  5098                              <1> 
  5099                              <1> set_env_change_variable_calc3:
  5100 00007056 AC                  <1> 	lodsb
  5101 00007057 3C20                <1> 	cmp	al, 20h
  5102 00007059 7203                <1> 	jb	short set_env_change_variable_calc4
  5103                              <1> 
  5104 0000705B 42                  <1> 	inc	edx ; length of ASCIIZ string (after the '=')
  5105                              <1> 	
  5106 0000705C EBF8                <1> 	jmp	short set_env_change_variable_calc3
  5107                              <1> 	
  5108                              <1> set_env_change_variable_calc4:
  5109 0000705E C646FF00            <1> 	mov	byte [esi-1], 0  ; put ZERO instead of CR
  5110                              <1> 	
  5111 00007062 5E                  <1> 	pop	esi ; ***** ; ASCIIZ string address (after '=')
  5112                              <1> 
  5113                              <1> 	; EDI = Old variable's address (after '=')
  5114                              <1> 	
  5115                              <1> 	; compare the new string with the old string
  5116 00007063 39CA                <1> 	cmp	edx, ecx
  5117 00007065 7717                <1> 	ja	short set_env_change_variable_calc5 ; longer
  5118 00007067 0F828F000000        <1>         jb      set_env_change_variable_calc9 ; shorter
  5119                              <1> 	
  5120                              <1> 	;same length (simple copy)
  5121 0000706D 0FB6C4              <1> 	movzx	eax, ah
  5122 00007070 01C2                <1> 	add	edx, eax
  5123 00007072 F7D8                <1> 	neg	eax
  5124 00007074 01F8                <1> 	add	eax, edi
  5125                              <1> 	; EAX = Start address of the variable
  5126                              <1> 	; EDX = Variable length (without ZERO at the end of variable)
  5127                              <1> 
  5128 00007076 F3A4                <1> 	rep	movsb
  5129 00007078 F8                  <1> 	clc	; 13/04/2016
  5130 00007079 E91CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5131                              <1> 
  5132                              <1> set_env_change_variable_calc5:
  5133                              <1> 	; 11/04/2016
  5134 0000707E 52                  <1> 	push	edx ; *****
  5135 0000707F 29CA                <1> 	sub	edx, ecx ; difference ; (the new string is longer)
  5136 00007081 89F3                <1> 	mov 	ebx, esi
  5137 00007083 89FE                <1> 	mov	esi, edi
  5138                              <1> 
  5139                              <1> set_env_change_variable_calc6:
  5140 00007085 AC                  <1> 	lodsb 
  5141 00007086 20C0                <1> 	and	al, al
  5142 00007088 75FB                <1> 	jnz	short set_env_change_variable_calc6
  5143                              <1> 
  5144 0000708A 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5145 00007090 0F8369FFFFFF        <1>         jnb     set_env_add_variable_nspc
  5146                              <1> 
  5147 00007096 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5148 00007098 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5149                              <1> 
  5150 0000709A AC                  <1> 	lodsb
  5151 0000709B 08C0                <1> 	or	al, al
  5152 0000709D 7416                <1> 	jz	short set_env_change_variable_calc8 ; 00
  5153                              <1> 
  5154                              <1> set_env_change_variable_calc7:
  5155 0000709F AC                  <1> 	lodsb
  5156 000070A0 20C0                <1> 	and	al, al
  5157 000070A2 75FB                <1> 	jnz	short set_env_change_variable_calc7
  5158                              <1> 
  5159 000070A4 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5160 000070AA 0F834FFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5161                              <1> 
  5162 000070B0 AC                  <1> 	lodsb
  5163 000070B1 08C0                <1> 	or	al, al
  5164 000070B3 75EA                <1> 	jnz	short set_env_change_variable_calc7
  5165                              <1> 
  5166                              <1> set_env_change_variable_calc8:
  5167 000070B5 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5168                              <1> 
  5169 000070B6 01F2                <1> 	add	edx, esi ; final position of the last 0
  5170                              <1> 
  5171 000070B8 81FA00320900        <1> 	cmp	edx, Env_Page + Env_Page_Size ; 512 (4096)
  5172 000070BE 0F833BFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5173                              <1> 
  5174 000070C4 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5175                              <1> 
  5176 000070C6 89F1                <1> 	mov	ecx, esi 
  5177 000070C8 29F9                <1> 	sub	ecx, edi ; count of bytes to move forward
  5178                              <1> 
  5179                              <1> 	; 13/04/2016
  5180 000070CA C60200              <1> 	mov	byte [edx], 0
  5181 000070CD 89D7                <1> 	mov	edi, edx
  5182 000070CF 29F2                <1> 	sub	edx, esi ; difference (additional byte count)
  5183 000070D1 4F                  <1> 	dec	edi ; the last zero address (first byte of the 00)
  5184 000070D2 89FE                <1> 	mov	esi, edi
  5185 000070D4 29D6                <1> 	sub	esi, edx ; - displacement
  5186                              <1> 	
  5187 000070D6 FA                  <1> 	cli	; disable interrupts
  5188 000070D7 FD                  <1> 	std	; backward
  5189                              <1> 
  5190 000070D8 F3A4                <1> 	rep	movsb ; move ECX bytes from DS:ESI to ES:EDI
  5191                              <1> 
  5192 000070DA FC                  <1> 	cld	; forward (default)
  5193 000070DB FB                  <1> 	sti	; enable interrupts
  5194                              <1> 	
  5195 000070DC 89C7                <1> 	mov	edi, eax
  5196 000070DE 59                  <1> 	pop	ecx ; ***** ; byte count (after '=')
  5197 000070DF 89CA                <1> 	mov	edx, ecx
  5198 000070E1 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5199 000070E3 89FB                <1> 	mov	ebx, edi
  5200                              <1> 
  5201 000070E5 F3A4                <1> 	rep	movsb
  5202                              <1> 
  5203 000070E7 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5204                              <1> 
  5205 000070E9 0FB605[0CDC0000]    <1> 	movzx	eax, byte [env_var_length]
  5206 000070F0 01C2                <1> 	add	edx, eax ; variable length (total)
  5207 000070F2 F7D8                <1> 	neg	eax
  5208 000070F4 01D8                <1> 	add	eax, ebx ; start address of the variable
  5209 000070F6 F8                  <1> 	clc	; 13/04/2016
  5210 000070F7 E99EFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5211                              <1> 
  5212                              <1> set_env_change_variable_calc9:
  5213                              <1> 	; 11/04/2016
  5214 000070FC 21D2                <1> 	and	edx, edx ; is empty ?
  5215 000070FE 753B                <1> 	jnz	short set_env_change_variable_calc15
  5216                              <1> 	
  5217 00007100 0FB6DC              <1> 	movzx	ebx, ah
  5218 00007103 F7DB                <1> 	neg	ebx
  5219 00007105 01FB                <1> 	add	ebx, edi
  5220                              <1> 
  5221                              <1> 	; EBX = Start address of the variable (in env page)
  5222                              <1> 	; EDX = Variable length = 0
  5223                              <1> 	
  5224 00007107 89FE                <1> 	mov	esi, edi
  5225                              <1> 
  5226                              <1> set_env_change_variable_calc10:
  5227 00007109 AC                  <1> 	lodsb
  5228 0000710A 08C0                <1> 	or	al, al
  5229 0000710C 75FB                <1> 	jnz	short set_env_change_variable_calc10
  5230                              <1> 
  5231 0000710E B9FF310900          <1> 	mov	ecx, Env_Page + Env_Page_Size - 1
  5232                              <1> 
  5233 00007113 39CE                <1> 	cmp	esi, ecx ; +511 (+4095)
  5234 00007115 7604                <1> 	jna	short set_env_change_variable_calc11
  5235                              <1> 
  5236 00007117 89CE                <1> 	mov	esi, ecx
  5237 00007119 8806                <1> 	mov	[esi], al ; 0
  5238                              <1> 
  5239                              <1> set_env_change_variable_calc11:
  5240 0000711B 89DF                <1> 	mov	edi, ebx ; old variable's start address
  5241                              <1> 
  5242                              <1> set_env_change_variable_calc12:
  5243 0000711D AC                  <1> 	lodsb
  5244 0000711E AA                  <1> 	stosb
  5245 0000711F 20C0                <1> 	and	al, al
  5246 00007121 75FA                <1> 	jnz	short set_env_change_variable_calc12
  5247 00007123 39CE                <1> 	cmp	esi, ecx
  5248 00007125 7706                <1> 	ja	short set_env_change_variable_calc13
  5249 00007127 AC                  <1> 	lodsb
  5250 00007128 AA                  <1> 	stosb
  5251 00007129 20C0                <1> 	and	al, al
  5252 0000712B 75F0                <1> 	jnz	short set_env_change_variable_calc12	
  5253                              <1> 
  5254                              <1> set_env_change_variable_calc13:
  5255 0000712D 29F9                <1> 	sub	ecx, edi
  5256 0000712F 7203                <1> 	jb	short set_env_change_variable_calc14
  5257 00007131 41                  <1> 	inc	ecx ; 1-512 (1-4096)
  5258 00007132 F3AA                <1> 	rep	stosb ; al = 0	
  5259                              <1> 
  5260                              <1> set_env_change_variable_calc14:
  5261 00007134 29C0                <1> 	sub	eax, eax ; Start address of the variable
  5262                              <1> 	; EAX = 0 -> Variable is removed
  5263                              <1> 	; EDX = Variable length = 0	
  5264                              <1> 
  5265 00007136 E95FFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5266                              <1> 	    
  5267                              <1> set_env_change_variable_calc15:	
  5268 0000713B 52                  <1> 	push	edx ; *****
  5269 0000713C F7DA                <1> 	neg	edx
  5270 0000713E 01CA                <1> 	add	edx, ecx ; difference (the old string is longer)
  5271 00007140 89F3                <1> 	mov 	ebx, esi
  5272 00007142 89FE                <1> 	mov	esi, edi
  5273                              <1> 
  5274                              <1> set_env_change_variable_calc16:
  5275 00007144 AC                  <1> 	lodsb 
  5276 00007145 20C0                <1> 	and	al, al
  5277 00007147 75FB                <1> 	jnz	short set_env_change_variable_calc16
  5278                              <1> 
  5279 00007149 B900320900          <1> 	mov	ecx, Env_Page + Env_Page_Size
  5280                              <1> 
  5281 0000714E 39CE                <1> 	cmp	esi, ecx ; +512 (+4096)
  5282 00007150 7605                <1> 	jna	short set_env_change_variable_calc17
  5283                              <1> 
  5284 00007152 89CE                <1> 	mov	esi, ecx
  5285 00007154 8846FF              <1> 	mov	[esi-1], al ; 0
  5286                              <1> 
  5287                              <1> set_env_change_variable_calc17:
  5288 00007157 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5289 00007159 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5290                              <1> 
  5291 0000715B AC                  <1> 	lodsb
  5292 0000715C 08C0                <1> 	or	al, al
  5293 0000715E 741D                <1> 	jz	short set_env_change_variable_calc20
  5294                              <1> 
  5295                              <1> set_env_change_variable_calc18:
  5296 00007160 AC                  <1> 	lodsb
  5297 00007161 20C0                <1> 	and	al, al
  5298 00007163 75FB                <1> 	jnz	short set_env_change_variable_calc18
  5299                              <1> 
  5300 00007165 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size
  5301 0000716B 720B                <1> 	jb	short set_env_change_variable_calc19
  5302 0000716D 740E                <1> 	je	short set_env_change_variable_calc20
  5303                              <1> 
  5304 0000716F BEFF310900          <1> 	mov	esi, Env_Page + Env_Page_Size - 1
  5305 00007174 8806                <1> 	mov	[esi], al ; 0
  5306 00007176 EB06                <1> 	jmp	short set_env_change_variable_calc21
  5307                              <1> 
  5308                              <1> set_env_change_variable_calc19:
  5309 00007178 AC                  <1> 	lodsb
  5310 00007179 08C0                <1> 	or	al, al
  5311 0000717B 75E3                <1> 	jnz	short set_env_change_variable_calc18
  5312                              <1> 
  5313                              <1> set_env_change_variable_calc20:
  5314 0000717D 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5315                              <1> 
  5316                              <1> set_env_change_variable_calc21:
  5317                              <1> 	; edx = difference (byte count)
  5318                              <1> 	
  5319 0000717E 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5320                              <1> 
  5321 00007180 89F1                <1> 	mov	ecx, esi 
  5322 00007182 29F9                <1> 	sub	ecx, edi ; count of bytes to move backward
  5323                              <1> 
  5324 00007184 89FE                <1> 	mov	esi, edi ; next variable's address
  5325 00007186 29D7                <1> 	sub	edi, edx ; (displacement)
  5326                              <1> 	
  5327 00007188 F3A4                <1> 	rep	movsb
  5328                              <1> 
  5329 0000718A 880F                <1> 	mov	[edi], cl ; 0 ; 00 ; end of environment variables
  5330                              <1> 
  5331 0000718C 89C7                <1> 	mov	edi, eax
  5332 0000718E 5A                  <1> 	pop	edx ; ***** ; byte count (after '=')
  5333 0000718F 89D1                <1> 	mov	ecx, edx
  5334 00007191 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5335 00007193 89FB                <1> 	mov	ebx, edi
  5336                              <1> 	
  5337 00007195 F3A4                <1> 	rep	movsb
  5338                              <1> 
  5339 00007197 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5340                              <1> 
  5341 00007199 0FB605[0CDC0000]    <1> 	movzx	eax, byte [env_var_length]
  5342 000071A0 01C2                <1> 	add	edx, eax ; variable length (total)
  5343 000071A2 F7D8                <1> 	neg	eax
  5344 000071A4 01D8                <1> 	add	eax, ebx ; start address of the variable
  5345 000071A6 F8                  <1> 	clc	; 13/04/2016
  5346 000071A7 E9EEFDFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5347                              <1> 
  5348                              <1> mainprog_startup_configuration:
  5349                              <1> 	; 06/05/2016
  5350                              <1> 	; 14/04/2016 (TRDOS 386 = TRDOS v2.0)
  5351                              <1> 	; 17/09/2011 (TRDOS v1, MAINPROG.ASM)
  5352                              <1> 	;
  5353                              <1> loc_load_mainprog_cfg_file:
  5354 000071AC BE[0CBE0000]        <1> 	mov	esi, MainProgCfgFile
  5355 000071B1 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5356 000071B5 E8FFE9FFFF          <1> 	call	find_first_file
  5357 000071BA 7256                <1> 	jc	short loc_load_mainprog_cfg_exit
  5358                              <1> 
  5359                              <1> 	;or	eax, eax
  5360                              <1> 	;jz	short loc_load_mainprog_cfg_exit
  5361                              <1> 
  5362                              <1> loc_start_mainprog_configuration:
  5363                              <1> 	; ESI = FindFile_DirEntry Location
  5364                              <1> 	; EAX = File Size
  5365                              <1> 
  5366 000071BC A3[90CF0000]        <1> 	mov	[MainProgCfg_FileSize], eax
  5367                              <1> 
  5368 000071C1 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  5369 000071C5 C1E210              <1> 	shl	edx, 16
  5370 000071C8 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  5371 000071CC 8915[C0DB0000]      <1> 	mov	[csftdf_sf_cluster], edx
  5372                              <1> 
  5373 000071D2 89C1                <1> 	mov	ecx, eax
  5374 000071D4 29C0                <1> 	sub	eax, eax
  5375                              <1> 
  5376                              <1> 	; TRDOS 386 (TRDOS v2.0)
  5377                              <1> 	; Allocate contiguous memory block for loading the file
  5378                              <1> 	
  5379                              <1> 	; eax = 0 (Allocate memory from the beginning)
  5380                              <1> 	; ecx = File (Allocation) size in bytes
  5381                              <1> 	
  5382 000071D6 E820C7FFFF          <1> 	call	allocate_memory_block
  5383 000071DB 7235                <1> 	jc	short loc_load_mainprog_cfg_exit
  5384                              <1> 
  5385 000071DD A3[B8DB0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  5386 000071E2 890D[BCDB0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  5387                              <1> 
  5388 000071E8 31DB                <1> 	xor	ebx, ebx
  5389                              <1> 	;mov	[csftdf_sf_rbytes], ebx ; 0, reset
  5390                              <1> 
  5391 000071EA 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv] ; [FindFile_Drv]
  5392 000071F0 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5393 000071F5 01DE                <1> 	add	esi, ebx
  5394                              <1> 
  5395 000071F7 8B1D[B8DB0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  5396                              <1> 
  5397 000071FD 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5398 00007201 7710                <1>         ja	short loc_mcfg_load_fat_file
  5399                              <1> 
  5400 00007203 C705[C8DB0000]0000- <1> 	mov	dword [csftdf_r_size], 65536
  5400 0000720B 0100                <1>
  5401 0000720D E992010000          <1>         jmp     loc_mcfg_load_fs_file
  5402                              <1> 
  5403                              <1> loc_load_mainprog_cfg_exit:
  5404 00007212 C3                  <1> 	retn 
  5405                              <1> 
  5406                              <1> loc_mcfg_load_fat_file:
  5407 00007213 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  5408 00007217 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  5409 0000721B F7E1                <1> 	mul	ecx
  5410 0000721D A3[C8DB0000]        <1> 	mov	[csftdf_r_size], eax
  5411                              <1> 
  5412                              <1> loc_mcfg_load_fat_file_next:
  5413 00007222 E813010000          <1> 	call	mcfg_read_fat_file_sectors
  5414 00007227 0F82F7000000        <1>         jc      mcfg_deallocate_mem
  5415                              <1> 
  5416 0000722D 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  5417 0000722F 74F1                <1> 	jz	short loc_mcfg_load_fat_file_next
  5418                              <1> 
  5419                              <1> loc_mcfg_load_fat_file_ok:
  5420                              <1> 	; 06/05/2016
  5421 00007231 C705[50DC0000]-     <1> 	mov	dword [mainprog_return_addr], loc_mcfg_ci_return_addr 
  5421 00007237 [E5720000]          <1>
  5422                              <1> 	;
  5423 0000723B 8B35[B8DB0000]      <1> 	mov	esi, [csftdf_sf_mem_addr]
  5424 00007241 8935[94CF0000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5425                              <1> 	
  5426 00007247 A1[90CF0000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5427 0000724C 89C2                <1> 	mov	edx, eax
  5428 0000724E 01F2                <1> 	add	edx, esi
  5429                              <1> 
  5430                              <1> loc_mcfg_process_next_line_check:
  5431 00007250 89C1                <1> 	mov	ecx, eax
  5432                              <1> 
  5433 00007252 803E2A              <1> 	cmp	byte [esi], "*" ; Remark sign
  5434 00007255 7503                <1> 	jne	short loc_mcfg_process_next_line
  5435 00007257 46                  <1> 	inc	esi
  5436 00007258 EB17                <1> 	jmp	short loc_move_mainprog_cfg_nl1
  5437                              <1> 
  5438                              <1> loc_mcfg_process_next_line:
  5439 0000725A 83F94F              <1> 	cmp	ecx, 79
  5440 0000725D 7605                <1> 	jna	short loc_start_mainprog_cfg_process
  5441                              <1> 	
  5442 0000725F B94F000000          <1> 	mov	ecx, 79 
  5443                              <1> 
  5444                              <1> loc_start_mainprog_cfg_process:
  5445 00007264 BF[52D00000]        <1> 	mov	edi, CommandBuffer
  5446                              <1> 
  5447                              <1> loc_move_mainprog_cfg_line:
  5448 00007269 AC                  <1> 	lodsb
  5449 0000726A 3C20                <1> 	cmp	al, 20h
  5450 0000726C 720C                <1> 	jb	short loc_move_mainprog_cfg_nl2
  5451 0000726E AA                  <1> 	stosb
  5452 0000726F E2F8                <1> 	loop	loc_move_mainprog_cfg_line
  5453                              <1> 
  5454                              <1> loc_move_mainprog_cfg_nl1:
  5455 00007271 39D6                <1> 	cmp	esi, edx ; + configuration file size
  5456 00007273 7312                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5457 00007275 AC                  <1> 	lodsb
  5458 00007276 3C20                <1> 	cmp	al, 20h
  5459 00007278 73F7                <1> 	jnb	short loc_move_mainprog_cfg_nl1
  5460                              <1> 
  5461                              <1> loc_move_mainprog_cfg_nl2:
  5462 0000727A 39D6                <1> 	cmp	esi, edx
  5463 0000727C 7309                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5464 0000727E 8A06                <1> 	mov	al, [esi]
  5465 00007280 3C20                <1> 	cmp	al, 20h
  5466 00007282 7703                <1>  	ja	short loc_end_of_mainprog_cfg_line
  5467 00007284 46                  <1> 	inc	esi
  5468 00007285 EBF3                <1> 	jmp	short loc_move_mainprog_cfg_nl2	               
  5469                              <1> 
  5470                              <1> loc_end_of_mainprog_cfg_line:
  5471 00007287 C60700              <1> 	mov	byte [edi], 0
  5472                              <1> 
  5473 0000728A 8935[94CF0000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5474                              <1> 	
  5475                              <1> loc_move_mainprog_cfg_command:
  5476 00007290 BE[52D00000]        <1> 	mov	esi, CommandBuffer
  5477 00007295 89F7                <1> 	mov	edi, esi
  5478 00007297 31DB                <1> 	xor	ebx, ebx
  5479                              <1> 	;xor	ecx, ecx
  5480 00007299 30C9                <1> 	xor	cl, cl
  5481                              <1> 
  5482                              <1> loc_move_mcfg_first_cmd_char:
  5483 0000729B 8A041E              <1> 	mov	al, [esi+ebx]
  5484 0000729E FEC3                <1> 	inc	bl 
  5485 000072A0 3C20                <1> 	cmp	al, 20h
  5486 000072A2 7712                <1> 	ja	short loc_move_mcfg_cmd_capitalizing
  5487 000072A4 7237                <1> 	jb	short loc_move_mcfg_cmd_arguments_ok
  5488 000072A6 80FB4F              <1> 	cmp	bl, 79
  5489 000072A9 72F0                <1> 	jb	short loc_move_mcfg_first_cmd_char
  5490 000072AB EB30                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5491                              <1> 
  5492                              <1> loc_move_mcfg_next_cmd_char:
  5493 000072AD 8A041E              <1> 	mov	al, [esi+ebx]
  5494 000072B0 FEC3                <1> 	inc	bl
  5495 000072B2 3C20                <1> 	cmp	al, 20h
  5496 000072B4 7614                <1> 	jna	short loc_move_mcfg_cmd_ok
  5497                              <1> 
  5498                              <1> loc_move_mcfg_cmd_capitalizing:
  5499 000072B6 3C61                <1> 	cmp	al, 61h ; 'a'
  5500 000072B8 7206                <1> 	jb	short loc_move_mcfg_cmd_caps_ok
  5501 000072BA 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  5502 000072BC 7702                <1> 	ja	short loc_move_mcfg_cmd_caps_ok
  5503 000072BE 24DF                <1> 	and	al, 0DFh ; sub	al, 'a'-'A'
  5504                              <1> 
  5505                              <1> loc_move_mcfg_cmd_caps_ok:
  5506 000072C0 AA                  <1> 	stosb 
  5507 000072C1 FEC1                <1> 	inc	cl
  5508 000072C3 80FB4F              <1> 	cmp	bl, 79
  5509 000072C6 72E5                <1> 	jb	short loc_move_mcfg_next_cmd_char
  5510 000072C8 EB13                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5511                              <1> 
  5512                              <1> loc_move_mcfg_cmd_ok:
  5513 000072CA 30C0                <1> 	xor	al, al ; 0
  5514                              <1> 
  5515                              <1> loc_move_mcfg_cmd_arguments:
  5516 000072CC 8807                <1> 	mov	[edi], al
  5517 000072CE 47                  <1> 	inc	edi
  5518 000072CF 80FB4F              <1> 	cmp	bl, 79
  5519 000072D2 7309                <1> 	jnb	short loc_move_mcfg_cmd_arguments_ok
  5520 000072D4 8A041E              <1> 	mov	al, [esi+ebx]
  5521 000072D7 FEC3                <1> 	inc	bl
  5522 000072D9 3C20                <1> 	cmp	al, 20h
  5523 000072DB 73EF                <1> 	jnb	short loc_move_mcfg_cmd_arguments
  5524                              <1> 	
  5525                              <1> loc_move_mcfg_cmd_arguments_ok:
  5526 000072DD C60700              <1> 	mov	byte [edi], 0
  5527                              <1>        
  5528                              <1> loc_mcfg_process_cmd_interpreter:
  5529 000072E0 E809E0FFFF          <1> 	call    command_interpreter
  5530                              <1> 
  5531                              <1> loc_mcfg_ci_return_addr: 
  5532 000072E5 A1[90CF0000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5533 000072EA 89C2                <1> 	mov	edx, eax
  5534 000072EC 8B35[94CF0000]      <1> 	mov	esi, [MainProgCfg_LineOffset]
  5535 000072F2 01F2                <1> 	add	edx, esi
  5536 000072F4 0305[B8DB0000]      <1> 	add	eax, [csftdf_sf_mem_addr]
  5537 000072FA 29F0                <1> 	sub	eax, esi
  5538 000072FC 0F874EFFFFFF        <1>         ja      loc_mcfg_process_next_line_check
  5539                              <1> 
  5540 00007302 E81D000000          <1> 	call	mcfg_deallocate_mem
  5541                              <1>  
  5542 00007307 B94F000000          <1>  	mov	ecx, 79 ; 80 ?
  5543 0000730C BF[52D00000]        <1> 	mov	edi, CommandBuffer
  5544 00007311 30C0                <1> 	xor	al, al
  5545 00007313 F3AA                <1> 	rep	stosb
  5546                              <1> 
  5547                              <1> 	; 06/05/2016
  5548 00007315 BE[76CB0000]        <1> 	mov	esi, nextline
  5549 0000731A E800CCFFFF          <1> 	call	print_msg
  5550 0000731F E93BD6FFFF          <1> 	jmp	dos_prompt
  5551                              <1> 
  5552                              <1> mcfg_deallocate_mem:
  5553 00007324 A1[B8DB0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  5554 00007329 8B0D[BCDB0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  5555                              <1> 	;call	deallocate_memory_block
  5556                              <1> 	;retn
  5557 0000732F E9C8C7FFFF          <1> 	jmp	deallocate_memory_block
  5558                              <1> 
  5559                              <1> mcfg_read_file_sectors:
  5560                              <1> 	; 14/04/2016
  5561 00007334 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5562 00007338 7669                <1>         jna	short mcfg_read_fs_file_sectors
  5563                              <1> 
  5564                              <1> mcfg_read_fat_file_sectors:
  5565                              <1> 	; return:
  5566                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  5567                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  5568                              <1> 	;   CF = 1 -> read error (error code in AL)	
  5569                              <1> 
  5570                              <1> mcfg_read_fat_file_secs_0:
  5571 0000733A 8B15[90CF0000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5572 00007340 2B15[D0DB0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  5573 00007346 3B15[C8DB0000]      <1> 	cmp	edx, [csftdf_r_size]	
  5574 0000734C 7306                <1> 	jnb	short mcfg_read_fat_file_secs_1
  5575 0000734E 8915[C8DB0000]      <1> 	mov	[csftdf_r_size], edx
  5576                              <1> 		
  5577                              <1> mcfg_read_fat_file_secs_1:
  5578 00007354 A1[C8DB0000]        <1> 	mov	eax, [csftdf_r_size]
  5579 00007359 29D2                <1> 	sub	edx, edx
  5580 0000735B 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  5581 0000735F 01C8                <1> 	add	eax, ecx
  5582 00007361 48                  <1> 	dec	eax
  5583 00007362 F7F1                <1> 	div	ecx
  5584 00007364 89C1                <1> 	mov	ecx, eax ; sector count
  5585 00007366 A1[C0DB0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5586                              <1> 
  5587                              <1> 	; EBX = memory block address (current)
  5588                              <1> 	
  5589 0000736B E86E230000          <1> 	call	read_fat_file_sectors
  5590 00007370 7230                <1> 	jc	short mcfg_read_fat_file_secs_3
  5591                              <1> 
  5592                              <1> 	; EBX = next memory address
  5593                              <1> 
  5594 00007372 A1[D0DB0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  5595 00007377 0305[C8DB0000]      <1> 	add	eax, [csftdf_r_size]
  5596 0000737D 8B15[90CF0000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5597 00007383 39D0                <1> 	cmp	eax, edx
  5598 00007385 731B                <1> 	jnb	short mcfg_read_fat_file_secs_3 ; edx > 0
  5599 00007387 A3[D0DB0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  5600                              <1> 
  5601 0000738C 53                  <1> 	push	ebx ; *
  5602                              <1> 	; get next cluster (csftdf_r_size! bytes)
  5603 0000738D A1[C0DB0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5604 00007392 E819210000          <1> 	call	get_next_cluster
  5605 00007397 5B                  <1> 	pop	ebx ; *
  5606 00007398 7301                <1> 	jnc	short mcfg_read_fat_file_secs_2
  5607                              <1> 
  5608                              <1> 	;mov	eax, 15h ; Read error !
  5609 0000739A C3                  <1> 	retn
  5610                              <1> 
  5611                              <1> mcfg_read_fat_file_secs_2:
  5612 0000739B 29D2                <1> 	sub	edx, edx ; 0
  5613 0000739D A3[C0DB0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  5614                              <1> 
  5615                              <1> mcfg_read_fat_file_secs_3:
  5616 000073A2 C3                  <1> 	retn
  5617                              <1> 
  5618                              <1> mcfg_read_fs_file_sectors:
  5619 000073A3 C3                  <1> 	retn
  5620                              <1> 
  5621                              <1> loc_mcfg_load_fs_file:
  5622 000073A4 C3                  <1> 	retn
  5623                              <1> 
  5624                              <1> load_and_execute_file:
  5625                              <1> 	; 07/05/2016
  5626                              <1> 	; 06/05/2016
  5627                              <1> 	; 24/04/2016
  5628                              <1> 	; 23/04/2016
  5629                              <1> 	; 22/04/2016 (TRDOS 386 = TRDOS v2.0)
  5630                              <1> 	; 05/11/2011 
  5631                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'cmp_cmd_run', 'cmp_cmd_external')
  5632                              <1> 	; ('loc_run_check_filename')
  5633                              <1> 	; 29/08/2011
  5634                              <1> 	; 10/09/2011
  5635                              <1> 	; INPUT->
  5636                              <1> 	;	ESI = Path Name address (CommandBuffer address)
  5637                              <1> 	; OUTPUT ->
  5638                              <1> 	;	none (error message will be shown if an error will occur)
  5639                              <1> 	;
  5640                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI, EBP will be changed) 
  5641                              <1> 	;
  5642                              <1> loc_run_check_filename:
  5643 000073A5 803E20              <1> 	cmp	byte [esi], 20h
  5644 000073A8 0F820FE3FFFF        <1> 	jb	loc_cmd_failed
  5645 000073AE 7703                <1> 	ja	short loc_run_check_filename_ok
  5646 000073B0 46                  <1> 	inc	esi
  5647 000073B1 EBF2                <1> 	jmp	short loc_run_check_filename
  5648                              <1> 
  5649                              <1> loc_run_check_filename_ok:
  5650 000073B3 C605[03D00000]00    <1> 	mov	byte [CmdArgStart], 0 ; reset
  5651 000073BA 56                  <1> 	push	esi ; *
  5652                              <1> loc_run_get_first_arg_pos:
  5653 000073BB 46                  <1> 	inc	esi
  5654 000073BC 8A06                <1> 	mov	al, [esi]
  5655 000073BE 3C20                <1> 	cmp	al, 20h
  5656 000073C0 77F9                <1> 	ja	short loc_run_get_first_arg_pos
  5657 000073C2 C60600              <1> 	mov	byte [esi], 0
  5658 000073C5 7215                <1> 	jb	short loc_run_parse_path_name
  5659                              <1> loc_run_get_external_arg_pos:
  5660 000073C7 46                  <1> 	inc	esi
  5661 000073C8 8A06                <1> 	mov	al, [esi]
  5662 000073CA 3C20                <1> 	cmp	al, 20h
  5663 000073CC 720E                <1> 	jb	short loc_run_parse_path_name
  5664 000073CE 74F7                <1> 	je	short loc_run_get_external_arg_pos
  5665 000073D0 89F0                <1> 	mov	eax, esi
  5666 000073D2 2D[52D00000]        <1> 	sub	eax, CommandBuffer
  5667 000073D7 A2[03D00000]        <1> 	mov	byte [CmdArgStart], al
  5668                              <1> loc_run_parse_path_name:
  5669 000073DC 5E                  <1> 	pop	esi ; *
  5670 000073DD BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  5671 000073E2 E8D2090000          <1> 	call	parse_path_name
  5672 000073E7 0F82D0E2FFFF        <1> 	jc	loc_cmd_failed
  5673                              <1> 
  5674                              <1> loc_run_check_filename_exists:
  5675 000073ED BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5676 000073F2 803E20              <1> 	cmp	byte [esi], 20h
  5677 000073F5 0F86C2E2FFFF        <1> 	jna	loc_cmd_failed
  5678                              <1> 
  5679                              <1> loc_run_check_exe_filename_ext:
  5680 000073FB E88D020000          <1> 	call	check_prg_filename_ext
  5681 00007400 0F82B7E2FFFF        <1> 	jc	loc_cmd_failed
  5682                              <1> 	
  5683                              <1> loc_run_check_exe_filename_ext_ok:
  5684 00007406 66A3[4EDC0000]      <1> 	mov	word [EXE_ID], ax
  5685                              <1> 
  5686                              <1> loc_run_drv:
  5687 0000740C C605[4DDC0000]00    <1> 	mov	byte [Run_Manual_Path], 0
  5688 00007413 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5689 00007418 A3[48DC0000]        <1>         mov     [Run_CDirFC], eax
  5690                              <1> 	;
  5691 0000741D 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  5692 00007423 8835[02D80000]      <1> 	mov	[RUN_CDRV], dh
  5693                              <1> 
  5694 00007429 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  5695 0000742F 38F2                <1> 	cmp	dl, dh
  5696 00007431 7412                <1> 	je	short loc_run_change_directory
  5697                              <1>                
  5698 00007433 8005[4DDC0000]02    <1> 	add	byte [Run_Manual_Path], 2
  5699                              <1> 
  5700 0000743A E8E4D3FFFF          <1> 	call	change_current_drive
  5701 0000743F 0F82A3E2FFFF        <1> 	jc	loc_run_cmd_failed
  5702                              <1> 
  5703                              <1> loc_run_change_directory:
  5704 00007445 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5705 0000744C 7623                <1> 	jna	short loc_run_find_executable_file
  5706                              <1> 
  5707 0000744E FE05[4DDC0000]      <1> 	inc	byte [Run_Manual_Path]
  5708                              <1>      
  5709 00007454 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  5710                              <1> 
  5711 0000745A BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  5712 0000745F 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5713 00007461 E83F030000          <1> 	call	change_current_directory
  5714 00007466 0F827CE2FFFF        <1> 	jc	loc_run_cmd_failed
  5715                              <1> 
  5716                              <1> loc_run_change_prompt_dir_string:
  5717 0000746C E854020000          <1> 	call	change_prompt_dir_string
  5718                              <1> 
  5719                              <1> loc_run_find_executable_file:
  5720 00007471 66C705[4CDC0000]00- <1> 	mov	word [Run_Auto_Path], 0
  5720 00007479 00                  <1>
  5721                              <1> 
  5722                              <1> loc_run_find_executable_file_next:
  5723 0000747A BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5724                              <1> loc_run_find_program_file_next:
  5725 0000747F 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5726 00007483 E831E7FFFF          <1> 	call	find_first_file
  5727                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  5728                              <1> 	; EDI = Directory Buffer Directory Entry Location
  5729                              <1> 	; EAX = File size
  5730 00007488 0F835C010000        <1> 	jnc	loc_load_and_run_file
  5731                              <1> 	 
  5732 0000748E 3C02                <1> 	cmp	al, 2 ; file not found
  5733 00007490 0F8552E2FFFF        <1> 	jne	loc_run_cmd_failed
  5734                              <1> 
  5735 00007496 66A1[4EDC0000]      <1> 	mov	ax, word [EXE_ID]
  5736 0000749C 80FC2E              <1> 	cmp	ah, '.' ; File name has extension sign
  5737 0000749F 7424                <1> 	je	short loc_run_check_auto_path
  5738                              <1> 
  5739 000074A1 08C0                <1> 	or	al, al
  5740 000074A3 7520                <1> 	jnz	short loc_run_check_auto_path
  5741                              <1> 
  5742 000074A5 80FC08              <1> 	cmp	ah, 8 ; count of file name chars
  5743 000074A8 771B                <1> 	ja	short loc_run_check_auto_path
  5744                              <1> 
  5745                              <1> loc_run_change_file_ext_to_prg:
  5746 000074AA 0FB6DC              <1> 	movzx	ebx, ah ; count of file name chars
  5747 000074AD BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5748 000074B2 01F3                <1> 	add	ebx, esi	
  5749                              <1> 	; 07/05/2016
  5750 000074B4 C7032E505247        <1> 	mov	dword [ebx],  '.PRG'
  5751 000074BA 66C705[4EDC0000]50- <1> 	mov	word [EXE_ID], 'P.'
  5751 000074C2 2E                  <1>
  5752 000074C3 EBBA                <1> 	jmp	short loc_run_find_program_file_next	
  5753                              <1> 
  5754                              <1> loc_run_check_auto_path:
  5755                              <1> 	; NOTE: /// 07/05/2016 ///
  5756                              <1> 	; If the path is given, value of byte [Run_Manual_Path]
  5757                              <1> 	; will not be ZERO. If so, file searching by using
  5758                              <1> 	; Automatic Path (via 'PATH' environment variable)
  5759                              <1> 	; will not be applicable, because the program file 
  5760                              <1> 	; is already/absolutely not found.
  5761                              <1> 
  5762 000074C5 A0[4DDC0000]        <1> 	mov	al, [Run_Manual_Path]
  5763 000074CA 08C0                <1> 	or	al, al
  5764 000074CC 0F85EBE1FFFF        <1> 	jnz	loc_cmd_failed
  5765                              <1> 
  5766                              <1> loc_run_check_auto_path_again:
  5767 000074D2 66833D[4CDC0000]FF  <1> 	cmp	word [Run_Auto_Path], 0FFFFh		 
  5768                              <1> 		; 0FFFFh = Not a valid run path (in ENV block) 
  5769 000074DA 0F83DDE1FFFF        <1> 	jnb	loc_cmd_failed
  5770                              <1> 	; xor	al, al 
  5771 000074E0 BE[92BE0000]        <1> 	mov	esi, Cmd_Path ; 'PATH'
  5772 000074E5 BF[A2D00000]        <1> 	mov	edi, TextBuffer
  5773 000074EA E853F9FFFF          <1> 	call	get_environment_string
  5774 000074EF 730E                <1> 	jnc	short loc_run_chk_filename_ext_again
  5775 000074F1 66C705[4CDC0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; invalid
  5775 000074F9 FF                  <1>
  5776 000074FA E9BEE1FFFF          <1> 	jmp	loc_cmd_failed
  5777                              <1> 
  5778                              <1> loc_run_chk_filename_ext_again:
  5779 000074FF 89C1                <1> 	mov	ecx, eax ; string length (with zero tail)
  5780 00007501 49                  <1> 	dec	ecx ; without zero tail
  5781 00007502 66A1[4EDC0000]      <1> 	mov	ax, [EXE_ID]
  5782 00007508 80FC2E              <1> 	cmp	ah, '.'
  5783 0000750B 740E                <1> 	je	short loc_run_chk_auto_path_pos
  5784                              <1> 	 
  5785                              <1> loc_run_change_file_ext_to_noext_again:
  5786 0000750D 0FB6DC              <1> 	movzx	ebx, ah
  5787 00007510 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5788 00007515 01F3                <1> 	add 	ebx, esi
  5789 00007517 29C0                <1> 	sub	eax, eax
  5790 00007519 8903                <1> 	mov	[ebx], eax ; 0 ; erase extension (.PRG)
  5791                              <1> 
  5792                              <1> loc_run_chk_auto_path_pos:
  5793                              <1> 	;movzx	eax,  word [Run_Auto_Path]
  5794 0000751B 66A1[4CDC0000]      <1> 	mov	ax, [Run_Auto_Path]
  5795 00007521 39C8                <1> 	cmp	eax, ecx ; ecx = string length (except zero tail)
  5796 00007523 0F8394E1FFFF        <1> 	jnb	loc_cmd_failed
  5797                              <1> 	;or	eax, eax
  5798 00007529 6609C0              <1> 	or	ax, ax
  5799 0000752C 7502                <1> 	jnz	short loc_run_auto_path_pos_move
  5800 0000752E B005                <1> 	mov	al, 5
  5801                              <1> 
  5802                              <1> loc_run_auto_path_pos_move:
  5803 00007530 89FE                <1> 	mov	esi, edi ; offset TextBuffer
  5804 00007532 01C6                <1> 	add	esi, eax
  5805                              <1> 
  5806                              <1> loc_run_auto_path_pos_space_loop:
  5807 00007534 AC                  <1> 	lodsb
  5808 00007535 3C20                <1> 	cmp	al, 20h 
  5809 00007537 74FB                <1> 	je	short loc_run_auto_path_pos_space_loop
  5810 00007539 0F827EE1FFFF        <1> 	jb	loc_cmd_failed 
  5811 0000753F AA                  <1> 	stosb
  5812                              <1> loc_run_auto_path_pos_move_next: 
  5813 00007540 AC                  <1> 	lodsb
  5814 00007541 3C3B                <1> 	cmp	al, ';'
  5815 00007543 7414                <1> 	je	short loc_run_auto_path_pos_move_last_byte
  5816 00007545 3C20                <1> 	cmp	al, 20h
  5817 00007547 74F7                <1> 	je	short loc_run_auto_path_pos_move_next
  5818 00007549 7203                <1> 	jb	short loc_byte_ptr_end_of_path
  5819 0000754B AA                  <1> 	stosb
  5820 0000754C EBF2                <1> 	jmp	short loc_run_auto_path_pos_move_next 
  5821                              <1> 
  5822                              <1> loc_byte_ptr_end_of_path: 
  5823 0000754E 66C705[4CDC0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; end of path
  5823 00007556 FF                  <1>
  5824 00007557 EB0D                <1> 	jmp	short loc_run_auto_path_move_ok 
  5825                              <1> 
  5826                              <1> loc_run_auto_path_pos_move_last_byte:
  5827 00007559 89F0                <1> 	mov	eax, esi
  5828 0000755B 2D[A2D00000]        <1> 	sub	eax, TextBuffer 
  5829 00007560 66A3[4CDC0000]      <1> 	mov	[Run_Auto_Path], ax ; next path position
  5830                              <1> 
  5831                              <1> loc_run_auto_path_move_ok:
  5832 00007566 4F                  <1> 	dec	edi
  5833 00007567 B02F                <1> 	mov	al, '/'
  5834 00007569 3807                <1> 	cmp	[edi], al
  5835 0000756B 7403                <1> 	je	short loc_run_auto_path_move_file_name
  5836 0000756D 47                  <1> 	inc	edi
  5837 0000756E 8807                <1> 	mov	[edi], al
  5838                              <1> 
  5839                              <1> loc_run_auto_path_move_file_name:
  5840 00007570 47                  <1> 	inc	edi   
  5841 00007571 BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5842                              <1> 
  5843                              <1> loc_run_auto_path_move_fn_loop:
  5844 00007576 AC                  <1> 	lodsb
  5845 00007577 AA                  <1> 	stosb
  5846 00007578 08C0                <1> 	or	al, al
  5847 0000757A 75FA                <1> 	jnz	short loc_run_auto_path_move_fn_loop
  5848                              <1> 
  5849 0000757C BE[A2D00000]        <1> 	mov	esi, TextBuffer
  5850 00007581 BF[46D90000]        <1> 	mov	edi, FindFile_Drv
  5851 00007586 E82E080000          <1> 	call	parse_path_name
  5852 0000758B 0F822CE1FFFF        <1> 	jc	loc_cmd_failed
  5853                              <1> 
  5854 00007591 8A35[A2CF0000]      <1> 	mov	dh, [Current_Drv]
  5855 00007597 8A15[46D90000]      <1> 	mov	dl, [FindFile_Drv]
  5856 0000759D 38F2                <1> 	cmp	dl, dh
  5857 0000759F 740B                <1> 	je	short loc_run_change_directory_again
  5858                              <1>                
  5859 000075A1 E87DD2FFFF          <1> 	call	change_current_drive
  5860 000075A6 0F823CE1FFFF        <1> 	jc	loc_run_cmd_failed
  5861                              <1> 
  5862                              <1> loc_run_change_directory_again:
  5863 000075AC 803D[47D90000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5864 000075B3 761D                <1> 	jna	short loc_load_executable_cdir_chk_again
  5865                              <1> 
  5866 000075B5 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  5867 000075BB BE[47D90000]        <1> 	mov	esi, FindFile_Directory
  5868 000075C0 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5869 000075C2 E8DE010000          <1> 	call	change_current_directory
  5870 000075C7 0F821BE1FFFF        <1> 	jc	loc_run_cmd_failed
  5871                              <1> 
  5872                              <1> loc_run_chg_prompt_dir_str_again:
  5873 000075CD E8F3000000          <1> 	call	change_prompt_dir_string
  5874                              <1> 
  5875                              <1> loc_load_executable_cdir_chk_again:
  5876 000075D2 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5877 000075D7 3B05[48DC0000]      <1> 	cmp	eax, [Run_CDirFC]
  5878 000075DD 0F8597FEFFFF        <1> 	jne	loc_run_find_executable_file_next
  5879 000075E3 30C0                <1> 	xor	al, al ; 0
  5880 000075E5 E9E8FEFFFF          <1> 	jmp	loc_run_check_auto_path_again
  5881                              <1> 
  5882                              <1> loc_load_and_run_file:
  5883                              <1> 	; 23/04/2016
  5884 000075EA BE[88D90000]        <1> 	mov	esi, FindFile_Name
  5885 000075EF BF[A2D00000]        <1> 	mov	edi, TextBuffer
  5886                              <1> 
  5887                              <1>  	; 24/04/2016
  5888 000075F4 31D2                <1> 	xor	edx, edx
  5889 000075F6 668915[FEDF0000]    <1> 	mov	word [argc], dx ; 0
  5890 000075FD 8915[A8DF0000]      <1> 	mov	dword [u.nread], edx ; 0
  5891                              <1> 
  5892                              <1> loc_load_and_run_file_1:
  5893 00007603 AC                  <1> 	lodsb	
  5894 00007604 AA                  <1> 	stosb
  5895 00007605 FF05[A8DF0000]      <1> 	inc	dword [u.nread]
  5896 0000760B 20C0                <1> 	and	al, al
  5897 0000760D 75F4                <1> 	jnz 	short loc_load_and_run_file_1
  5898                              <1> 	
  5899 0000760F A0[03D00000]        <1> 	mov	al, [CmdArgStart]
  5900 00007614 20C0                <1> 	and	al, al
  5901 00007616 743B                <1> 	jz	short loc_load_and_run_file_7
  5902                              <1> 
  5903 00007618 B950000000          <1> 	mov	ecx, 80
  5904 0000761D 29F1                <1> 	sub	ecx, esi
  5905 0000761F 81C6[52D00000]      <1> 	add	esi, CommandBuffer
  5906                              <1> 
  5907                              <1> loc_load_and_run_file_2:
  5908 00007625 AC                  <1> 	lodsb
  5909 00007626 3C20                <1> 	cmp	al, 20h
  5910 00007628 7717                <1> 	ja	short loc_load_and_run_file_5	
  5911 0000762A 721E                <1> 	jb	short loc_load_and_run_file_6
  5912                              <1> 
  5913                              <1> loc_load_and_run_file_3:
  5914 0000762C 803E20              <1> 	cmp	byte [esi], 20h
  5915 0000762F 7707                <1> 	ja	short loc_load_and_run_file_4
  5916 00007631 7217                <1> 	jb	short loc_load_and_run_file_6
  5917 00007633 46                  <1> 	inc	esi
  5918 00007634 E2F6                <1> 	loop	loc_load_and_run_file_3
  5919 00007636 EB12                <1> 	jmp	short loc_load_and_run_file_6
  5920                              <1> 
  5921                              <1> loc_load_and_run_file_4:
  5922 00007638 28C0                <1> 	sub	al, al ; 0
  5923 0000763A 66FF05[FEDF0000]    <1> 	inc	word [argc]
  5924                              <1> loc_load_and_run_file_5:
  5925 00007641 AA                  <1> 	stosb
  5926 00007642 FF05[A8DF0000]      <1> 	inc	dword [u.nread]
  5927 00007648 E2DB                <1> 	loop	loc_load_and_run_file_2
  5928                              <1> 			
  5929                              <1> loc_load_and_run_file_6:
  5930 0000764A 30C0                <1> 	xor	al, al ; 0
  5931 0000764C AA                  <1> 	stosb
  5932 0000764D FF05[A8DF0000]      <1> 	inc	dword [u.nread]
  5933                              <1> loc_load_and_run_file_7:
  5934 00007653 8807                <1> 	mov 	[edi], al
  5935 00007655 66FF05[FEDF0000]    <1> 	inc	word [argc] ; 24/04/2016
  5936 0000765C FF05[A8DF0000]      <1> 	inc	dword [u.nread] ; 24/04/2016
  5937 00007662 BE[A2D00000]        <1> 	mov	esi, TextBuffer
  5938 00007667 8B15[B4D90000]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  5939 0000766D 66A1[ACD90000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  5940 00007673 66C1E010            <1> 	shl	ax, 16
  5941 00007677 66A1[B2D90000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusLO]
  5942                              <1> 	; EAX = First Cluster number
  5943                              <1> 	; EDX = File Size
  5944                              <1> 	; ESI = Argument list address
  5945                              <1> 	; [argc] = argument count
  5946                              <1> 	; [u.nread] = argument list length
  5947 0000767D E89D3C0000          <1> 	call	load_and_run_file ; trdosk6.s
  5948 00007682 0F8260E0FFFF        <1>         jc      loc_run_cmd_failed
  5949                              <1> loc_load_and_run_file_8: ; 06/05/2016
  5950 00007688 E950E9FFFF          <1> 	jmp	loc_file_rw_restore_retn
  5951                              <1> 
  5952                              <1> check_prg_filename_ext:
  5953                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  5954                              <1> 	; 10/09/2011 
  5955                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'proc_check_exe_filename_ext')
  5956                              <1> 	; 14/11/2009
  5957                              <1> 	; INPUT -> 
  5958                              <1> 	;	ESI = Dot File Name
  5959                              <1> 	; OUTPUT ->
  5960                              <1> 	;     cf = 0 -> EXE_ID in AL
  5961                              <1> 	;	ESI = Last char + 1 position
  5962                              <1> 	;     cf = 1 -> Invalid executable file name
  5963                              <1> 	;	or no file name extension if AH<=8
  5964                              <1> 	;	AL = Last file name char     
  5965                              <1> 	;     cf = 0 -> AL='P' (PRG), AL=0 (no extension)
  5966                              <1> 	;
  5967                              <1> 	; (Modified registers: EAX, ESI)
  5968                              <1>   
  5969 0000768D 30E4                <1> 	xor	ah, ah
  5970                              <1> loc_run_check_filename_ext:	
  5971 0000768F AC                  <1> 	lodsb
  5972 00007690 3C21                <1> 	cmp	al, 21h
  5973 00007692 7229                <1> 	jb	short loc_check_exe_fn_retn 
  5974 00007694 FEC4                <1> 	inc	ah
  5975 00007696 3C2E                <1> 	cmp	al, '.'
  5976 00007698 75F5                <1> 	jne	short loc_run_check_filename_ext	
  5977                              <1> 		 
  5978                              <1> loc_run_check_filename_ext_dot:
  5979 0000769A 80FC02              <1> 	cmp	ah, 2 ; .??? is not valid
  5980 0000769D 88C4                <1> 	mov	ah, al ; '.' 
  5981 0000769F 7219                <1> 	jb	short loc_check_prg_fn_retn
  5982                              <1> 
  5983                              <1> loc_run_check_filename_ext_dot_ok:
  5984 000076A1 AC                  <1> 	lodsb
  5985 000076A2 24DF                <1> 	and	al, 0DFh 
  5986                              <1> 
  5987                              <1> loc_run_check_filename_ext_prg:
  5988 000076A4 3C50                <1> 	cmp	al, 'P'
  5989 000076A6 7212                <1> 	jb	short loc_check_prg_fn_retn
  5990 000076A8 7711                <1> 	ja	short loc_check_prg_fn_stc
  5991 000076AA AC                  <1> 	lodsb
  5992 000076AB 24DF                <1> 	and	al, 0DFh 
  5993 000076AD 3C52                <1> 	cmp	al, 'R'
  5994 000076AF 750A                <1> 	jne	short loc_check_prg_fn_stc
  5995 000076B1 AC                  <1> 	lodsb
  5996 000076B2 24DF                <1> 	and	al, 0DFh
  5997 000076B4 3C47                <1> 	cmp	al, 'G'
  5998 000076B6 7503                <1> 	jne	short loc_check_prg_fn_stc
  5999                              <1> 
  6000 000076B8 B050                <1> 	mov	al, 'P'
  6001                              <1> loc_check_prg_fn_retn:
  6002 000076BA C3                  <1> 	retn
  6003                              <1> 
  6004                              <1> loc_check_prg_fn_stc:
  6005 000076BB F9                  <1> 	stc
  6006 000076BC C3                  <1> 	retn
  6007                              <1>  
  6008                              <1> loc_check_exe_fn_retn:
  6009 000076BD 28C0                <1> 	sub	al, al ; 0
  6010 000076BF C3                  <1> 	retn
  6011                              <1>               
  6012                              <1> find_and_list_files:
  6013 000076C0 C3                  <1> 	retn
  6014                              <1> set_exec_arguments:
  6015 000076C1 C3                  <1> 	retn
  6016                              <1> delete_fs_directory:
  6017 000076C2 31C0                <1> 	xor eax, eax
  6018 000076C4 C3                  <1> 	retn
  1927                                  %include 'trdosk4.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - Directory Functions : trdosk4.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 04/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; DIR.ASM (09/10/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> ; DIR.ASM  [ TRDOS KERNEL - COMMAND EXECUTER SECTION - DIRECTORY FUNCTIONS ]
    15                              <1> ; (c) 2004-2010  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/10/2011
    16                              <1> ; FILE.ASM [ FILE FUNCTIONS ] Last Update: 09/10/2011
    17                              <1> 
    18                              <1> change_prompt_dir_string:
    19                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    20                              <1> 	; 27/03/2011
    21                              <1> 	; 09/10/2009
    22                              <1> 	; INPUT/OUTPUT => none
    23                              <1> 	; this procedure changes current directory string/text  
    24                              <1> 	; 2005
    25                              <1> 
    26 000076C5 BF[A6CF0000]        <1> 	mov	edi, Current_Directory
    27 000076CA 8A25[A0CF0000]      <1> 	mov	ah, [Current_Dir_Level]
    28 000076D0 BE[03D80000]        <1> 	mov	esi, PATH_Array
    29 000076D5 E807000000          <1> 	call	set_current_directory_string
    30 000076DA 880D[01D00000]      <1> 	mov	[Current_Dir_StrLen], cl
    31                              <1> 
    32 000076E0 C3                  <1> 	retn
    33                              <1> 
    34                              <1> set_current_directory_string:
    35                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    36                              <1> 	; 27/03/2011
    37                              <1> 	; 09/10/2009
    38                              <1> 	; INPUT:
    39                              <1> 	;    ESI = Path Array Address 
    40                              <1> 	;    EDI = Current Directory String Buffer
    41                              <1> 	;    AH = Current Directory Level
    42                              <1> 	; OUTPUT => EAX, EBX, ESI will be changed
    43                              <1> 	;    EDI will be same with input
    44                              <1> 	;    ECX = Current Directory String Length 
    45                              <1> 
    46 000076E1 57                  <1> 	push    edi
    47 000076E2 80FC00              <1> 	cmp     ah, 0
    48 000076E5 7652                <1> 	jna	short pass_write_path
    49 000076E7 83C610              <1> 	add	esi, 16
    50 000076EA 89F3                <1> 	mov	ebx, esi
    51                              <1> loc_write_path:
    52 000076EC B908000000          <1> 	mov	ecx, 8
    53                              <1> path_write_dirname1:
    54 000076F1 AC                  <1> 	lodsb
    55 000076F2 3C20                <1> 	cmp	al, 20h
    56 000076F4 7612                <1> 	jna	short pass_write_dirname1
    57 000076F6 AA                  <1> 	stosb
    58 000076F7 81FF[00D00000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    59 000076FD 733A                <1> 	jnb	short pass_write_path
    60 000076FF E2F0                <1> 	loop	path_write_dirname1
    61 00007701 803E20              <1> 	cmp	byte [esi], 20h
    62 00007704 7624                <1> 	jna	short pass_write_dirname2
    63 00007706 EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    64                              <1> pass_write_dirname1:
    65 00007708 89DE                <1> 	mov	esi, ebx
    66 0000770A 83C608              <1> 	add	esi, 8
    67 0000770D 803E20              <1> 	cmp	byte [esi], 20h
    68 00007710 7618                <1> 	jna	short pass_write_dirname2
    69                              <1> loc_put_dot_cont_ext:
    70 00007712 C6072E              <1> 	mov	byte [edi], "."
    71                              <1> 	;mov	ecx, 3
    72 00007715 B103                <1> 	mov	cl, 3
    73                              <1> loc_check_dir_name_ext:
    74 00007717 AC                  <1> 	lodsb
    75 00007718 47                  <1> 	inc	edi
    76 00007719 3C20                <1> 	cmp	al, 20h
    77 0000771B 760D                <1> 	jna	short pass_write_dirname2
    78 0000771D 8807                <1> 	mov	[edi], al
    79 0000771F 81FF[00D00000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    80 00007725 7312                <1> 	jnb	short pass_write_path
    81 00007727 E2EE                <1> 	loop    loc_check_dir_name_ext
    82 00007729 47                  <1> 	inc	edi
    83                              <1> pass_write_dirname2:
    84 0000772A FECC                <1> 	dec	ah
    85 0000772C 740B                <1> 	jz      short pass_write_path
    86 0000772E 83C310              <1> 	add	ebx, 16
    87 00007731 89DE                <1> 	mov	esi, ebx
    88 00007733 C6072F              <1> 	mov	byte [edi],"/"
    89 00007736 47                  <1> 	inc	edi
    90 00007737 EBB3                <1> 	jmp	short loc_write_path
    91                              <1> pass_write_path:
    92 00007739 C60700              <1> 	mov	byte [edi], 0
    93 0000773C 47                  <1> 	inc	edi
    94 0000773D 89F9                <1> 	mov	ecx, edi
    95 0000773F 5F                  <1> 	pop	edi
    96 00007740 29F9                <1> 	sub	ecx, edi
    97                              <1> 	; ECX = Current Directory String Length
    98 00007742 C3                  <1> 	retn
    99                              <1> 
   100                              <1> get_current_directory:
   101                              <1> 	; 14/02/2016
   102                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
   103                              <1> 	; 27/03/2011
   104                              <1> 	;
   105                              <1> 	; INPUT-> ESI = Current Directory Buffer
   106                              <1> 	;         DL = TRDOS Logical Dos Drive Number + 1
   107                              <1> 	;              (0= Default/Current Drive)
   108                              <1> 	;           
   109                              <1> 	;   Note: Required dir buffer length may be <= 92 bytes
   110                              <1> 	;         for TRDOS (7*12 name chars + 7 slash + 0)
   111                              <1> 	; OUTPUT ->  ESI = Current Directory Buffer
   112                              <1> 	;            EAX, EBX, ECX, EDX, EDI will be changed
   113                              <1> 	;            CX/CL = Current Directory String Length
   114                              <1> 	;	     DL = Drive Number (0 based)
   115                              <1> 	;            (If input is 0, output is current drv number) 
   116                              <1> 	;            DH = same with input 
   117                              <1> 	;   cf = 0 -> AL = 0
   118                              <1> 	;   cf = 1 -> error code in AL 
   119                              <1>               
   120                              <1> loc_get_current_drive_0:
   121 00007743 80FA00              <1> 	cmp	dl, 0
   122 00007746 7708                <1> 	ja	short loc_get_current_drive_1
   123 00007748 8A15[A2CF0000]      <1> 	mov	dl, [Current_Drv]
   124 0000774E EB17                <1> 	jmp	short loc_get_current_drive_2
   125                              <1> loc_get_current_drive_1:
   126 00007750 FECA                <1> 	dec 	dl
   127 00007752 3A15[C5BD0000]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   128 00007758 760D                <1> 	jna	short loc_get_current_drive_2
   129 0000775A B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
   130 0000775F F5                  <1> 	cmc 	; stc
   131 00007760 C3                  <1> 	retn
   132                              <1> 
   133                              <1> loc_get_current_drive_not_ready_retn:
   134 00007761 5E                  <1> 	pop	esi
   135                              <1> 	;mov	eax, 15h
   136 00007762 66B81500            <1> 	mov	ax, 15h ; Drive not ready
   137 00007766 C3                  <1> 	retn  
   138                              <1>  
   139                              <1> loc_get_current_drive_2:
   140 00007767 31C0                <1> 	xor	eax, eax
   141 00007769 88D4                <1> 	mov	ah, dl
   142 0000776B 56                  <1> 	push	esi
   143 0000776C BE00010900          <1> 	mov	esi, Logical_DOSDisks
   144 00007771 01C6                <1> 	add	esi, eax
   145 00007773 8A06                <1> 	mov	al, [esi+LD_Name] 
   146 00007775 3C41                <1> 	cmp	al, 'A'
   147 00007777 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   148                              <1> 
   149 00007779 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   150 0000777C 08E4                <1> 	or	ah, ah
   151 0000777E 7506                <1> 	jnz	short loc_get_current_drive_3
   152                              <1> 
   153                              <1> 	;xor	ah, ah ; mov ah, 0
   154 00007780 8826                <1> 	mov	[esi], ah
   155 00007782 31C9                <1> 	xor	ecx, ecx
   156 00007784 EB1C                <1> 	jmp	short loc_get_current_drive_4
   157                              <1> 
   158                              <1> loc_get_current_drive_3:
   159 00007786 BF[03D80000]        <1>         mov     edi, PATH_Array
   160 0000778B 57                  <1> 	push	edi
   161 0000778C 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   162 00007792 B920000000          <1> 	mov	ecx, 32
   163 00007797 F3A5                <1> 	rep	movsd
   164 00007799 5E                  <1> 	pop	esi ; Path Array Address
   165 0000779A 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   166                              <1> 	;
   167 0000779B E841FFFFFF          <1> 	call	set_current_directory_string
   168 000077A0 89FE                <1> 	mov	esi, edi
   169                              <1> 
   170                              <1> loc_get_current_drive_4:
   171 000077A2 30C0                <1> 	xor	al, al
   172 000077A4 C3                  <1> 	retn
   173                              <1> 
   174                              <1> change_current_directory:
   175                              <1> 	; 19/02/2016
   176                              <1> 	; 11/02/2016
   177                              <1> 	; 10/02/2016
   178                              <1> 	; 08/02/2016
   179                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   180                              <1> 	; 18/09/2011 (DIR.ASM, 09/10/2011)	
   181                              <1> 	; 04/10/2009
   182                              <1> 	; 2005
   183                              <1> 	; INPUT -> 
   184                              <1> 	;	ESI = Directory string
   185                              <1> 	;	ah = CD command (CDh = save current dir string)
   186                              <1> 	; OUTPUT -> 
   187                              <1> 	; 	EDI = DOS Drive Description Table
   188                              <1> 	; 	cf = 1 -> error
   189                              <1> 	;	   EAX = Error code
   190                              <1> 	;	cf = 0 -> succesful
   191                              <1> 	;	   ESI = PATH_Array
   192                              <1> 	;	   EAX = Current Directory First Cluster
   193                              <1> 	;
   194                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
   195                              <1> 	
   196 000077A5 8825[91D80000]      <1> 	mov	[CD_COMMAND], ah
   197 000077AB 803E2F              <1> 	cmp	byte [esi], '/'
   198 000077AE 7505                <1> 	jne	short loc_ccd_cdir_level
   199 000077B0 46                  <1> 	inc	esi
   200 000077B1 30C0                <1> 	xor	al, al
   201 000077B3 EB05                <1> 	jmp	short loc_ccd_parse_path_name
   202                              <1> loc_ccd_cdir_level:
   203 000077B5 A0[A0CF0000]        <1> 	mov	al, [Current_Dir_Level]
   204                              <1> loc_ccd_parse_path_name:
   205 000077BA 88C4                <1> 	mov	ah, al
   206 000077BC BF[03D80000]        <1> 	mov	edi, PATH_Array
   207                              <1> 
   208                              <1> ; Reset directory levels > cdir level
   209                              <1> 	; is this required !?
   210                              <1> 	;
   211                              <1> 	; Relations:
   212                              <1> 	; MAINPROG.ASM (pass_ccdrv_reset_cdir_FAT_fcluster)
   213                              <1> 	; proc_parse_dir_name,
   214                              <1> 	; proc_change_current_directory (this procedure)
   215                              <1> 	; proc_change_prompt_dir_string 
   216                              <1>  
   217 000077C1 0FB6C8              <1> 	movzx	ecx, al
   218 000077C4 FEC1                <1> 	inc	cl
   219 000077C6 C0E104              <1> 	shl	cl, 4
   220 000077C9 01CF                <1> 	add	edi, ecx
   221 000077CB B107                <1> 	mov	cl, 7
   222 000077CD 28C1                <1> 	sub	cl, al
   223 000077CF C0E102              <1> 	shl	cl, 2
   224 000077D2 89C3                <1> 	mov	ebx, eax
   225 000077D4 31C0                <1> 	xor	eax, eax ; 0
   226 000077D6 F3AB                <1> 	rep	stosd
   227 000077D8 89D8                <1> 	mov	eax, ebx
   228                              <1> 
   229 000077DA BF[03D80000]        <1> 	mov	edi, PATH_Array
   230                              <1> 
   231 000077DF 803E20              <1> 	cmp	byte [esi], 20h
   232 000077E2 F5                  <1> 	cmc
   233 000077E3 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   234                              <1> 
   235                              <1> 		; ESI = Path name
   236                              <1> 		; AL = CCD_Level
   237 000077E5 E872010000          <1>         call    parse_dir_name
   238                              <1> 		; AL = CCD_Level 
   239                              <1> 		; AH = Last_Dir_Level
   240                              <1> 		; (EDI = PATH_Array)
   241                              <1> 
   242                              <1> pass_ccd_parse_dir_name:
   243 000077EA 9C                  <1> 	pushf
   244                              <1> 
   245                              <1> 	;mov	[CCD_Level], al
   246                              <1>         ;mov	[Last_Dir_Level], ah
   247 000077EB 66A3[87D80000]      <1> 	mov	[CCD_Level], ax
   248                              <1> 
   249 000077F1 31DB                <1> 	xor	ebx, ebx
   250 000077F3 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
   251 000077F9 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   252 000077FE 01DE                <1> 	add	esi, ebx
   253                              <1> 
   254 00007800 9D                  <1> 	popf 
   255 00007801 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   256                              <1> 
   257 00007803 8935[83D80000]      <1> 	mov	[CCD_DriveDT], esi
   258                              <1> 
   259 00007809 3C07                <1> 	cmp	al, 7
   260 0000780B 7209                <1> 	jb	short loc_ccd_load_child_dir
   261                              <1> 
   262                              <1> loc_ccd_bad_path_name_retn:
   263 0000780D 87F7                <1> 	xchg	esi, edi
   264                              <1> 	; DOS Error Code 
   265 0000780F B818000000          <1> 	mov	eax, 18h ; Bad request structure length 
   266 00007814 F9                  <1> 	stc
   267                              <1> loc_ccd_retn_p:
   268 00007815 C3                  <1> 	retn
   269                              <1> 
   270                              <1> loc_ccd_load_child_dir:
   271                              <1> 	; AL = CCD_Level
   272 00007816 08C0                <1> 	or	al, al
   273 00007818 7468                <1> 	jz	short loc_ccd_load_root_dir
   274                              <1> 
   275 0000781A 6689C1              <1> 	mov	cx, ax
   276 0000781D C0E004              <1> 	shl	al, 4
   277 00007820 0FB6F0              <1> 	movzx	esi, al
   278 00007823 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   279                              <1> 
   280 00007825 8B460C              <1> 	mov	eax, [esi+12]
   281 00007828 38E9                <1> 	cmp	cl, ch
   282 0000782A 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   283 00007830 A3[9CCF0000]        <1> 	mov	[Current_Dir_FCluster], eax
   284                              <1> 
   285                              <1> loc_ccd_load_child_dir_next:
   286 00007835 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   287                              <1> 
   288                              <1>  	; Directory attribute : 10h
   289 00007838 B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   290                              <1> 	;mov	ah, 11001000b ; C8h
   291                              <1> 	; Volume name attribute: 8h
   292 0000783A B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   293                              <1> 
   294 0000783C 6631C9              <1> 	xor	cx, cx  
   295 0000783F E8B5010000          <1> 	call	locate_current_dir_file
   296 00007844 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   297                              <1> 
   298                              <1> 	 ; 19/02/2016
   299                              <1> 	;mov	edi, [CCD_DriveDT]
   300 00007846 8A25[87D80000]      <1> 	mov	ah, [CCD_Level]
   301 0000784C 803D[91D80000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   302 00007853 7509                <1> 	jne	short loc_ccd_load_child_dir_err
   303                              <1> 	; It is better to save recent successful part 
   304                              <1> 	; of the (requested) path as current directory.
   305                              <1> 	; (Otherwise the path would be reset to back
   306                              <1> 	; on the next 'CD' command.)
   307 00007855 88E1                <1> 	mov	cl, ah
   308 00007857 50                  <1> 	push	eax
   309 00007858 E8E3000000          <1> 	call	loc_ccd_save_current_dir
   310 0000785D 58                  <1> 	pop	eax
   311                              <1> loc_ccd_load_child_dir_err:            
   312 0000785E 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   313 00007860 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   314 00007862 F9                  <1> 	stc
   315 00007863 C3                  <1> 	retn
   316                              <1> 
   317                              <1> loc_ccd_path_not_found_retn:
   318 00007864 B003                <1> 	mov	al, 3	; Path not found
   319 00007866 C3                  <1> 	retn
   320                              <1> 
   321                              <1> loc_ccd_load_FAT_root_dir:
   322 00007867 803D[A1CF0000]02    <1> 	cmp	byte [Current_FATType], 2
   323 0000786E 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   324                              <1> 
   325                              <1> 	;mov	esi, [CCD_DriveDT]
   326                              <1> 	;push	esi
   327 00007870 E8961D0000          <1> 	call	load_FAT_root_directory
   328                              <1> 	;pop	edi ; Dos Drv Description Table
   329                              <1> 
   330 00007875 89F7                <1> 	mov	edi, esi
   331 00007877 BE[03D80000]        <1> 	mov	esi, PATH_Array
   332 0000787C 7297                <1> 	jc	short loc_ccd_retn_p
   333                              <1> 
   334 0000787E 31C0                <1> 	xor	eax, eax
   335 00007880 EB78                <1>         jmp	short loc_ccd_set_cdfc
   336                              <1> 
   337                              <1> loc_ccd_load_root_dir:
   338 00007882 803D[A1CF0000]01    <1> 	cmp	byte [Current_FATType], 1
   339 00007889 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   340                              <1> 
   341                              <1> loc_ccd_load_FS_root_dir:
   342 0000788B E8421E0000          <1> 	call	load_FS_root_directory
   343 00007890 EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   344                              <1> 
   345                              <1> loc_ccd_load_FS_sub_directory_next:
   346 00007892 E83C1E0000          <1> 	call	load_FS_sub_directory
   347 00007897 EB1F                <1> 	jmp	short pass_ccd_set_dir_cluster_ptr  
   348                              <1> 
   349                              <1> loc_ccd_set_dir_cluster_ptr:
   350                              <1> 	; EDI = Directory Entry
   351 00007899 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   352 0000789D C1E010              <1> 	shl	eax, 16
   353 000078A0 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   354                              <1> 
   355 000078A4 8B35[83D80000]      <1> 	mov	esi, [CCD_DriveDT]
   356 000078AA 803D[A1CF0000]01    <1> 	cmp	byte [Current_FATType], 1
   357 000078B1 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   358                              <1> 	;push	esi
   359 000078B3 E8DE1D0000          <1> 	call	load_FAT_sub_directory
   360                              <1> 	;pop	edi ; Dos Drv Description Table
   361                              <1> 
   362                              <1> pass_ccd_set_dir_cluster_ptr:
   363                              <1> 	;mov	edi, esi
   364 000078B8 BE[03D80000]        <1> 	mov	esi, PATH_Array
   365 000078BD 7264                <1> 	jc	short loc_ccd_retn_c
   366                              <1> 
   367 000078BF A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
   368                              <1> 
   369 000078C4 FE05[87D80000]      <1> 	inc	byte [CCD_Level]
   370 000078CA 0FB61D[87D80000]    <1> 	movzx	ebx, byte [CCD_Level]
   371 000078D1 C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   372 000078D4 01DE                <1> 	add	esi, ebx ; 19/02/2016
   373 000078D6 89460C              <1> 	mov	[esi+12], eax
   374 000078D9 EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   375                              <1> 
   376                              <1> loc_ccd_load_FAT32_root_dir:
   377 000078DB BE[03D80000]        <1> 	mov	esi, PATH_Array
   378 000078E0 8B460C              <1> 	mov	eax, [esi+12]
   379 000078E3 8B35[83D80000]      <1> 	mov	esi, [CCD_DriveDT]
   380                              <1>  
   381                              <1> loc_ccd_load_FAT_sub_directory:
   382                              <1> 	;push	esi
   383 000078E9 E8A81D0000          <1> 	call	load_FAT_sub_directory
   384                              <1> 	;pop	edi ; Dos Drv Description Table
   385                              <1> 
   386                              <1> pass_ccd_load_FAT_sub_directory:
   387                              <1> 	;mov	edi, esi
   388 000078EE BE[03D80000]        <1> 	mov	esi, PATH_Array
   389 000078F3 722E                <1> 	jc	short loc_ccd_retn_c
   390                              <1> 
   391 000078F5 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
   392                              <1> 
   393                              <1> loc_ccd_set_cdfc:
   394 000078FA 8A0D[87D80000]      <1> 	mov	cl, [CCD_Level]
   395 00007900 880D[A0CF0000]      <1> 	mov	[Current_Dir_Level], cl
   396 00007906 A3[9CCF0000]        <1> 	mov	[Current_Dir_FCluster], eax
   397                              <1> 
   398 0000790B 8A2D[88D80000]      <1> 	mov	ch, [Last_Dir_Level]
   399 00007911 38E9                <1> 	cmp	cl, ch 
   400 00007913 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   401                              <1> 	
   402 00007919 803D[91D80000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   403 00007920 741E                <1> 	je	short loc_ccd_save_current_dir
   404                              <1> 
   405                              <1>         ; jne -> don't save, restore (the previous cdir) later !
   406                              <1>         ; (saving the cdir would prevent previous cdir restoration!)
   407                              <1> 
   408 00007922 F8                  <1> 	clc
   409                              <1> 
   410                              <1> loc_ccd_retn_c:
   411 00007923 8B3D[83D80000]      <1> 	mov	edi, [CCD_DriveDT]
   412 00007929 C3                  <1> 	retn
   413                              <1> 
   414                              <1> loc_ccd_load_sub_directory:
   415 0000792A 8B35[83D80000]      <1> 	mov	esi, [CCD_DriveDT]
   416 00007930 803D[A1CF0000]01    <1> 	cmp	byte [Current_FATType], 1
   417 00007937 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   418 00007939 E8951D0000          <1> 	call	load_FS_sub_directory
   419 0000793E EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   420                              <1> 
   421                              <1> loc_ccd_save_current_dir:
   422 00007940 BE[03D80000]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   423 00007945 8B3D[83D80000]      <1> 	mov	edi, [CCD_DriveDT]
   424 0000794B 57                  <1> 	push	edi
   425 0000794C 83C77F              <1>         add     edi, LD_CDirLevel
   426 0000794F 880F                <1> 	mov	[edi], cl
   427 00007951 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   428 00007952 56                  <1> 	push	esi
   429                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   430 00007953 66B92000            <1> 	mov	cx, 32
   431 00007957 F3A5                <1> 	rep	movsd
   432                              <1> 	; Current directory has been saved to 
   433                              <1> 	; the DOS drive description table, cdir area !
   434 00007959 5E                  <1> 	pop	esi  ; PATH_Array
   435 0000795A 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   436                              <1> 
   437 0000795B C3                  <1> 	retn
   438                              <1> 
   439                              <1> parse_dir_name:
   440                              <1> 	; 11/02/2016
   441                              <1> 	; 10/02/2016
   442                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   443                              <1> 	; 18/09/2011
   444                              <1> 	; 17/10/2009
   445                              <1> 	; INPUT ->
   446                              <1> 	;	ESI = ASCIIZ Directory String Address
   447                              <1> 	;	AL = Current Directory Level
   448                              <1> 	;	EDI = Destination Adress
   449                              <1> 	;	     (8 levels, each one 12+4 byte)
   450                              <1> 	; OUTPUT ->
   451                              <1> 	;	EDI = Dir Entry Formatted Array
   452                              <1> 	;	     with zero cluster pointer at the last level
   453                              <1> 	;	AH = Last Dir Level
   454                              <1> 	;	AL = Current Dir Level
   455                              <1> 	;
   456                              <1> 	; (esi, ebx, ecx will be changed) 
   457                              <1> 
   458                              <1> 	;mov	[PATH_Array_Ptr], edi
   459 0000795C 88C4                <1> 	mov	ah, al
   460 0000795E 66A3[28D90000]      <1> 	mov	[PATH_CDLevel], ax
   461                              <1> repeat_ppdn_check_slash:
   462 00007964 AC                  <1> 	lodsb
   463 00007965 3C2F                <1> 	cmp	al, '/'
   464 00007967 74FB                <1> 	je	short repeat_ppdn_check_slash
   465 00007969 3C21                <1> 	cmp	al, 21h
   466 0000796B 7219                <1> 	jb	short loc_ppdn_retn
   467 0000796D 57                  <1> 	push	edi
   468                              <1> loc_ppdn_get_dir_name:
   469 0000796E B90C000000          <1> 	mov	ecx, 12
   470 00007973 BF[2AD90000]        <1> 	mov	edi, Dir_File_Name
   471                              <1> repeat_ppdn_get_dir_name:
   472 00007978 AA                  <1> 	stosb
   473 00007979 AC                  <1> 	lodsb
   474 0000797A 3C2F                <1> 	cmp	al, '/'
   475 0000797C 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   476 0000797E 3C20                <1> 	cmp	al, 20h
   477 00007980 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   478 00007982 E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   479 00007984 5F                  <1> 	pop	edi
   480 00007985 F9                  <1> 	stc
   481                              <1> loc_ppdn_retn:
   482 00007986 C3                  <1> 	retn
   483                              <1> 
   484                              <1> loc_ppdn_end_of_path_scan:
   485 00007987 4E                  <1> 	dec	esi
   486                              <1> loc_check_level_dot_conv_dir_name:
   487 00007988 31C0                <1> 	xor	eax, eax
   488 0000798A AA                  <1> 	stosb
   489 0000798B 89F3                <1> 	mov	ebx, esi
   490 0000798D BE[2AD90000]        <1> 	mov	esi, Dir_File_Name
   491 00007992 AC                  <1> 	lodsb
   492                              <1> repeat_ppdn_name_check_dot:
   493 00007993 3C2E                <1> 	cmp	al, '.'
   494 00007995 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   495                              <1> repeat_ppdn_name_dot_dot:
   496 00007997 AC                  <1> 	lodsb
   497 00007998 3C2E                <1> 	cmp	al, '.'
   498 0000799A 743E                <1> 	je	short loc_ppdn_dot_dot
   499 0000799C 3C21                <1> 	cmp	al, 21h
   500 0000799E 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   501                              <1> loc_ppdn_convert_sub_dir_name:
   502 000079A0 8A25[29D90000]      <1> 	mov	ah, [PATH_Level]
   503 000079A6 80FC07              <1> 	cmp	ah, 7
   504 000079A9 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   505 000079AB FEC4                <1> 	inc	ah  
   506 000079AD 8825[29D90000]      <1> 	mov	[PATH_Level], ah
   507 000079B3 BE[2AD90000]        <1> 	mov	esi, Dir_File_Name
   508                              <1> 	;mov	edi, [PATH_Array_Ptr]
   509 000079B8 B010                <1> 	mov	al, 16
   510 000079BA F6E4                <1> 	mul	ah
   511 000079BC 8B3C24              <1> 	mov	edi, [esp]
   512                              <1> 	;push	edi 
   513 000079BF 01C7                <1> 	add	edi, eax
   514 000079C1 E828030000          <1> 	call	convert_file_name
   515                              <1> 	;pop	edi
   516                              <1> pass_ppdn_convert_sub_dir_name:
   517 000079C6 89DE                <1> 	mov	esi, ebx
   518                              <1> repeat_ppdn_check_last_slash:
   519 000079C8 AC                  <1> 	lodsb
   520 000079C9 3C2F                <1> 	cmp	al, '/'
   521 000079CB 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   522 000079CD 3C21                <1> 	cmp	al, 21h
   523 000079CF 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   524                              <1> end_of_parse_dir_name:
   525 000079D1 5F                  <1> 	pop	edi
   526 000079D2 F5                  <1> 	cmc  
   527                              <1> 	;mov	al, [PATH_CDLevel]
   528                              <1> 	;mov	ah, [PATH_Level]
   529 000079D3 66A1[28D90000]      <1> 	mov	ax, [PATH_CDLevel]
   530 000079D9 C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_ppdn_dot_dot:
   533 000079DA AC                  <1> 	lodsb
   534 000079DB 3C21                <1> 	cmp	al, 21h
   535 000079DD 73F2                <1> 	jnb	short end_of_parse_dir_name 
   536                              <1> loc_ppdn_dot_dot_prev_level:
   537 000079DF 66A1[28D90000]      <1> 	mov	ax, [PATH_CDLevel]
   538 000079E5 80EC01              <1> 	sub	ah, 1
   539 000079E8 80D400              <1> 	adc	ah, 0
   540 000079EB 38E0                <1> 	cmp	al, ah
   541 000079ED 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   542 000079EF 88E0                <1> 	mov	al, ah
   543                              <1> pass_ppdn_set_al_to_ah:
   544 000079F1 66A3[28D90000]      <1> 	mov	[PATH_CDLevel], ax
   545 000079F7 EBCD                <1> 	jmp	short pass_ppdn_convert_sub_dir_name
   546                              <1> 
   547                              <1> locate_current_dir_file:
   548                              <1> 	; 14/02/2016
   549                              <1> 	; 13/02/2016
   550                              <1> 	; 10/02/2016
   551                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   552                              <1> 	; 14/08/2010
   553                              <1> 	; 19/09/2009
   554                              <1>         ; 2005
   555                              <1> 	; INPUT ->
   556                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   557                              <1> 	;	AL = Attributes Mask 
   558                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   559                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   560                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   561                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   562                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   563                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   564                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   565                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   566                              <1> 	;	     proper entry (which fits with Atributes Masks)
   567                              <1> 	;	CX = 0 Find Valid File/Directory/VolumeName
   568                              <1> 	;	? = Any One Char
   569                              <1> 	;	* = Every Chars
   570                              <1> 	; OUTPUT ->
   571                              <1> 	;	EDI = Directory Entry Address (in Directory Buffer)
   572                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   573                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   574                              <1> 	;	DL = Attributes
   575                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   576                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   577                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   578                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   579                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   580                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in EAX/AL
   581                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   582                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   583                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   584                              <1> 	;	CF = 0 -> 
   585                              <1> 	;	EBX = Current Directory Entry Index/Number (BX)
   586                              <1> 
   587                              <1> 	;mov	word [DirBuff_EntryCounter], 0 ; Zero Based
   588                              <1> 
   589 000079F9 8935[8BD80000]      <1> 	mov	[CDLF_FNAddress], esi
   590 000079FF 66A3[89D80000]      <1> 	mov	[CDLF_AttributesMask], ax
   591 00007A05 66890D[8FD80000]    <1> 	mov	[CDLF_DEType], cx
   592                              <1> 
   593 00007A0C 31DB                <1> 	xor	ebx, ebx
   594 00007A0E 881D[A0D80000]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   595                              <1> 
   596 00007A14 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
   597 00007A1A 381D[CCD70000]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   598 00007A20 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   599 00007A22 8A1D[CAD70000]      <1>         mov     bl, [DirBuff_DRV]
   600 00007A28 80EB41              <1> 	sub	bl, 'A'
   601 00007A2B 38DF                <1> 	cmp	bh, bl
   602 00007A2D 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   603 00007A2F 8B15[D1D70000]      <1> 	mov	edx, [DirBuff_Cluster]
   604 00007A35 3B15[9CCF0000]      <1> 	cmp	edx, [Current_Dir_FCluster]
   605 00007A3B 7412                <1> 	je	short loc_cdir_locatefile_search
   606                              <1> 
   607                              <1> loc_lcdf_reload_current_dir1:
   608 00007A3D 30DB                <1> 	xor	bl, bl
   609                              <1> loc_lcdf_reload_current_dir2:
   610 00007A3F 89DE                <1> 	mov	esi, ebx
   611 00007A41 81C600010900        <1>         add     esi, Logical_DOSDisks
   612 00007A47 E872000000          <1> 	call	reload_current_directory 
   613 00007A4C 735B                <1> 	jnc	short loc_locatefile_search_again 
   614 00007A4E C3                  <1> 	retn  
   615                              <1> 
   616                              <1> loc_cdir_locatefile_search:
   617 00007A4F 31DB                <1> 	xor	ebx, ebx
   618 00007A51 E8A5000000          <1> 	call	find_directory_entry
   619 00007A56 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   620                              <1> 
   621                              <1> loc_locatefile_check_stc_reason:
   622 00007A58 08ED                <1> 	or	ch, ch
   623 00007A5A 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   624                              <1> 
   625                              <1> loc_locatefile_check_next_entryblock:
   626 00007A5C 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
   627 00007A62 28DB                <1> 	sub	bl, bl
   628 00007A64 0FB7F3              <1> 	movzx	esi, bx
   629 00007A67 81C600010900        <1>         add     esi, Logical_DOSDisks
   630                              <1> 
   631 00007A6D 803D[A0CF0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
   632 00007A74 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   633                              <1>             
   634 00007A76 803D[A1CF0000]01    <1> 	cmp	byte [Current_FATType], 1
   635 00007A7D 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   636 00007A7F C3                  <1> 	retn  
   637                              <1> 
   638                              <1> loc_locatefile_check_FAT_type:
   639 00007A80 803D[A1CF0000]03    <1> 	cmp	byte [Current_FATType], 3
   640 00007A87 7218                <1> 	jb	short loc_cdir_locate_file_retn
   641                              <1> 
   642                              <1> loc_locatefile_load_subdir_cluster:
   643 00007A89 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
   644 00007A8E E81D1A0000          <1> 	call	get_next_cluster
   645 00007A93 730D                <1> 	jnc	short loc_locatefile_next_cluster
   646 00007A95 09C0                <1> 	or	eax, eax
   647 00007A97 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   648 00007A99 F9                  <1> 	stc
   649                              <1> loc_locatefile_file_notfound:
   650 00007A9A B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   651 00007A9F C3                  <1> 	retn
   652                              <1> 
   653                              <1> loc_locatefile_drive_not_ready_read_err:
   654                              <1> 	;mov	eax, 15h ;Drive not ready or read error
   655                              <1> loc_cdir_locate_file_stc_retn:
   656 00007AA0 F5                  <1> 	cmc ;stc
   657                              <1> loc_cdir_locate_file_retn:
   658 00007AA1 C3                  <1> 	retn
   659                              <1> 
   660                              <1> loc_locatefile_next_cluster:
   661 00007AA2 E8EF1B0000          <1> 	call	load_FAT_sub_directory
   662                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   663 00007AA7 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   664                              <1> 
   665                              <1> loc_locatefile_search_again:
   666 00007AA9 8B35[8BD80000]      <1> 	mov	esi, [CDLF_FNAddress] 
   667 00007AAF 66A1[89D80000]      <1> 	mov	ax, [CDLF_AttributesMask]
   668 00007AB5 668B0D[8FD80000]    <1> 	mov	cx, [CDLF_DEType] 
   669 00007ABC EB91                <1> 	jmp	short loc_cdir_locatefile_search
   670                              <1> 
   671                              <1> reload_current_directory:
   672                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   673                              <1> 	; 13/06/2010
   674                              <1> 	; 22/09/2009
   675                              <1>         ;
   676                              <1> 	; INPUT ->
   677                              <1> 	;	ESI = Dos drive description table address
   678                              <1> 	
   679                              <1> 	;mov	al, [esi+LD_FATType]
   680 00007ABE A0[A1CF0000]        <1> 	mov	al, [Current_FATType]
   681 00007AC3 3C02                <1> 	cmp	al, 2
   682 00007AC5 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   683 00007AC7 8A25[A0CF0000]      <1> 	mov	ah, [Current_Dir_Level]
   684 00007ACD 08C0                <1> 	or	al, al
   685 00007ACF 740A                <1> 	jz	short loc_reload_FS_directory
   686 00007AD1 08E4                <1> 	or	ah, ah
   687 00007AD3 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   688                              <1> loc_reload_FAT_12_16_root_directory:
   689 00007AD5 E8311B0000          <1> 	call	load_FAT_root_directory
   690 00007ADA C3                  <1> 	retn
   691                              <1> loc_reload_FS_directory:
   692 00007ADB 20E4                <1> 	and	ah, ah
   693 00007ADD 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   694                              <1> loc_reload_FS_root_directory: 
   695 00007ADF E8EE1B0000          <1> 	call	load_FS_root_directory
   696 00007AE4 C3                  <1> 	retn
   697                              <1> loc_reload_FS_sub_directory:
   698 00007AE5 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
   699 00007AEA E8E41B0000          <1> 	call	load_FS_sub_directory
   700 00007AEF C3                  <1> 	retn 
   701                              <1> loc_reload_FAT_sub_directory:
   702 00007AF0 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
   703 00007AF5 E89C1B0000          <1> 	call	load_FAT_sub_directory
   704 00007AFA C3                  <1> 	retn
   705                              <1> 
   706                              <1> find_directory_entry:
   707                              <1> 	; 14/02/2016
   708                              <1> 	; 13/02/2016
   709                              <1> 	; 10/02/2016
   710                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   711                              <1> 	; 14/08/2010 (DIR.ASM, "proc_find_direntry")
   712                              <1> 	; 19/09/2009
   713                              <1> 	; 2005
   714                              <1> 	; INPUT ->
   715                              <1> 	;	ESI = Sub Dir or File Name Address
   716                              <1> 	;	AL = Attributes Mask 
   717                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   718                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   719                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   720                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   721                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   722                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   723                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   724                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   725                              <1> 	;            proper entry (which fits with Atributes Masks)
   726                              <1> 	;	CX = 0 -> Find Valid File/Directory/VolumeName
   727                              <1> 	;	? = Any One Char
   728                              <1> 	;	* = Every Chars
   729                              <1> 	;	EBX = Current Dir Entry (BX)
   730                              <1> 	;
   731                              <1> 	; OUTPUT -> 
   732                              <1> 	;	EDI = Directory Entry Address (in DirectoryBuffer)
   733                              <1> 	;	ESI = Sub Dir or File Name Address
   734                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   735                              <1> 	;	DL = Attributes
   736                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   737                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   738                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   739                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   740                              <1> 	;	EBX = CurrentDirEntry (BX)
   741                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   742                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in AX/AL
   743                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   744                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   745                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   746                              <1> 	;
   747                              <1> 	; (EAX, EBX, ECX, EDX, EDI, EBP will be changed)	 
   748                              <1> 
   749 00007AFB 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   750 00007B02 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   751                              <1> 
   752                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   753                              <1> 
   754 00007B08 BF00000800          <1>   	mov	edi, Directory_Buffer
   755 00007B0D 66A3[9CD80000]      <1> 	mov	[FDE_AttrMask], ax
   756                              <1> 
   757 00007B13 29C0                <1> 	sub	eax, eax
   758                              <1>             
   759                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   760 00007B15 66A3[9ED80000]      <1> 	mov	[AmbiguousFileName], ax ; 0
   761                              <1> 
   762 00007B1B 6689D8              <1> 	mov	ax, bx
   763 00007B1E 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   764 00007B22 01C7                <1> 	add     edi, eax
   765                              <1> 
   766 00007B24 08ED                <1> 	or	ch, ch
   767 00007B26 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   768                              <1> 
   769 00007B2C 08C9                <1> 	or      cl, cl
   770 00007B2E 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   771                              <1>  
   772                              <1> check_find_dir_entry:
   773 00007B34 66A1[9CD80000]      <1> 	mov	ax, [FDE_AttrMask]
   774 00007B3A 8A2F                <1> 	mov	ch, [edi]
   775 00007B3C 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   776 00007B3F 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   777 00007B45 56                  <1> 	push	esi
   778 00007B46 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   779 00007B49 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   780 00007B4C 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   781                              <1> 
   782 00007B4E 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   783 00007B51 7505                <1> 	jne     short loc_check_attributes_mask
   784 00007B53 E8ED010000          <1> 	call	save_longname_sub_component
   785                              <1> 
   786                              <1> loc_check_attributes_mask:
   787 00007B58 88C6                <1> 	mov	dh, al
   788 00007B5A 20D6                <1> 	and	dh, dl    
   789 00007B5C 38F0                <1> 	cmp	al, dh
   790 00007B5E 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   791 00007B64 20D4                <1> 	and	ah, dl
   792 00007B66 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   793 00007B6C 80FA0F              <1> 	cmp	dl, 0Fh
   794 00007B6F 751A                <1> 	jne	short pass_direntry_attr_check
   795                              <1> 
   796 00007B71 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   797 00007B73 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   798                              <1> 
   799 00007B79 5E                  <1> 	pop	esi
   800 00007B7A 6631C0              <1> 	xor	ax, ax
   801 00007B7D 8A35[A0D80000]      <1> 	mov	dh, [PreviousAttr]
   802 00007B83 66891D[CDD70000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   803 00007B8A C3                  <1> 	retn
   804                              <1> 
   805                              <1> pass_direntry_attr_check:
   806 00007B8B 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   807 00007B8D B908000000          <1> 	mov	ecx, 8
   808                              <1> loc_lodsb_find_dir:
   809 00007B92 AC                  <1> 	lodsb
   810 00007B93 3C2A                <1> 	cmp	al, '*'
   811 00007B95 7508                <1> 	jne	short pass_fde_ambiguous1_check
   812 00007B97 FE05[9FD80000]      <1>         inc     byte [AmbiguousFileName+1]
   813 00007B9D EB28                <1> 	jmp	short loc_check_direntry_extension
   814                              <1> 
   815                              <1> pass_fde_ambiguous1_check:
   816 00007B9F 3C3F                <1> 	cmp	al, '?'
   817 00007BA1 750D                <1> 	jne	short pass_fde_ambiguous2_check
   818 00007BA3 FE05[9ED80000]      <1> 	inc	byte [AmbiguousFileName]
   819 00007BA9 803F20              <1> 	cmp	byte [edi], 20h
   820 00007BAC 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   821 00007BAE EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   822                              <1> 
   823                              <1> pass_fde_ambiguous2_check:
   824 00007BB0 3C20                <1> 	cmp	al, 20h
   825 00007BB2 750C                <1> 	jne	short loc_scasb_find_dir
   826 00007BB4 803F20              <1> 	cmp	byte [edi], 20h
   827 00007BB7 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   828 00007BB9 EB0C                <1> 	jmp	short loc_check_direntry_extension
   829                              <1> 
   830                              <1> loc_find_dir_next_entry_prevdeleted:
   831 00007BBB 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   832 00007BBE EB5E                <1> 	jmp	short loc_find_dir_next_entry
   833                              <1> 
   834                              <1> loc_scasb_find_dir:
   835 00007BC0 3A07                <1> 	cmp	al, [edi]
   836 00007BC2 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   837                              <1> loc_scasb_find_dir_inc_di:
   838 00007BC4 47                  <1> 	inc	edi
   839 00007BC5 E2CB                <1> 	loop	loc_lodsb_find_dir
   840                              <1> 
   841                              <1> loc_check_direntry_extension:
   842 00007BC7 BE08000000          <1> 	mov	esi, 8
   843 00007BCC 89F7                <1> 	mov	edi, esi ; 8
   844 00007BCE 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   845 00007BD1 01EF                <1> 	add	edi, ebp
   846 00007BD3 B103                <1> 	mov	cl, 3
   847                              <1> loc_lodsb_find_dir_ext:
   848 00007BD5 AC                  <1> 	lodsb
   849 00007BD6 3C2A                <1> 	cmp	al, '*'
   850 00007BD8 7508                <1> 	jne	short pass_fde_ambiguous3_check
   851 00007BDA FE05[9FD80000]      <1> 	inc	byte [AmbiguousFileName+1]
   852 00007BE0 EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   853                              <1> 
   854                              <1> pass_fde_ambiguous3_check:
   855 00007BE2 3C3F                <1> 	cmp	al, '?'
   856 00007BE4 750D                <1> 	jne	short pass_fde_ambiguous4_check
   857 00007BE6 FE05[9ED80000]      <1> 	inc	byte [AmbiguousFileName]
   858 00007BEC 803F20              <1> 	cmp	byte [edi], 20h
   859 00007BEF 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   860 00007BF1 EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   861                              <1> 
   862                              <1> pass_fde_ambiguous4_check:
   863 00007BF3 3C20                <1> 	cmp	al, 20h
   864 00007BF5 7541                <1> 	jne	short loc_scasb_find_dir_ext
   865 00007BF7 803F20              <1> 	cmp	byte [edi], 20h
   866 00007BFA 7404                <1> 	je	short loc_find_dir_proper_direntry
   867                              <1> 
   868                              <1> loc_find_dir_next_entry_ebp:
   869 00007BFC 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   870 00007BFE EB1E                <1> 	jmp	short loc_find_dir_next_entry
   871                              <1> 
   872                              <1> loc_find_dir_proper_direntry:
   873 00007C00 30C9                <1> 	xor	cl, cl
   874                              <1> loc_find_dir_proper_direntry_1:
   875 00007C02 5E                  <1> 	pop	esi
   876 00007C03 89EF                <1>         mov     edi, ebp
   877 00007C05 8A2F                <1> 	mov	ch, [edi]
   878 00007C07 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   879 00007C0A 66A1[9ED80000]      <1> 	mov	ax, [AmbiguousFileName]
   880                              <1> loc_find_dir_proper_direntry_2:
   881 00007C10 8A35[A0D80000]      <1> 	mov     dh, [PreviousAttr]
   882 00007C16 66891D[CDD70000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   883 00007C1D C3                  <1> 	retn
   884                              <1> 
   885                              <1> loc_find_dir_next_entry:
   886 00007C1E 8815[A0D80000]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   887                              <1> loc_find_dir_next_entry_1:
   888 00007C24 5E                  <1> 	pop	esi
   889 00007C25 83C720              <1> 	add	edi, 32
   890                              <1> 	;inc	word [DirBuff_EntryCounter]
   891 00007C28 6643                <1> 	inc	bx
   892 00007C2A 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   893 00007C31 770E                <1> 	ja	short loc_ffde_stc_retn_255
   894 00007C33 E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   895                              <1> 
   896                              <1> loc_scasb_find_dir_ext:
   897 00007C38 3A07                <1> 	cmp	al, [edi]
   898 00007C3A 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   899                              <1> loc_scasb_find_dir_ext_inc_di:
   900 00007C3C 47                  <1> 	inc	edi
   901 00007C3D E296                <1> 	loop    loc_lodsb_find_dir_ext
   902 00007C3F EBC1                <1> 	jmp	short loc_find_dir_proper_direntry_1
   903                              <1> 
   904                              <1> loc_ffde_stc_retn_255:
   905                              <1> 	;mov	cx, 0FFFFh
   906 00007C41 31C9                <1> 	xor	ecx, ecx
   907 00007C43 49                  <1> 	dec	ecx ; 0FFFFFFFFh
   908                              <1> 	;xor	eax, eax
   909                              <1> loc_find_direntry_stc_retn:
   910                              <1> loc_check_ffde_retn_1:
   911                              <1> 	;mov	ax, 2
   912 00007C44 B802000000          <1> 	mov	eax, 2 ; File Not Found
   913 00007C49 8A35[A0D80000]      <1> 	mov	dh, [PreviousAttr]
   914 00007C4F 66891D[CDD70000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   915 00007C56 F9                  <1> 	stc
   916 00007C57 C3                  <1> 	retn
   917                              <1> 
   918                              <1> loc_find_free_deleted_entry_0:
   919 00007C58 66A1[9CD80000]      <1> 	mov	ax, [FDE_AttrMask]
   920 00007C5E 8A2F                <1> 	mov	ch, [edi]
   921 00007C60 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   922 00007C63 08C9                <1> 	or	cl, cl 
   923 00007C65 7407                <1> 	jz	short loc_check_ffde_0_repeat
   924                              <1> 	;cmp	cl, 0E5h
   925                              <1> 	;je	short pass_loc_check_ffde_0_err
   926 00007C67 80F9FF              <1> 	cmp	cl, 0FFh
   927 00007C6A 7432                <1> 	je	short loc_find_free_deleted_entry_1
   928 00007C6C EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   929                              <1> 
   930                              <1> loc_check_ffde_0_repeat:
   931 00007C6E 08ED                <1> 	or	ch, ch
   932 00007C70 7511                <1> 	jnz	short loc_check_ffde_0_next
   933                              <1> 
   934                              <1> loc_check_ffde_retn_2:
   935 00007C72 6629C0              <1> 	sub	ax, ax
   936 00007C75 8A35[A0D80000]      <1> 	mov	dh, [PreviousAttr]
   937 00007C7B 66891D[CDD70000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   938 00007C82 C3                  <1> 	retn
   939                              <1>  
   940                              <1> loc_check_ffde_0_next:
   941 00007C83 6643                <1> 	inc	bx
   942 00007C85 83C720              <1> 	add	edi, 32
   943                              <1> 	;inc	word [DirBuff_EntryCounter]
   944                              <1> 	 
   945 00007C88 663B1D[CFD70000]    <1>         cmp	bx, [DirBuff_LastEntry]
   946 00007C8F 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   947 00007C91 8815[A0D80000]      <1> 	mov	[PreviousAttr], dl
   948 00007C97 8A2F                <1> 	mov	ch, [edi]
   949 00007C99 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   950 00007C9C EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   951                              <1> 
   952                              <1> loc_find_free_deleted_entry_1:
   953 00007C9E 28D2                <1> 	sub	dl, dl      
   954                              <1> loc_find_free_deleted_entry_2:
   955 00007CA0 20ED                <1> 	and	ch, ch  
   956 00007CA2 74CE                <1> 	jz	short loc_check_ffde_retn_2
   957 00007CA4 80FDE5              <1> 	cmp	ch, 0E5h
   958 00007CA7 74C9                <1> 	je	short loc_check_ffde_retn_2
   959 00007CA9 6643                <1> 	inc	bx
   960 00007CAB 83C720              <1> 	add	edi, 32
   961 00007CAE 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   962 00007CB5 778A                <1> 	ja	short loc_ffde_stc_retn_255
   963 00007CB7 8A2F                <1> 	mov	ch, [edi]
   964 00007CB9 EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   965                              <1> 
   966                              <1> pass_loc_check_ffde_0_err:
   967 00007CBB 38CD                <1> 	cmp	ch, cl
   968 00007CBD 741F                <1> 	je	short loc_check_ffde_attrib 
   969                              <1> 
   970 00007CBF 6643                <1> 	inc	bx
   971 00007CC1 83C720              <1> 	add	edi, 32
   972 00007CC4 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   973 00007CCB 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   974 00007CD1 8815[A0D80000]      <1> 	mov	[PreviousAttr], dl
   975 00007CD7 8A2F                <1> 	mov	ch, [edi]
   976 00007CD9 8A570B              <1> 	mov	dl, [edi+0Bh]
   977 00007CDC EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   978                              <1> 
   979                              <1> loc_check_ffde_attrib:
   980 00007CDE 88C6                <1> 	mov	dh, al
   981 00007CE0 20D6                <1> 	and	dh, dl    
   982 00007CE2 38F0                <1> 	cmp	al, dh
   983 00007CE4 759D                <1> 	jne	short loc_check_ffde_0_next
   984 00007CE6 20D4                <1> 	and	ah, dl
   985 00007CE8 7599                <1> 	jnz	short loc_check_ffde_0_next
   986 00007CEA 30C9                <1> 	xor	cl, cl 
   987 00007CEC EB84                <1>         jmp     loc_check_ffde_retn_2
   988                              <1> 
   989                              <1> convert_file_name:
   990                              <1> 	; 06/03/2016
   991                              <1> 	; 11/02/2016
   992                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   993                              <1> 	; 06/10/2009
   994                              <1> 	; 2005
   995                              <1> 	;
   996                              <1> 	; INPUT  ->
   997                              <1> 	;	ESI = Dot File Name Location
   998                              <1> 	;	EDI = Dir Entry Format File Name Location
   999                              <1> 	; OUTPUT ->
  1000                              <1> 	;	EDI = Dir Entry Format File Name Location
  1001                              <1> 	;	ESI = Dot File Name Location (capitalized)
  1002                              <1> 	;
  1003                              <1> 	; (ECX, AL will be changed) 
  1004                              <1>      
  1005 00007CEE 56                  <1> 	push	esi  
  1006 00007CEF 57                  <1> 	push	edi
  1007                              <1> 
  1008 00007CF0 B90B000000          <1> 	mov	ecx, 11
  1009 00007CF5 B020                <1> 	mov	al, 20h
  1010 00007CF7 F3AA                <1> 	rep	stosb
  1011                              <1> 
  1012 00007CF9 8B3C24              <1> 	mov	edi, [esp]
  1013                              <1> 
  1014 00007CFC B10C                <1> 	mov	cl, 12 ; file name length (max.)
  1015                              <1> 	; 06/03/2016
  1016                              <1> 	; Directory entry name limit (11 bytes) check for
  1017                              <1> 	; 'rename_directory_entry' procedure.
  1018                              <1> 	; (EDI points to Directory Entry)
  1019                              <1> 	; (If the file name would not contain a dot
  1020                              <1> 	; and file name length would be 12, this would cause to
  1021                              <1> 	; overwrite the attributes byte of the directory entry.)
  1022                              <1> 	;
  1023 00007CFE B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1024                              <1> loc_check_first_dot:
  1025 00007D00 8A06                <1> 	mov	al, [esi]
  1026 00007D02 3C2E                <1> 	cmp	al, 2Eh
  1027 00007D04 750C                <1> 	jne	short pass_check_first_dot
  1028 00007D06 8807                <1> 	mov	[edi], al
  1029 00007D08 47                  <1> 	inc	edi
  1030 00007D09 46                  <1> 	inc	esi
  1031 00007D0A FEC9                <1> 	dec	cl
  1032 00007D0C 75F2                <1> 	jnz	short loc_check_first_dot
  1033                              <1> 	;;(ecx <= 12)
  1034                              <1> 	;;loop	loc_check_first_dot 
  1035 00007D0E EB30                <1> 	jmp	short stop_convert_file
  1036                              <1> 
  1037                              <1> loc_get_fchar:
  1038 00007D10 8A06                <1> 	mov	al, [esi]
  1039                              <1> pass_check_first_dot:
  1040 00007D12 3C61                <1> 	cmp	al, 61h ; 'a'
  1041 00007D14 7208                <1> 	jb	short pass_name_capitalize
  1042 00007D16 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1043 00007D18 7704                <1> 	ja	short pass_name_capitalize
  1044 00007D1A 24DF                <1> 	and	al, 0DFh
  1045 00007D1C 8806                <1> 	mov	[esi], al
  1046                              <1> pass_name_capitalize:
  1047 00007D1E 3C21                <1> 	cmp	al, 21h
  1048 00007D20 721E                <1> 	jb	short stop_convert_file
  1049 00007D22 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1050 00007D24 750C                <1> 	jne	short pass_dot_space
  1051                              <1> add_dot_space: 
  1052 00007D26 80F904              <1> 	cmp	cl, 4
  1053 00007D29 760E                <1> 	jna	short inc_and_loop
  1054 00007D2B 47                  <1> 	inc	edi
  1055 00007D2C FECD                <1> 	dec	ch ; 06/03/2016
  1056 00007D2E FEC9                <1> 	dec	cl
  1057 00007D30 EBF4                <1> 	jmp	short add_dot_space
  1058                              <1> 	
  1059                              <1> 	;mov	al, 4
  1060                              <1> 	;cmp	cl, al
  1061                              <1> 	;jna	short inc_and_loop
  1062                              <1> 	;sub	cl, al
  1063                              <1> 	;add	edi, ecx
  1064                              <1> 	;mov	cl, al
  1065                              <1> 	;jmp	short inc_and_loop	
  1066                              <1> 
  1067                              <1> pass_dot_space:
  1068 00007D32 8807                <1> 	mov	[edi], al
  1069                              <1> loc_after_double_dot:
  1070                              <1> 	; 06/03/2016
  1071 00007D34 FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1072 00007D36 740A                <1> 	jz	short stop_convert_file_x
  1073 00007D38 47                  <1> 	inc	edi
  1074                              <1> inc_and_loop:
  1075 00007D39 FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1076 00007D3B 7403                <1> 	jz	short stop_convert_file	
  1077 00007D3D 46                  <1> 	inc	esi
  1078                              <1> 	;;(ecx <= 12)
  1079                              <1> 	;;loop	loc_get_fchar
  1080 00007D3E EBD0                <1> 	jmp	short loc_get_fchar
  1081                              <1> 
  1082                              <1> stop_convert_file:
  1083                              <1> 	; 06/03/2016
  1084 00007D40 30ED                <1> 	xor	ch, ch
  1085                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1086                              <1> stop_convert_file_x:
  1087 00007D42 5F                  <1> 	pop	edi
  1088 00007D43 5E                  <1> 	pop	esi
  1089 00007D44 C3                  <1> 	retn
  1090                              <1>  
  1091                              <1> save_longname_sub_component:
  1092                              <1> 	; 13/02/2016
  1093                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
  1094                              <1> 	; 28/02/2010
  1095                              <1> 	; 17/10/2009
  1096                              <1> 	; INPUT ->
  1097                              <1> 	;	EDI = Directory Entry    
  1098                              <1> 	;     	// This procedure is called
  1099                              <1> 	;	// from 'find_directory_entry' procedure.
  1100                              <1> 	;	// If the last entry returns with
  1101                              <1> 	;	// a non-zero LongnameFound value and
  1102                              <1> 	;	// if LFN_CheckSum value is equal to
  1103                              <1> 	;	// the next shortname checksum,
  1104                              <1> 	;	// long name is valid.
  1105                              <1> 	;	// If a longname is longer than 65 bytes,
  1106                              <1> 	;	// it is invalid for trdos. (>45h)
  1107                              <1>  
  1108 00007D45 57                  <1> 	push	edi
  1109 00007D46 56                  <1> 	push	esi
  1110                              <1> 	;push	ebx
  1111                              <1> 	;push	ecx
  1112                              <1> 	;push	edx
  1113 00007D47 50                  <1> 	push	eax
  1114                              <1>            
  1115 00007D48 29C9                <1> 	sub	ecx, ecx
  1116                              <1> 	;sub	eax, eax
  1117 00007D4A B11A                <1> 	mov	cl, 26
  1118                              <1> 
  1119 00007D4C 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1120 00007D4F 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1121 00007D51 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1122                              <1> 
  1123 00007D53 88C4                <1> 	mov	ah, al
  1124 00007D55 80EC40              <1> 	sub	ah, 40h
  1125 00007D58 8825[A2D80000]      <1> 	mov	[LFN_EntryLength], ah
  1126                              <1> 	
  1127 00007D5E 3C45                <1> 	cmp	al, 45h  ; 40h (last long entry sign) + 5
  1128                              <1>  		; Max 130 byte length is usable in TRDOS
  1129                              <1> ; 26*5 = 130
  1130 00007D60 7753                <1> 	ja	short loc_pslnsc_retn
  1131                              <1> 
  1132 00007D62 2407                <1> 	and	al, 07h ; 0Fh
  1133 00007D64 A2[A1D80000]        <1> 	mov	[LongNameFound], al
  1134                              <1> 
  1135 00007D69 FEC8                <1> 	dec	al
  1136                              <1> 	;mov	cl, 26
  1137 00007D6B F6E1                <1> 	mul	cl
  1138                              <1> 
  1139 00007D6D 89C6                <1> 	mov	esi, eax
  1140 00007D6F 01CE                <1> 	add	esi, ecx
  1141                              <1> 		; to make is an ASCIZZ string
  1142                              <1> 		; with ax+26 bytes length
  1143 00007D71 81C6[A4D80000]      <1> 	add	esi, LongFileName
  1144 00007D77 66C7060000          <1> 	mov	word [esi], 0   
  1145 00007D7C EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1146                              <1> 
  1147                              <1> pass_pslnsc_last_long_entry:
  1148 00007D7E 3C04                <1> 	cmp	al, 04h
  1149 00007D80 7733                <1> 	ja	short loc_pslnsc_retn
  1150 00007D82 FE0D[A1D80000]      <1> 	dec	byte [LongNameFound]
  1151 00007D88 3A05[A1D80000]      <1> 	cmp	al, [LongNameFound]
  1152 00007D8E 7525                <1> 	jne	short loc_pslnsc_retn
  1153                              <1> 
  1154                              <1> loc_pslsc_move_ldir_name1:
  1155 00007D90 FEC8                <1> 	dec	al
  1156                              <1> 	;mov	cl, 26
  1157 00007D92 F6E1                <1> 	mul	cl
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name2:
  1160 00007D94 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1161 00007D97 880D[A3D80000]      <1> 	mov	[LFN_CheckSum], cl 
  1162 00007D9D 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1163 00007D9F BF[A4D80000]        <1> 	mov	edi, LongFileName
  1164 00007DA4 01C7                <1> 	add	edi, eax
  1165 00007DA6 46                  <1> 	inc	esi
  1166 00007DA7 B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1167 00007DA9 F366A5              <1> 	rep	movsw
  1168 00007DAC 83C603              <1> 	add	esi, 3
  1169 00007DAF A5                  <1> 	movsd	; char 6 & 7 
  1170 00007DB0 A5                  <1> 	movsd	; char 8 & 9
  1171 00007DB1 A5                  <1> 	movsd	; char 10 & 11
  1172 00007DB2 46                  <1> 	inc	esi
  1173 00007DB3 46                  <1> 	inc	esi 
  1174 00007DB4 A5                  <1> 	movsd   ; char 12 & 13 
  1175                              <1> 
  1176                              <1> loc_pslnsc_retn:
  1177 00007DB5 58                  <1>  	pop	eax
  1178                              <1> 	;pop	edx
  1179                              <1> 	;pop	ecx
  1180                              <1> 	;pop	ebx
  1181 00007DB6 5E                  <1> 	pop	esi  
  1182 00007DB7 5F                  <1> 	pop	edi
  1183                              <1>  
  1184 00007DB8 C3                  <1>     	retn
  1185                              <1> 
  1186                              <1> parse_path_name:
  1187                              <1> 	; 10/02/2016
  1188                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  1189                              <1> 	; 10/009/2011 ('proc_parse_pathname')
  1190                              <1> 	; 27/11/2009
  1191                              <1> 	; 05/12/2004
  1192                              <1> 	;
  1193                              <1> 	; INPUT ->
  1194                              <1> 	;	ESI = Beginning of ASCIIZ pathname string
  1195                              <1> 	;       EDI = Destination Address
  1196                              <1> 	;	      (which is TR-DOS FindFile data buffer)
  1197                              <1> 	; OUTPUT ->
  1198                              <1> 	;	CF = 1 -> Error
  1199                              <1> 	;	     EAX = Error Code (AL)
  1200                              <1> 	;
  1201                              <1> 	; (Modified registers: eax, ecx, esi, edi) 
  1202                              <1> 	
  1203                              <1> 	; Clear the pathname bytes in TR-DOS Findfile data buffer 
  1204 00007DB9 57                  <1> 	push	edi
  1205 00007DBA B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1206 00007DBF 31C0                <1> 	xor	eax, eax
  1207 00007DC1 F3AB                <1> 	rep	stosd 
  1208 00007DC3 5F                  <1> 	pop	edi
  1209                              <1> 
  1210 00007DC4 668B06              <1> 	mov	ax, [esi]
  1211 00007DC7 80FC3A              <1> 	cmp	ah, ':'
  1212 00007DCA 741C                <1> 	je	short loc_ppn_change_drive
  1213 00007DCC A0[A2CF0000]        <1> 	mov	al, [Current_Drv]
  1214 00007DD1 EB33                <1> 	jmp	short pass_ppn_change_drive
  1215                              <1> 
  1216                              <1> pass_ppn_cdir:
  1217 00007DD3 8B35[C6D90000]      <1> 	mov	esi, [First_Path_Pos]
  1218 00007DD9 AC                  <1> 	lodsb
  1219                              <1> loc_ppn_get_filename:
  1220 00007DDA 83C741              <1> 	add	edi, 65 ; FindFile_Name location
  1221                              <1> 	; TRDOS Filename length must not be more than 12 bytes
  1222                              <1> 	;mov	ecx, 12
  1223 00007DDD B10C                <1> 	mov	cl, 12
  1224                              <1> loc_ppn_get_fnchar_next:
  1225 00007DDF AA                  <1> 	stosb
  1226 00007DE0 AC                  <1> 	lodsb
  1227 00007DE1 3C21                <1> 	cmp	al, 21h
  1228 00007DE3 7274                <1> 	jb	short loc_ppn_clc_return 
  1229 00007DE5 E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1230                              <1> loc_ppn_return:
  1231 00007DE7 C3                  <1> 	retn
  1232                              <1> 
  1233                              <1> loc_ppn_change_drive:
  1234 00007DE8 24DF                <1> 	and	al, 0DFh
  1235 00007DEA 2C41                <1> 	sub	al, 'A'; A:
  1236 00007DEC 726F                <1> 	jc	short loc_ppn_invalid_drive
  1237 00007DEE 3805[C5BD0000]      <1> 	cmp	[Last_DOS_DiskNo], al
  1238 00007DF4 7267                <1> 	jb	short loc_ppn_invalid_drive
  1239                              <1> 
  1240 00007DF6 46                  <1> 	inc	esi
  1241 00007DF7 46                  <1> 	inc	esi
  1242 00007DF8 8A26                <1> 	mov	ah, [esi]
  1243 00007DFA 80FC21              <1> 	cmp	ah, 21h
  1244 00007DFD 7307                <1> 	jnb	short pass_ppn_change_drive
  1245                              <1> 
  1246                              <1> loc_ppn_cmd_failed:
  1247                              <1> 	; File or directory name is not existing
  1248 00007DFF 8807                <1> 	mov	[edi], al ; Drv 
  1249 00007E01 66B80100            <1> 	mov	ax, 1 ; eax = 1
  1250                              <1> 	; TR-DOS Error Code 1h = Bad Command Argument
  1251                              <1> 	; MS-DOS Error Code 1h : Invalid Function Number
  1252                              <1> 	;stc
  1253                              <1> 	; (MainProg ErrMsg: "Bad command or file name!")
  1254 00007E05 C3                  <1> 	retn
  1255                              <1> 
  1256                              <1> pass_ppn_change_drive:
  1257 00007E06 8935[C6D90000]      <1> 	mov	[First_Path_Pos], esi
  1258 00007E0C C705[CAD90000]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1258 00007E14 0000                <1>
  1259 00007E16 AA                  <1> 	stosb
  1260 00007E17 8A06                <1> 	mov	al, [esi]
  1261                              <1> loc_scan_ppn_dslash:
  1262 00007E19 3C2F                <1> 	cmp	al, '/'
  1263 00007E1B 7506                <1>   	jne	short loc_scan_next_slash_pos
  1264 00007E1D 8935[CAD90000]      <1> 	mov	[Last_Slash_Pos], esi
  1265                              <1> loc_scan_next_slash_pos:
  1266 00007E23 46                  <1> 	inc	esi
  1267 00007E24 8A06                <1> 	mov	al, [esi]
  1268 00007E26 3C20                <1> 	cmp	al, 20h
  1269 00007E28 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1270 00007E2A 833D[CAD90000]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1271 00007E31 76A0                <1> 	jna	short pass_ppn_cdir
  1272                              <1> 	
  1273 00007E33 8B0D[CAD90000]      <1> 	mov	ecx, [Last_Slash_Pos]
  1274 00007E39 8B35[C6D90000]      <1> 	mov	esi, [First_Path_Pos]
  1275 00007E3F 29F1                <1> 	sub	ecx, esi
  1276 00007E41 41                  <1> 	inc	ecx
  1277                              <1> 	;cmp	ecx, 64
  1278 00007E42 80F940              <1> 	cmp	cl, 64
  1279 00007E45 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1280                              <1> 
  1281 00007E47 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1282 00007E49 F3A4                <1> 	rep	movsb
  1283                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1284 00007E4B 8B35[CAD90000]      <1> 	mov	esi, [Last_Slash_Pos]
  1285 00007E51 46                  <1> 	inc	esi
  1286 00007E52 89C7                <1> 	mov	edi, eax
  1287 00007E54 AC                  <1> 	lodsb
  1288 00007E55 3C21                <1> 	cmp	al, 21h
  1289 00007E57 7381                <1> 	jnb	short loc_ppn_get_filename
  1290                              <1> loc_ppn_clc_return:
  1291                              <1> 	;clc
  1292 00007E59 31C0                <1> 	xor	eax, eax
  1293 00007E5B C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> loc_ppn_invalid_drive_stc:
  1296 00007E5C F5                  <1> 	cmc	 ; stc
  1297                              <1> loc_ppn_invalid_drive:
  1298                              <1> 	; cf = 1
  1299                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1300 00007E5D 66B80F00            <1> 	mov	ax, 0Fh
  1301                              <1> 	; MS-DOS Error Code 0Fh = Disk Drive Invalid 
  1302                              <1> 	; (MainProg ErrMsg: "Drive not ready or read error!")
  1303 00007E61 C3                  <1> 	retn
  1304                              <1> 
  1305                              <1> find_longname:
  1306                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1307                              <1> 	; 24/01/2010 (DIR.ASM, 'proc_find_longname')
  1308                              <1> 	; 17/10/2009
  1309                              <1> 	
  1310                              <1> 	; INPUT -> 
  1311                              <1> 	;	ESI = DOS short file name address
  1312                              <1> 	; 	for example: "filename.ext"
  1313                              <1> 	;
  1314                              <1> 	; OUTPUT ->
  1315                              <1> 	; 	ESI = ASCIIZ longname address (cf = 0)
  1316                              <1> 	;	cf = 1 -> error number returns in EAX (AL)
  1317                              <1> 	;	AL = 0 & CF=1 -> longname not found
  1318                              <1> 	;	     the file/directory has no longname
  1319                              <1> 	; 	cf = 0 -> AL = FAT Type 
  1320                              <1>  
  1321                              <1> 	; 17/10/2009
  1322                              <1> 	; ASCIIZ string will be returned
  1323                              <1> 	; as LongFileName
  1324                              <1> 	; clearing/reset is not needed
  1325                              <1> 	;mov	ecx, 33
  1326                              <1> 	;mov	edi, LongFileName
  1327                              <1> 	;sub	ax, ax ; 0
  1328                              <1> 	;rep	stosw
  1329                              <1> 
  1330                              <1> 	;mov	byte [LongNameFound], 0
  1331                              <1> 
  1332                              <1> 	; ESI = ASCIIZ file/directory name address
  1333                              <1> 	;   AL = Attributes AND mask 
  1334                              <1> 	;	(Result of AND must be equal to AL)
  1335                              <1> 	;   AH = Negative attributes mask 
  1336                              <1> 	;	(Result of AND must be ZERO)
  1337 00007E62 66B80008            <1> 	mov	ax, 0800h 
  1338                              <1> 		; it must not be volume name or longname
  1339 00007E66 E84EDDFFFF          <1> 	call	find_first_file
  1340 00007E6B 7216                <1> 	jc	short loc_fln_retn
  1341                              <1>  
  1342                              <1> loc_fln_check_FAT_Type:
  1343 00007E6D 803D[A1CF0000]01    <1> 	cmp	byte [Current_FATType], 1
  1344 00007E74 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1345                              <1> 
  1346 00007E76 E839000000          <1> 	call	get_fs_longname
  1347 00007E7B C3                  <1> 	retn
  1348                              <1> 
  1349                              <1> loc_fln_check_longname_yes_sign:
  1350 00007E7C 08FF                <1> 	or	bh, bh
  1351 00007E7E 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1352                              <1> loc_fln_longname_not_found_retn:
  1353 00007E80 31C0                <1> 	xor	eax, eax 
  1354                              <1> 	; cf = 1 & al = 0 -> longname not found
  1355 00007E82 F9                  <1> 	stc
  1356                              <1> loc_fln_retn:
  1357 00007E83 C3                  <1> 	retn
  1358                              <1> 
  1359                              <1> loc_fln_check_longnamefound_number:
  1360                              <1> 	; 'LongNameFound' is set by
  1361                              <1>         ; by 'save_longname_sub_component'
  1362                              <1> 	; which is called from
  1363                              <1> 	; 'find_directory_entry' 
  1364                              <1> 	; which is called from 
  1365                              <1> 	; 'find_first_file'
  1366                              <1> 	; It must 1 if the longname is valid
  1367 00007E84 803D[A1D80000]01    <1>         cmp     byte [LongNameFound], 1
  1368 00007E8B 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1369                              <1>              
  1370                              <1> loc_fln_calculate_checksum: 
  1371 00007E8D E813000000          <1> 	call	calculate_checksum
  1372                              <1> 	; AL = shortname checksum
  1373                              <1> 
  1374                              <1> loc_fln_longname_validation:
  1375                              <1> 	; 'LFN_CheckSum' has been set already
  1376                              <1> 	; by 'save_longname_sub_component'
  1377                              <1> 	; which is called from
  1378                              <1> 	; 'find_directory_entry' 
  1379                              <1> 	; which is called from 
  1380                              <1> 	; 'find_first_file'
  1381 00007E92 3805[A3D80000]      <1> 	cmp	[LFN_CheckSum], al
  1382 00007E98 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1383                              <1> 
  1384 00007E9A BE[A4D80000]        <1> 	mov	esi, LongFileName
  1385 00007E9F A0[A1CF0000]        <1> 	mov	al, [Current_FATType]
  1386 00007EA4 C3                  <1> 	retn
  1387                              <1> 
  1388                              <1> calculate_checksum:
  1389                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1390                              <1> 	; 17/10/2009 (DIR.ASM, 'proc_calculate_checksum')
  1391                              <1>         ;    
  1392                              <1> 	; INPUT ->
  1393                              <1> 	;	ESI = 11 byte DOS File Name location
  1394                              <1> 	;	(in DOS Directory Entry Format)
  1395                              <1> 	; OUTPUT ->
  1396                              <1> 	;	 AL = 8 bit checksum (CRC) value
  1397                              <1> 	;
  1398                              <1> 	; (Modified registers: EAX, ECX, ESI)
  1399                              <1> 
  1400                              <1> 	; Erdogan Tan [ 17-10-2009 ]
  1401                              <1> 	;  'ror al, 1' instruction
  1402                              <1> 
  1403                              <1> 	; Erdogan Tan [ 20-06-2004 ]
  1404                              <1> 	; This 8086 assembly code is an original code
  1405                              <1> 	; which is adapted from C code in
  1406                              <1> 	; Microsoft FAT32 File System Specification
  1407                              <1> 	; Version 1.03, December 6, 2000
  1408                              <1> 	; Page 28
  1409                              <1> 
  1410 00007EA5 30C0                <1> 	xor	al, al
  1411 00007EA7 B90B000000          <1> 	mov	ecx, 11
  1412                              <1> loc_next_sum:
  1413                              <1> 	;xor	ah, ah
  1414                              <1> 	;test	al, 1
  1415                              <1> 	;jz	short pass_ah_80h
  1416                              <1> 	;mov	ah, 80h
  1417                              <1> ;pass_ah_80h:
  1418                              <1> 	;shr	al, 1
  1419 00007EAC D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1420 00007EAE 0206                <1> 	add	al, [esi]
  1421 00007EB0 46                  <1> 	inc	esi
  1422                              <1> 	;add	al, ah
  1423 00007EB1 E2F9                <1> 	loop	loc_next_sum
  1424 00007EB3 C3                  <1> 	retn
  1425                              <1> 
  1426                              <1> get_fs_longname:
  1427                              <1> 	; temporary (13/02/2016)
  1428 00007EB4 31C0                <1> 	xor eax, eax
  1429 00007EB6 F9                  <1> 	stc
  1430 00007EB7 C3                  <1> 	retn
  1431                              <1> 
  1432                              <1> make_sub_directory:
  1433                              <1> 	; 03/03/2016
  1434                              <1> 	; 02/03/2016
  1435                              <1> 	; 27/02/2026
  1436                              <1> 	; 26/02/2016
  1437                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1438                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_make_directory')
  1439                              <1> 	; 10/07/2010
  1440                              <1> 	; INPUT ->
  1441                              <1> 	; 	ESI = ASCIIZ Directory Name
  1442                              <1> 	;	CL = Directory Attributes
  1443                              <1> 	; OUTPUT ->
  1444                              <1> 	;	EAX = New sub dir's first cluster
  1445                              <1> 	;	ESI = Logical Dos Drv Descr. Table Addr.
  1446                              <1> 	;	CF = 1 -> error code in AL (EAX)
  1447                              <1> 
  1448                              <1> 	;test	cl, 10h  ; directory
  1449                              <1> 	;jz	short loc_make_directory_access_denied
  1450                              <1> 	;test	cl, 08h ; volume name
  1451                              <1> 	;jnz	short loc_make_directory_access_denied
  1452                              <1> 
  1453 00007EB8 80E107              <1> 	and	cl, 07h
  1454 00007EBB 880D[20DA0000]      <1> 	mov	byte [mkdir_attrib], cl
  1455                              <1> 
  1456 00007EC1 56                  <1> 	push	esi
  1457 00007EC2 31DB                <1> 	xor	ebx, ebx
  1458 00007EC4 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  1459 00007ECA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1460 00007ECF 01DE                <1> 	add	esi, ebx
  1461 00007ED1 5B                  <1> 	pop	ebx
  1462                              <1> 
  1463                              <1> 	; 10/07/2010 -> 1st writable disk check for trdos
  1464                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  1465 00007ED2 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1466 00007ED6 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1467 00007ED8 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  1468 00007EDD BA00000000          <1> 	mov	edx, 0
  1469                              <1> 	; err retn: EDX = 0, EBX = Dir name offset
  1470                              <1> 	;ESI = Logical DOS drive description table address
  1471 00007EE2 C3                  <1> 	retn
  1472                              <1> 
  1473                              <1> ;loc_make_directory_access_denied:
  1474                              <1> 	;mov	ax, 05h ; access denied (invalid attributes input)
  1475                              <1> 	;stc
  1476                              <1> 	;retn
  1477                              <1> 
  1478                              <1> loc_mkdir_check_file_sytem:
  1479 00007EE3 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1480 00007EE7 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1481                              <1> 
  1482                              <1> loc_make_fs_directory:
  1483 00007EE9 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  1484                              <1> 	; EAX = Parent directory DDT Address
  1485                              <1> 	; ESI = Logical DOS Drive DT Address
  1486                              <1> 	; EBX = Directory name offset (as ASCIIZ name)
  1487 00007EEE E8B8150000          <1> 	call	make_fs_directory
  1488 00007EF3 C3                  <1> 	retn
  1489                              <1> 
  1490                              <1> loc_mkdir_check_free_sectors:
  1491 00007EF4 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1492 00007EF8 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1493 00007EFB 39C1                <1> 	cmp	ecx, eax
  1494 00007EFD 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1495                              <1> 
  1496                              <1> loc_make_fat_directory:
  1497 00007EFF 891D[10DA0000]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1498 00007F05 890D[1CDA0000]      <1> 	mov	[mkdir_FreeSectors], ecx
  1499                              <1> 
  1500                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1501 00007F0B A2[22DA0000]        <1> 	mov	byte [mkdir_SecPerClust], al
  1502                              <1> 
  1503                              <1> loc_mkdir_gffc_1:
  1504 00007F10 E8F2170000          <1> 	call	get_first_free_cluster
  1505 00007F15 722A                <1> 	jc	short loc_mkdir_gffc_retn
  1506                              <1> 
  1507                              <1> ;loc_mkdir_gffc_1_cont: 
  1508                              <1> 	;cmp	eax, 2
  1509                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1510                              <1> 
  1511                              <1> ;loc_mkdir_gffc_1_save_fcluster:  
  1512 00007F17 A3[14DA0000]        <1> 	mov	[mkdir_FFCluster], eax
  1513                              <1> 
  1514                              <1> loc_mkdir_locate_ffe:
  1515                              <1> 	; Current directory fcluster <> Directory buffer cluster
  1516                              <1> 	; Current directory will be reloaded by
  1517                              <1> 	; 'locate_current_dir_file' procedure
  1518                              <1> 	;
  1519                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1520                              <1> 	;push	esi ; 27/02/2016
  1521 00007F1C 31C0                <1> 	xor	eax, eax
  1522 00007F1E 89C1                <1>         mov	ecx, eax
  1523 00007F20 6649                <1> 	dec	cx ; FFFFh  
  1524                              <1> 	; CX = FFFFh -> find first deleted or free entry
  1525                              <1> 	; ESI would be ASCIIZ filename address if the call
  1526                              <1> 	; would not be for first free or deleted dir entry
  1527 00007F22 E8D2FAFFFF          <1> 	call	locate_current_dir_file
  1528 00007F27 734C                <1> 	jnc	short loc_mkdir_set_ff_dir_entry_1
  1529                              <1> 	;pop	esi 
  1530                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1531 00007F29 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1532 00007F2C 752B                <1> 	jne	short loc_mkdir_stc_return
  1533                              <1> 
  1534                              <1> loc_mkdir_add_new_cluster:
  1535 00007F2E 3805[A1CF0000]      <1> 	cmp	byte [Current_FATType], al ; 2
  1536                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1537 00007F34 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1538 00007F36 803D[A0CF0000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1539                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1540 00007F3D 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1541                              <1> 
  1542 00007F3F B00C                <1> 	mov	al, 12 ; No more files 
  1543                              <1> loc_mkdir_gffc_retn:
  1544 00007F41 C3                  <1> 	retn
  1545                              <1> 
  1546                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1547 00007F42 8B0D[1CDA0000]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1548                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1549 00007F48 A0[22DA0000]        <1> 	mov	al, [mkdir_SecPerClust]
  1550 00007F4D 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1551 00007F50 39C1                <1> 	cmp	ecx, eax
  1552 00007F52 7350                <1> 	jnb	short loc_mkdir_add_new_subdir_cluster
  1553                              <1> 
  1554                              <1> loc_mkdir_insufficient_disk_space:
  1555                              <1> 	;mov	edx, ecx
  1556                              <1> ;loc_mkdir_gffc_insufficient_disk_space:
  1557 00007F54 66B82700            <1> 	mov	ax, 27h ; MSDOS err => insufficient disk space
  1558                              <1> 	; err retn: EDX = Free sectors, EBX = Dir name offset
  1559                              <1>         ; ESI -> Dos drive description table address
  1560                              <1> 	;; ecx = edx
  1561                              <1> 	;
  1562 00007F58 C3                  <1> 	retn
  1563                              <1> 
  1564                              <1> loc_mkdir_stc_return:
  1565 00007F59 F9                  <1> 	stc
  1566 00007F5A C3                  <1> 	retn 
  1567                              <1> 
  1568                              <1> loc_mkdir_gffc_2:
  1569 00007F5B E8A7170000          <1> 	call	get_first_free_cluster
  1570 00007F60 72DF                <1> 	jc	short loc_mkdir_gffc_retn
  1571                              <1> 
  1572                              <1> ;loc_mkdir_gffc_1_cont: 
  1573                              <1> 	;cmp	eax, 2
  1574                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1575                              <1> 
  1576                              <1> ;loc_mkdir_gffc_2_save_fcluster:  
  1577 00007F62 A3[14DA0000]        <1> 	mov	[mkdir_FFCluster], eax
  1578                              <1> 
  1579 00007F67 A1[18DA0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1580                              <1> 
  1581 00007F6C E825170000          <1> 	call	load_FAT_sub_directory 
  1582 00007F71 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1583                              <1> 
  1584 00007F73 31FF                <1> 	xor	edi, edi
  1585                              <1> loc_mkdir_set_ff_dir_entry_1:
  1586                              <1> 	; 27/02/2016
  1587 00007F75 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1588                              <1> 	; EDI = Directory Entry Address
  1589 00007F76 8B35[10DA0000]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1590 00007F7C A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1591                              <1> 
  1592 00007F81 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1593                              <1> 			; CH = 0 -> File size is 0
  1594 00007F85 0A0D[20DA0000]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1595 00007F8B E8B0010000          <1> 	call	make_directory_entry
  1596                              <1> 
  1597 00007F90 5E                  <1> 	pop	esi
  1598                              <1> 
  1599 00007F91 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1600 00007F98 E880020000          <1> 	call	save_directory_buffer
  1601 00007F9D 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1602                              <1> 
  1603                              <1> loc_mkdir_return:
  1604 00007FA3 C3                  <1> 	retn
  1605                              <1> 
  1606                              <1> loc_mkdir_add_new_subdir_cluster:
  1607 00007FA4 8B15[D1D70000]      <1> 	mov	edx, [DirBuff_Cluster]
  1608 00007FAA 8915[18DA0000]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1609                              <1> 
  1610 00007FB0 A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1611 00007FB5 E8DC160000          <1> 	call	load_FAT_sub_directory 
  1612 00007FBA 72E7                <1> 	jc	short loc_mkdir_return
  1613                              <1> 	; eax = 0
  1614                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1615                              <1> 
  1616                              <1> pass_mkdir_add_new_subdir_cluster:
  1617 00007FBC 29FF                <1> 	sub	edi, edi ; 0
  1618                              <1> 	;mov	al, 128 ; double word
  1619                              <1> 	;mul	ecx ; ecx =  directory buffer sector count
  1620                              <1> 	;mov	ecx, eax
  1621                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1622 00007FBE 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1623 00007FC2 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1624 00007FC6 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1625 00007FC9 6689C1              <1> 	mov	cx, ax
  1626 00007FCC 6629C0              <1> 	sub	ax, ax ; 0
  1627 00007FCF F3AB                <1> 	rep	stosd ; clear directory buffer
  1628                              <1> 
  1629 00007FD1 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1630 00007FD8 E840020000          <1> 	call	save_directory_buffer 
  1631 00007FDD 72C4                <1> 	jc	short loc_mkdir_return
  1632                              <1> 
  1633                              <1> loc_mkdir_save_added_cluster:
  1634 00007FDF A1[18DA0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1635 00007FE4 8B0D[14DA0000]      <1> 	mov	ecx, [mkdir_FFCluster]
  1636                              <1> 	; 01/03/2016
  1637 00007FEA 31D2                <1> 	xor	edx, edx
  1638 00007FEC 8915[C1D70000]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1639 00007FF2 E8E3170000          <1> 	call	update_cluster
  1640 00007FF7 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1641 00007FF9 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1642 00007FFB 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1643                              <1> 
  1644                              <1> loc_mkdir_save_fat_buffer_0:
  1645 00007FFD A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1646 00008002 A3[18DA0000]        <1> 	mov	[mkdir_LastDirCluster], eax
  1647                              <1> 
  1648 00008007 31C9                <1> 	xor	ecx, ecx
  1649 00008009 49                  <1> 	dec	ecx ; FFFFFFFFh
  1650                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1651 0000800A E8CB170000          <1> 	call	update_cluster
  1652 0000800F 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1653 00008011 09C0                <1> 	or	eax, eax
  1654 00008013 7416                <1> 	jz	short loc_mkdir_save_fat_buffer_1
  1655                              <1> 
  1656                              <1> loc_mkdir_save_fat_buffer_stc_retn:
  1657                              <1> 	; 01/03/2016
  1658 00008015 803D[C1D70000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1659 0000801C 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1660                              <1> 
  1661 0000801E 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 00008022 50                  <1> 	push	eax
  1664 00008023 E8041B0000          <1> 	call	calculate_fat_freespace
  1665 00008028 58                  <1> 	pop	eax
  1666 00008029 F9                  <1> 	stc
  1667                              <1> loc_mkdir_save_fat_buffer_retn:
  1668 0000802A C3                  <1> 	retn
  1669                              <1> 
  1670                              <1> loc_mkdir_save_fat_buffer_1:
  1671                              <1> 	; byte [FAT_BuffValidData] = 2 
  1672 0000802B E8671A0000          <1> 	call	save_fat_buffer
  1673 00008030 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1674                              <1> 
  1675                              <1> 	; 01/03/2016
  1676 00008032 803D[C1D70000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1677 00008039 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1678                              <1> 
  1679                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1680 0000803B A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1681 00008040 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1682 00008044 E8E31A0000          <1> 	call	calculate_fat_freespace
  1683                              <1> 
  1684                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1685                              <1> 	;jnz	short loc_mkdir_save_fat_buffer_2
  1686                              <1> 
  1687                              <1> 	; ecx > 0 -> Recalculation is needed
  1688 00008049 09C9                <1> 	or	ecx, ecx 
  1689 0000804B 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1690                              <1> 
  1691 0000804D 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1692 00008051 E8D61A0000          <1> 	call	calculate_fat_freespace
  1693                              <1> 
  1694                              <1> loc_mkdir_save_fat_buffer_2:
  1695 00008056 C605[23DA0000]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1696 0000805D E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1697                              <1> 
  1698                              <1> loc_mkdir_update_sub_dir_cluster:
  1699 00008062 A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1700 00008067 29C9                <1> 	sub	ecx, ecx ; 0
  1701                              <1> 	; 01/03/2016
  1702 00008069 890D[C1D70000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1703 0000806F 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1704                              <1> 
  1705                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1706 00008070 E865170000          <1> 	call	update_cluster
  1707 00008075 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1708 00008077 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1709 00008079 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1710                              <1> 	; 01/03/2016
  1711 0000807B EB98                <1> 	jmp	short loc_mkdir_save_fat_buffer_stc_retn
  1712                              <1> 
  1713                              <1> loc_mkdir_set_ff_dir_entry_2:
  1714                              <1> 	; ESI = Logical DOS Drive Description Table address  
  1715 0000807D A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1716                              <1> 	; Load disk sectors as a directory cluster
  1717 00008082 E80F160000          <1> 	call	load_FAT_sub_directory 
  1718 00008087 7266                <1> 	jc	short retn_make_fat_directory
  1719                              <1> 	
  1720                              <1> 	; eax = 0
  1721                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1722                              <1> 
  1723 00008089 BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1724                              <1> 
  1725                              <1> 	; 02/03/2016
  1726 0000808E 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1727 00008092 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1728 00008096 F7E1                <1> 	mul 	ecx
  1729 00008098 89C1                <1> 	mov	ecx, eax
  1730 0000809A 6629C0              <1> 	sub	ax, ax
  1731 0000809D F3AB                <1> 	rep	stosd
  1732                              <1> 
  1733                              <1> 	;;mov	al, 128 ; double word
  1734                              <1> 	;;mul	ecx ; ecx =  directory buffer sector count
  1735                              <1> 	;;mov	ecx, eax
  1736                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1737                              <1> 	;;sub	eax, eax
  1738                              <1> 	;;sub	al, al ; 0
  1739                              <1> 	;rep	stosd ; clear directory buffer
  1740                              <1> 
  1741 0000809F BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1742                              <1> 	
  1743 000080A4 56                  <1> 	push	esi
  1744                              <1> 
  1745 000080A5 BE[24DA0000]        <1> 	mov	esi, mkdir_Name
  1746 000080AA 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1747                              <1> 
  1748 000080AF A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1749 000080B4 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1750                              <1> 			; CH = 0 -> File size is 0
  1751 000080B8 E883000000          <1> 	call	make_directory_entry
  1752                              <1> 
  1753 000080BD BF20000800          <1> 	mov	edi, Directory_Buffer + 32 ; 26/02/2016
  1754                              <1> 
  1755                              <1> 	; 03/03/2016
  1756                              <1> 	; Following modification has been done according to 
  1757                              <1> 	; 'Microsoft Extensible Firmware Initiative
  1758                              <1> 	; FAT32 File System Specification' document,
  1759                              <1> 	; 'FAT: General Overview of On-Disk FormatPage 25'.
  1760                              <1> 	; "Finally, you set DIR_FstClusLO and DIR_FstClusHI
  1761                              <1> 	; for the dotdot entry (the second entry) to the
  1762                              <1> 	; first cluster number of the directory in which you 
  1763                              <1> 	; just created the directory (value is 0 if this directory
  1764                              <1> 	; is the root directory even for FAT32 volumes)."
  1765                              <1> 	; (Correctness of this modification has been verified
  1766                              <1> 	;  by using Windows 98 'scandisk.exe'.)
  1767                              <1> 
  1768 000080C2 29C0                <1> 	sub	eax, eax
  1769 000080C4 3805[A0CF0000]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1770 000080CA 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1771 000080CC A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1772                              <1> loc_mkdir_set_ff_dir_entry_3:
  1773 000080D1 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1774                              <1> 
  1775                              <1> 	;mov	cx, 10h
  1776 000080D7 E864000000          <1> 	call	make_directory_entry
  1777                              <1> 
  1778 000080DC 5E                  <1> 	pop	esi
  1779                              <1> 
  1780 000080DD C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1781 000080E4 E834010000          <1> 	call	save_directory_buffer
  1782 000080E9 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1783                              <1>  
  1784                              <1> retn_make_fat_directory:
  1785 000080EF C3                  <1> 	retn
  1786                              <1> 
  1787                              <1> loc_mkdir_save_fat_buffer_3:
  1788                              <1> 	; 01/03/2016
  1789                              <1> 	; byte [FAT_BuffValidData] = 2 
  1790 000080F0 E8A2190000          <1> 	call	save_fat_buffer
  1791 000080F5 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1792                              <1> 
  1793 000080FB 803D[C1D70000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1794 00008102 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1795                              <1> 
  1796                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1797 00008104 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1798 00008109 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1799 0000810D E81A1A0000          <1> 	call	calculate_fat_freespace
  1800                              <1> 
  1801                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1802                              <1>         ;jnz    short loc_mkdir_save_fat_buffer_4
  1803                              <1> 
  1804                              <1> 	; ecx > 0 -> Recalculation is needed
  1805 00008112 09C9                <1> 	or	ecx, ecx 
  1806 00008114 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1807                              <1> 
  1808 00008116 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space
  1809 0000811A E80D1A0000          <1> 	call	calculate_fat_freespace
  1810                              <1> 
  1811                              <1> loc_mkdir_save_fat_buffer_4:	
  1812 0000811F C605[23DA0000]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1813                              <1> 
  1814                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1815 00008126 E88D010000          <1> 	call	update_parent_dir_lmdt
  1816                              <1> 
  1817                              <1> 	; 01/03/2016
  1818 0000812B 803D[23DA0000]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1819 00008132 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1820                              <1> 
  1821                              <1> loc_mkdir_retn_new_dir_cluster:
  1822 00008138 A1[14DA0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1823 0000813D 31D2                <1> 	xor	edx, edx
  1824                              <1> loc_mkdir_retn:
  1825 0000813F C3                  <1> 	retn
  1826                              <1> 
  1827                              <1> make_directory_entry:
  1828                              <1> 	; 02/03/2016
  1829                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1830                              <1> 	; 09/08/2010 (DIR.ASM, 'proc_make_directory_entry')
  1831                              <1> 	; 17/07/2010
  1832                              <1> 	; INPUT ->
  1833                              <1> 	; 	EDI = Directory Entry Address
  1834                              <1> 	;	ESI = Dot File Name Location
  1835                              <1> 	;	EAX = First Cluster
  1836                              <1> 	;	File Size = 0 (Must be set later)
  1837                              <1> 	;	CL = Attributes
  1838                              <1> 	;	CH = 0 (File size = 0) 
  1839                              <1> 	;	(If CH>0, File size is in dword [EBX]) (*)
  1840                              <1> 	; OUTPUT -> 
  1841                              <1> 	;	EDI = Directory Entry Address
  1842                              <1> 	;	ESI = Dot File Name Location (Capitalized)
  1843                              <1> 	;	If CH input = 0, File Size = 0
  1844                              <1> 	;	Otherwise file size is as dword [EBX] (*)
  1845                              <1> 	;	DX = Date, AX = Time in DOS Dir Entry format
  1846                              <1> 	;	EBX = same
  1847                              <1> 	;	ECX = same
  1848                              <1> 
  1849 00008140 51                  <1> 	push	ecx
  1850                              <1> 
  1851 00008141 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1852 00008144 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1853 00008148 C1E810              <1> 	shr	eax, 16
  1854 0000814B 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1855 0000814F 6631C0              <1> 	xor	ax, ax 
  1856 00008152 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1857                              <1> 			     ; CrtTimeTenth, 13
  1858 00008156 08ED                <1> 	or	ch, ch
  1859 00008158 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1860                              <1> 
  1861 0000815A 8B03                <1> 	mov	eax, [ebx]
  1862                              <1>         
  1863                              <1> loc_make_direntry_set_filesize:
  1864 0000815C 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1865                              <1> 	
  1866 0000815F E88AFBFFFF          <1> 	call	convert_file_name
  1867                              <1> 	;EDI = Dir Entry Format File Name Location
  1868                              <1> 	;ESI = Dot File Name Location (capitalized)
  1869                              <1> 
  1870 00008164 E816000000          <1> 	call	convert_current_date_time
  1871                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1872                              <1>         ; 	    AX = Time in dos dir entry format
  1873 00008169 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1874 0000816D 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1875 00008171 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1876 00008175 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1877 00008179 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1878 0000817D 59                  <1> 	pop	ecx
  1879                              <1> 
  1880 0000817E C3                  <1> 	retn
  1881                              <1> 
  1882                              <1> convert_current_date_time:
  1883                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1884                              <1> 	; 13/06/2010 (DIR.ASM, 'proc_convert_current_date_time')
  1885                              <1> 	; converts date&time to dos dir entry format
  1886                              <1> 	; INPUT -> none
  1887                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1888                              <1> 	;           AX = Time in dos dir entry format
  1889                              <1>  
  1890 0000817F B404                <1> 	mov	ah, 04h ; Return Current Date
  1891 00008181 E8E6B9FFFF          <1> 	call	int1Ah 
  1892                              <1> 
  1893 00008186 88E8                <1> 	mov	al, ch ; <- century BCD
  1894 00008188 240F                <1> 	and	al, 0Fh
  1895 0000818A 88EC                <1> 	mov	ah, ch
  1896 0000818C C0EC04              <1> 	shr	ah, 4
  1897 0000818F D50A                <1> 	aad
  1898 00008191 88C5                <1> 	mov	ch, al ; -> century 
  1899                              <1> 
  1900 00008193 88C8                <1> 	mov	al, cl ; <- year BCD
  1901 00008195 240F                <1> 	and	al, 0Fh
  1902 00008197 88CC                <1> 	mov	ah, cl
  1903 00008199 C0EC04              <1> 	shr	ah, 4
  1904 0000819C D50A                <1> 	aad
  1905 0000819E 88C1                <1> 	mov	cl, al ; -> year
  1906                              <1> 
  1907 000081A0 88E8                <1> 	mov	al, ch
  1908 000081A2 B464                <1> 	mov	ah, 100
  1909 000081A4 F6E4                <1> 	mul	ah
  1910 000081A6 30ED                <1> 	xor	ch, ch
  1911 000081A8 6601C8              <1> 	add	ax, cx
  1912 000081AB 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1913 000081AF 6689C1              <1> 	mov	cx, ax
  1914                              <1> 
  1915 000081B2 88F0                <1> 	mov	al, dh ; <- month in bcd
  1916 000081B4 240F                <1> 	and	al, 0Fh
  1917 000081B6 88F4                <1> 	mov	ah, dh
  1918 000081B8 C0EC04              <1> 	shr	ah, 4
  1919 000081BB D50A                <1> 	aad
  1920 000081BD 88C6                <1> 	mov	dh, al ; -> month
  1921                              <1> 
  1922 000081BF 88D0                <1> 	mov	al, dl ; <- day BCD
  1923 000081C1 240F                <1> 	and	al, 0Fh
  1924 000081C3 88D4                <1> 	mov	ah, dl
  1925 000081C5 C0EC04              <1> 	shr	ah, 4
  1926 000081C8 D50A                <1> 	aad
  1927 000081CA 88C2                <1> 	mov	dl, al ; -> day
  1928                              <1> 
  1929 000081CC 88C8                <1> 	mov	al, cl ; count of years from 1980
  1930 000081CE 66C1E004            <1> 	shl	ax, 4
  1931 000081D2 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1932 000081D4 66C1E005            <1> 	shl	ax, 5
  1933 000081D8 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1934                              <1> 	
  1935 000081DA 6650                <1> 	push	ax ; push date
  1936                              <1> 
  1937 000081DC B402                <1> 	mov	ah, 02h ; Return Current Time
  1938 000081DE E889B9FFFF          <1> 	call	int1Ah
  1939                              <1> 
  1940 000081E3 88E8                <1> 	mov	al, ch ; <- hours BCD
  1941 000081E5 240F                <1> 	and	al, 0Fh
  1942 000081E7 88EC                <1> 	mov	ah, ch
  1943 000081E9 C0EC04              <1> 	shr	ah, 4
  1944 000081EC D50A                <1> 	aad
  1945 000081EE 88C5                <1> 	mov	ch, al ; -> hours
  1946                              <1> 
  1947 000081F0 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1948 000081F2 240F                <1> 	and	al, 0Fh
  1949 000081F4 88CC                <1> 	mov	ah, cl
  1950 000081F6 C0EC04              <1> 	shr	ah, 4
  1951 000081F9 D50A                <1> 	aad
  1952 000081FB 88C1                <1> 	mov	cl, al ; -> minutes
  1953                              <1> 
  1954 000081FD 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1955 000081FF 240F                <1> 	and	al, 0Fh
  1956 00008201 88F4                <1> 	mov	ah, dh
  1957 00008203 C0EC04              <1> 	shr	ah, 4
  1958 00008206 D50A                <1> 	aad
  1959 00008208 88C6                <1> 	mov	dh, al ; -> seconds
  1960                              <1> 
  1961 0000820A 88E8                <1> 	mov	al, ch ; hours
  1962 0000820C 66C1E006            <1> 	shl	ax, 6
  1963 00008210 08C8                <1> 	or	al, cl ; minutes
  1964 00008212 66C1E005            <1> 	shl	ax, 5
  1965 00008216 D0EE                <1> 	shr	dh, 1 ; 2 seconds
  1966                              <1> 	; There is a bug in TRDOS v1 here !
  1967                              <1> 	; it was 'or al, dl' ! 
  1968 00008218 08F0                <1> 	or	al, dh ; seconds
  1969                              <1> 
  1970 0000821A 665A                <1> 	pop	dx ; pop date
  1971                              <1> 	
  1972 0000821C C3                  <1> 	retn
  1973                              <1> 
  1974                              <1> save_directory_buffer:
  1975                              <1> 	; 23/03/2016
  1976                              <1> 	; 26/02/2016
  1977                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  1978                              <1> 	; 01/08/2011
  1979                              <1> 	; 14/03/2010
  1980                              <1> 	; INPUT ->
  1981                              <1> 	; 	 none
  1982                              <1> 	; OUTPUT ->
  1983                              <1> 	;  cf = 0 -> write OK...
  1984                              <1> 	;  cf = 1 -> error code in AL (EAX)
  1985                              <1> 	;  cf = 1 & AL = 0Dh => CH & CL = FS & FAT type
  1986                              <1> 	;  EBX = Directory Buffer Address
  1987                              <1> 	;
  1988                              <1> 	;  (EAX, ECX, EDX will be modified)
  1989                              <1>  
  1990 0000821D BB00000800          <1> 	mov	ebx, Directory_Buffer
  1991 00008222 803D[CCD70000]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1992 00008229 7403                <1> 	je	short loc_save_dir_buffer
  1993 0000822B 31C0                <1> 	xor	eax, eax
  1994 0000822D C3                  <1> 	retn            
  1995                              <1> 
  1996                              <1> loc_save_dir_buffer:
  1997 0000822E 56                  <1> 	push	esi
  1998 0000822F 31DB                <1> 	xor	ebx, ebx 
  1999 00008231 8A3D[CAD70000]      <1>         mov     bh, [DirBuff_DRV]
  2000 00008237 80EF41              <1> 	sub	bh, 'A'
  2001 0000823A BE00010900          <1>         mov     esi, Logical_DOSDisks
  2002 0000823F 01DE                <1> 	add	esi, ebx
  2003 00008241 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2004                              <1> 	; CH = FS Type (A1h for FS)
  2005                              <1> 	; CL = FAT Type (0 for FS)
  2006 00008245 08C9                <1> 	or	cl, cl
  2007 00008247 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2008                              <1> 
  2009                              <1> loc_save_dir_buffer_check_cluster_no:    
  2010 00008249 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
  2011 0000824E 28FF                <1> 	sub	bh, bh ; ebx = 0
  2012 00008250 09C0                <1> 	or	eax, eax
  2013 00008252 7540                <1> 	jnz	short loc_save_sub_dir_buffer
  2014 00008254 8A25[CBD70000]      <1> 	mov	ah, [DirBuff_FATType]
  2015 0000825A FEC3                <1> 	inc	bl ;  bl = 1
  2016 0000825C 38DC                <1> 	cmp	ah, bl
  2017 0000825E 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2018 00008260 FEC3                <1> 	inc	bl ; bl = 2
  2019 00008262 38E3                <1> 	cmp	bl, ah
  2020 00008264 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2021                              <1> 
  2022                              <1> loc_save_root_dir_buffer:
  2023 00008266 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2024 0000826A 6683C30F            <1> 	add	bx, 15
  2025 0000826E 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2026 00008272 6609DB              <1> 	or	bx, bx
  2027 00008275 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2028                              <1> 	;mov	ecx, ebx 
  2029 00008277 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2030 0000827A EB23                <1> 	jmp	short loc_write_directory_to_disk
  2031                              <1> 
  2032                              <1> loc_save_dir_buff_stc_retn:
  2033 0000827C F9                  <1> 	stc
  2034                              <1> loc_save_dir_buff_inv_data_retn:
  2035 0000827D B00D                <1> 	mov	al, 0Dh ; Invalid data !
  2036 0000827F C605[CCD70000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2037 00008286 EB05                <1> 	jmp	short loc_save_dir_buff_retn 
  2038                              <1> 
  2039                              <1> loc_write_directory_to_disk_err:
  2040                              <1> 	; 23/03/2016
  2041 00008288 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error 
  2042                              <1> 
  2043                              <1> loc_save_dir_buff_retn:
  2044 0000828D BB00000800          <1> 	mov	ebx, Directory_Buffer
  2045 00008292 5E                  <1> 	pop	esi
  2046 00008293 C3                  <1> 	retn
  2047                              <1>  
  2048                              <1> loc_save_sub_dir_buffer:
  2049                              <1> 	; ebx  = 0
  2050 00008294 83E802              <1> 	sub	eax, 2
  2051 00008297 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2052 0000829A F7E3                <1> 	mul	ebx
  2053 0000829C 034668              <1>         add     eax, [esi+LD_DATABegin]
  2054                              <1>  	;mov	ecx, ebx
  2055                              <1> 
  2056                              <1> loc_write_directory_to_disk:
  2057 0000829F 89D9                <1>  	mov	ecx, ebx
  2058 000082A1 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2059 000082A6 E8D1370000          <1> 	call	disk_write
  2060 000082AB 72DB                <1> 	jc	short loc_write_directory_to_disk_err
  2061                              <1> 
  2062                              <1> loc_save_dir_buff_validate_retn:
  2063 000082AD C605[CCD70000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2064 000082B4 31C0                <1> 	xor	eax, eax
  2065                              <1> 	; 26/02/2016
  2066 000082B6 EBD5                <1> 	jmp	short loc_save_dir_buff_retn
  2067                              <1> 
  2068                              <1> update_parent_dir_lmdt:
  2069                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  2070                              <1> 	; 01/08/2011
  2071                              <1> 	; 16/10/2010 
  2072                              <1> 	; 
  2073                              <1> 	; INPUT -> 
  2074                              <1> 	;	none
  2075                              <1>  	; OUTPUT ->
  2076                              <1> 	;	(last modification date & time of the parent dir
  2077                              <1> 	;	will be changed/updated)
  2078                              <1> 	;
  2079                              <1> 	; (EAX, EBX, ECX, EDX, EDI will be changed)
  2080                              <1> 
  2081 000082B8 29C0                <1> 	sub	eax, eax
  2082 000082BA 8A25[A0CF0000]      <1> 	mov	ah, [Current_Dir_Level]
  2083 000082C0 A0[A1CF0000]        <1> 	mov	al, [Current_FATType]
  2084 000082C5 3C01                <1> 	cmp	al, 1
  2085 000082C7 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2086                              <1>     
  2087                              <1> loc_update_parent_dir_lm_date_time:
  2088 000082C9 08E4                <1> 	or	ah, ah
  2089 000082CB 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2090                              <1> 
  2091 000082CD 56                  <1> 	push	esi ; *
  2092 000082CE 8825[44DA0000]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2093 000082D4 8B15[9CCF0000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2094 000082DA 8915[45DA0000]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2095                              <1> 
  2096 000082E0 FECC                <1> 	dec	ah
  2097 000082E2 B90C000000          <1> 	mov	ecx, 12
  2098 000082E7 BE[03D80000]        <1>         mov     esi, PATH_Array
  2099                              <1> 
  2100 000082EC 8825[A0CF0000]      <1> 	mov	[Current_Dir_Level], ah
  2101 000082F2 08E4                <1> 	or	ah, ah
  2102 000082F4 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2103 000082F6 803D[A1CF0000]02    <1> 	cmp	byte [Current_FATType], 2
  2104 000082FD 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2105 000082FF 28C0                <1> 	sub	al, al ; eax = 0
  2106 00008301 EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2107                              <1> 
  2108                              <1> loc_UPDLMDT_proc_retn:
  2109 00008303 C3                  <1> 	retn
  2110                              <1>          
  2111                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2112 00008304 B010                <1> 	mov	al, 16
  2113 00008306 F6E4                <1> 	mul	ah 
  2114 00008308 01C6                <1> 	add	esi, eax
  2115                              <1> 
  2116                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2117 0000830A 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2118                              <1> 
  2119                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2120 0000830D A3[9CCF0000]        <1> 	mov	[Current_Dir_FCluster], eax
  2121                              <1> 
  2122 00008312 83C610              <1> 	add	esi, 16
  2123 00008315 66BF[2AD9]          <1> 	mov	di, Dir_File_Name  
  2124 00008319 F3A4                <1> 	rep	movsb
  2125                              <1> 	
  2126 0000831B BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2127 00008320 29DB                <1> 	sub	ebx, ebx
  2128 00008322 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  2129 00008328 01DE                <1> 	add	esi, ebx
  2130 0000832A E88FF7FFFF          <1> 	call	reload_current_directory
  2131 0000832F 7232                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2132                              <1> 
  2133                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2134 00008331 BE[2AD90000]        <1> 	mov	esi, Dir_File_Name        
  2135 00008336 6631C9              <1> 	xor	cx, cx
  2136 00008339 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2137 0000833D E8B7F6FFFF          <1>         call    locate_current_dir_file
  2138                              <1> 	; EDI = DirBuff Directory Entry Address
  2139 00008342 721F                <1> 	jc short loc_update_parent_dir_lmdt_restore_cdirlevel
  2140                              <1> 
  2141 00008344 E836FEFFFF          <1> 	call	convert_current_date_time
  2142 00008349 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2143 0000834D 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2144 00008351 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2145                              <1> 
  2146 00008355 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2147 0000835C E8BCFEFFFF          <1> 	call	save_directory_buffer
  2148 00008361 7200                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2149                              <1> 	;xor	al, al 
  2150                              <1> loc_update_parent_dir_lmdt_restore_cdirlevel:
  2151                              <1>  	;current directory level restoration
  2152 00008363 8A25[44DA0000]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2153 00008369 8825[A0CF0000]      <1> 	mov	[Current_Dir_Level], ah
  2154 0000836F 8B15[45DA0000]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2155 00008375 8915[9CCF0000]      <1> 	mov	[Current_Dir_FCluster], edx
  2156                              <1> 
  2157 0000837B 5E                  <1> 	pop	esi ; *
  2158 0000837C C3                  <1> 	retn
  2159                              <1> 
  2160                              <1> delete_longname:
  2161                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2162                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_longname')
  2163                              <1> 	; 14/03/2010
  2164                              <1> 	; INPUT ->
  2165                              <1> 	; 	EAX = Directory Entry (Index) Number (< 65536)
  2166                              <1> 	; OUTPUT ->
  2167                              <1> 	;	cf = 0 -> OK  (EAX = 0)
  2168                              <1> 	; 	cf = 1 -> error code in EAX (AL)
  2169                              <1> 	;
  2170                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2171                              <1> 
  2172 0000837D 66A3[70DA0000]      <1> 	mov	[DLN_EntryNumber], ax
  2173 00008383 C605[72DA0000]40    <1>         mov     byte [DLN_40h], 40h
  2174                              <1> 
  2175 0000838A E858000000          <1> 	call	locate_current_dir_entry
  2176 0000838F 7308                <1> 	jnc	short loc_dln_check_attributes
  2177 00008391 C3                  <1> 	retn
  2178                              <1> 
  2179                              <1> loc_dln_longname_not_found:
  2180 00008392 B802000000          <1> 	mov	eax, 2
  2181 00008397 F9                  <1> 	stc
  2182 00008398 C3                  <1> 	retn
  2183                              <1> 
  2184                              <1> loc_dln_check_attributes:
  2185 00008399 B00F                <1> 	mov	al, 0Fh  ; long name
  2186 0000839B 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2187 0000839E 38C4                <1> 	cmp	ah, al
  2188 000083A0 75F0                <1> 	jne	short loc_dln_longname_not_found
  2189 000083A2 8A27                <1> 	mov	ah, [edi]
  2190 000083A4 2A25[72DA0000]      <1> 	sub	ah, [DLN_40h]
  2191 000083AA 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2192 000083AC 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2193 000083AF 77E1                <1> 	ja	short loc_dln_longname_not_found
  2194                              <1>              
  2195 000083B1 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2196 000083B4 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2197 000083BB C605[72DA0000]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2198                              <1> 	  
  2199                              <1> loc_dln_delete_next_ln_entry:
  2200 000083C2 80FC01              <1> 	cmp	ah, 1
  2201 000083C5 7616                <1> 	jna	short loc_dln_longname_retn
  2202                              <1> loc_dln_delete_next_ln_entry_0:
  2203 000083C7 66FF05[70DA0000]    <1> 	inc	word [DLN_EntryNumber]
  2204 000083CE 0FB705[70DA0000]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2205 000083D5 E80D000000          <1> 	call	locate_current_dir_entry
  2206 000083DA 73BD                <1> 	jnc	short loc_dln_check_attributes
  2207                              <1> 
  2208                              <1> loc_dln_longname_stc_retn:
  2209 000083DC C3                  <1> 	retn 
  2210                              <1> 	   
  2211                              <1> loc_dln_longname_retn:
  2212                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2213                              <1> 	;jne	short loc_dln_longname_retn_xor_eax
  2214 000083DD E83BFEFFFF          <1> 	call	save_directory_buffer
  2215 000083E2 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2216                              <1> 
  2217                              <1> loc_dln_longname_retn_xor_eax:
  2218 000083E4 31C0                <1> 	xor	eax, eax
  2219 000083E6 C3                  <1> 	retn
  2220                              <1> 
  2221                              <1> locate_current_dir_entry:
  2222                              <1> 	; 23/03/2016
  2223                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2224                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_locate_current_dir_entry')
  2225                              <1> 	; 07/03/2010
  2226                              <1> 	; INPUT ->
  2227                              <1> 	;	EAX = Directory Entry (Index) Number (< 65536) 
  2228                              <1> 	; OUTPUT ->
  2229                              <1> 	;	EDI = Directory Entry Address
  2230                              <1> 	; 	EAX = Cluster Number of Directory Buffer
  2231                              <1> 	;	EBX = Directory Buffer Entry Offset
  2232                              <1> 	;	ECX = DirBuff Valid Data identifier (CL)
  2233                              <1> 	;   	If CF = 0 and CL = 2 then
  2234                              <1> 	;	   directory buffer modified and
  2235                              <1> 	;	   must be written to disk.
  2236                              <1> 	; 	If CF = 0  and CL = 1 then
  2237                              <1> 	;	   dir buffer has been written to disk, already.
  2238                              <1> 	;	CF = 1 -> Error code in EAX (AL)
  2239                              <1> 	;
  2240                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2241                              <1> 
  2242                              <1> loc_locate_current_dir_entry:
  2243 000083E7 56                  <1> 	push	esi
  2244 000083E8 89C1                <1> 	mov	ecx, eax
  2245 000083EA BA20000000          <1> 	mov	edx, 32
  2246 000083EF F7E2                <1> 	mul	edx 
  2247 000083F1 A3[7CDA0000]        <1> 	mov	[LCDE_ByteOffset], eax
  2248 000083F6 31DB                <1> 	xor	ebx, ebx
  2249 000083F8 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  2250 000083FE A0[CAD70000]        <1>         mov     al, [DirBuff_DRV]
  2251 00008403 2C41                <1> 	sub	al, 'A'
  2252 00008405 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2253 0000840A 01DE                <1> 	add	esi, ebx
  2254 0000840C 38C7                <1> 	cmp	bh, al
  2255 0000840E 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2256                              <1> loc_lcde_cdl_check:
  2257 00008414 803D[A0CF0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2258 0000841B 772A                <1> 	ja	short loc_lcde_calc_dirbuff_cluster_offset
  2259                              <1> 	; 27/02/2016
  2260                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2261                              <1> 	; (Root Directory Entries for FAT32 = 0)
  2262 0000841D 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2263 00008421 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2264                              <1> 
  2265                              <1> loc_lcde_cdl_check_FAT12_16:
  2266 00008423 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2267 00008427 6648                <1> 	dec	ax
  2268                              <1> 	;xor	dx, dx  
  2269 00008429 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2270 0000842C 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2271 0000842E 66890D[74DA0000]    <1> 	mov	[LCDE_EntryIndex], cx
  2272 00008435 31C0                <1> 	xor	eax, eax
  2273 00008437 E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2274                              <1> 
  2275                              <1> loc_lcde_stc_12h_retn:
  2276 0000843C 5E                  <1> 	pop	esi
  2277 0000843D 89CB                <1> 	mov	ebx, ecx
  2278 0000843F 89D1                <1> 	mov	ecx, edx
  2279 00008441 B812000000          <1> 	mov	eax, 12h ; No more files
  2280 00008446 C3                  <1> 	retn 
  2281                              <1> 
  2282                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2283 00008447 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2284 0000844A 30FF                <1> 	xor	bh, bh
  2285 0000844C 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2286 00008450 66F7E3              <1> 	mul	bx
  2287 00008453 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2288 00008456 755D                <1> 	jnz	short loc_lcde_invalid_format
  2289                              <1> 	;mov	ecx, eax
  2290 00008458 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2291 0000845B A1[7CDA0000]        <1> 	mov	eax, [LCDE_ByteOffset]
  2292                              <1> 	;sub	edx, edx
  2293 00008460 F7F1                <1> 	div	ecx
  2294 00008462 3DFFFF0000          <1> 	cmp	eax, 65535
  2295 00008467 774C                <1> 	ja	short loc_lcde_invalid_format
  2296                              <1> 
  2297                              <1> 	; cluster sequence number of directory (< 65536)
  2298 00008469 66A3[76DA0000]      <1> 	mov	[LCDE_ClusterSN], ax 
  2299                              <1> 
  2300 0000846F 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2301 00008472 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2302 00008476 6629D2              <1>         sub     dx, dx  ; 0
  2303 00008479 66F7F3              <1> 	div	bx 
  2304 0000847C 66A3[74DA0000]      <1> 	mov	[LCDE_EntryIndex], ax ; dir entry index/sequence number
  2305                              <1> 				      ; (in directory buffer/cluster)	  
  2306                              <1> loc_lcde_get_current_sub_dir_fcluster:
  2307 00008482 A1[9CCF0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2308                              <1> 
  2309                              <1> loc_lcde_get_next_cluster:
  2310 00008487 66833D[76DA0000]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2311 0000848F 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2312 00008491 A3[78DA0000]        <1> 	mov	[LCDE_Cluster], eax
  2313 00008496 E815100000          <1> 	call	get_next_cluster
  2314 0000849B 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2315 0000849D 66FF0D[76DA0000]    <1>   	dec	word [LCDE_ClusterSN]
  2316 000084A4 EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2317                              <1> 
  2318                              <1> loc_lcde_reload_current_directory:
  2319 000084A6 51                  <1> 	push	ecx
  2320 000084A7 E812F6FFFF          <1> 	call	reload_current_directory
  2321 000084AC 59                  <1> 	pop	ecx
  2322 000084AD 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2323 000084B3 5E                  <1> 	pop	esi
  2324 000084B4 C3                  <1> 	retn
  2325                              <1> 
  2326                              <1> loc_lcde_invalid_format:
  2327 000084B5 B80B000000          <1> 	mov	eax, 0Bh ; MSDOS Error code: Invalid Format
  2328                              <1> 	;mov	eax, 0Dh ; MSDOS Error code: Invalid Data
  2329                              <1> loc_lcde_drive_not_ready_read_err:
  2330 000084BA F9                  <1> 	stc
  2331 000084BB 5E                  <1> 	pop	esi 
  2332 000084BC C3                  <1> 	retn  
  2333                              <1> 
  2334                              <1> loc_lcde_check_gnc_error:
  2335 000084BD 09C0                <1> 	or	eax, eax
  2336 000084BF 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2337 000084C1 66FF0D[76DA0000]    <1> 	dec	word [LCDE_ClusterSN]
  2338 000084C8 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2339 000084CA A1[78DA0000]        <1> 	mov	eax, [LCDE_Cluster]
  2340                              <1> 
  2341                              <1> loc_lcde_check_dir_buffer_cluster:
  2342 000084CF 3B05[D1D70000]      <1> 	cmp	eax, [DirBuff_Cluster]
  2343 000084D5 755C                <1> 	jne	short loc_lcde_load_dir_cluster
  2344 000084D7 803D[CCD70000]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2345 000084DE 7727                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2346 000084E0 803D[A0CF0000]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2347 000084E7 775F                <1> 	ja	short loc_lcde_load_dir_cluster_0
  2348                              <1> 	; 27/02/2016
  2349                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2350 000084E9 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2351 000084ED 7359                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2352                              <1> 	;
  2353 000084EF 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2354 000084F3 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2355 000084F7 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2356                              <1> 
  2357 000084FB 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2358 000084FE EB54                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2359                              <1> 
  2360                              <1> loc_lcde_validate_dirBuff:
  2361 00008500 C605[CCD70000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2362                              <1> 
  2363                              <1> lcde_check_dir_buffer_cluster_next:
  2364 00008507 0FB71D[74DA0000]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2365 0000850E 663B1D[CFD70000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2366 00008515 779E                <1> 	ja	short loc_lcde_invalid_format 
  2367 00008517 B820000000          <1> 	mov	eax, 32
  2368 0000851C F7E3                <1> 	mul	ebx
  2369                              <1> 	;or	edx, edx
  2370                              <1> 	;jnz	short loc_lcde_invalid_format
  2371                              <1> 
  2372 0000851E BF00000800          <1> 	mov	edi, Directory_Buffer  
  2373 00008523 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2374                              <1> 
  2375                              <1> loc_lcde_dir_buffer_last_check:
  2376 00008525 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
  2377 0000852A 0FB60D[CCD70000]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2378                              <1> 
  2379                              <1> loc_lcde_retn:
  2380 00008531 5E                  <1> 	pop	esi
  2381 00008532 C3                  <1> 	retn
  2382                              <1> 
  2383                              <1> loc_lcde_load_dir_cluster:
  2384                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2385                              <1> 	;jne	short loc_lcde_load_dir_cluster_n2
  2386 00008533 50                  <1> 	push	eax
  2387 00008534 E8E4FCFFFF          <1> 	call	save_directory_buffer
  2388 00008539 58                  <1> 	pop	eax
  2389 0000853A 72F5                <1> 	jc	short loc_lcde_retn
  2390                              <1> 
  2391                              <1> loc_lcde_load_dir_cluster_n2:
  2392 0000853C C605[CCD70000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2393 00008543 A3[D1D70000]        <1> 	mov	[DirBuff_Cluster], eax
  2394                              <1> 
  2395                              <1> loc_lcde_load_dir_cluster_0:
  2396 00008548 83E802              <1> 	sub	eax, 2
  2397 0000854B 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2398 0000854F F7E1                <1> 	mul	ecx
  2399 00008551 034668              <1>         add     eax, [esi+LD_DATABegin]
  2400                              <1> 
  2401                              <1> loc_lcde_load_dir_cluster_1:
  2402 00008554 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2403                              <1> 	; ecx = sector count
  2404 00008559 E82D350000          <1> 	call	disk_read
  2405 0000855E 73A0                <1> 	jnc	short loc_lcde_validate_dirBuff
  2406                              <1> 
  2407                              <1> 	; 23/03/2016
  2408 00008560 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  2409 00008565 EBCA                <1> 	jmp	short loc_lcde_retn
  2410                              <1> 
  2411                              <1> 
  2412                              <1> remove_file:
  2413                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2414                              <1> 	; 10/04/2011 (FILE.ASM, 'proc_delete_file')
  2415                              <1> 	; 09/08/2010
  2416                              <1> 	; INPUT ->
  2417                              <1> 	;	EDI = Directory Buffer Entry Address
  2418                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2419                              <1> 	;	 BL = Longname Entry Length
  2420                              <1> 	;	 BH = Logical DOS Drive Number 
  2421                              <1> 
  2422 00008567 29C0                <1> 	sub	eax, eax
  2423 00008569 88FC                <1> 	mov	ah, bh
  2424 0000856B BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2425 00008570 01C6                <1> 	add	esi, eax
  2426                              <1> 
  2427 00008572 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2428 00008576 7312                <1> 	jnb	short loc_del_fat_file 
  2429                              <1>               
  2430 00008578 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2431 0000857C 7406                <1> 	je	short loc_del_fs_file
  2432                              <1> 
  2433                              <1> loc_del_file_invalid_format:
  2434 0000857E 30E4                <1> 	xor	ah, ah
  2435 00008580 B00B                <1> 	mov	al, 0Bh ; Invalid Format
  2436 00008582 F9                  <1> 	stc 
  2437 00008583 C3                  <1> 	retn
  2438                              <1> 
  2439                              <1> loc_del_fs_file:
  2440 00008584 E8200F0000          <1> 	call	delete_fs_file
  2441 00008589 C3                  <1> 	retn
  2442                              <1> 
  2443                              <1> loc_del_fat_file:
  2444 0000858A E808000000          <1> 	call	delete_directory_entry
  2445 0000858F 7205                <1> 	jc	short loc_del_file_err_retn 
  2446                              <1> 
  2447                              <1> loc_delfile_unlink_cluster_chain:
  2448 00008591 E834170000          <1> 	call	truncate_cluster_chain
  2449                              <1> 	;jc	short loc_del_file_err_retn
  2450                              <1> 
  2451                              <1> loc_delfile_return:
  2452                              <1> loc_del_file_err_retn:
  2453 00008596 C3                  <1> 	retn
  2454                              <1> 
  2455                              <1> delete_directory_entry:
  2456                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2457                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_directory_entry')
  2458                              <1> 	; 10/04/2011 
  2459                              <1> 	; INPUT ->
  2460                              <1> 	; 	ESI = Logical Dos Drive Descripton Table Address 
  2461                              <1> 	;	EDI = Directory Buffer Entry Address
  2462                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2463                              <1> 	;	 BL = Longname Entry Length
  2464                              <1> 	; OUTPUT ->
  2465                              <1> 	; 	ESI = Logical dos drive descripton table address 
  2466                              <1> 	;	EAX = First cluster to be truncated/unlinked
  2467                              <1> 	;       CF = 1 -> Error code in EAX (AL)
  2468                              <1> 	;       CF = 0 & BH <> 0 -> LMDT write error  (BH = 1)
  2469                              <1> 	;       CF = 0 & BL <> 0 -> Long name delete error (BL = FFh) 
  2470                              <1> 	;
  2471                              <1> 	;  (EDI, EBX, ECX register contents will be changed)
  2472                              <1> 
  2473 00008597 881D[0EDA0000]      <1> 	mov	[DelFile_LNEL], bl
  2474 0000859D 66890D[0CDA0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2475                              <1> 
  2476 000085A4 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2477 000085A8 C1E010              <1> 	shl	eax, 16
  2478 000085AB 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2479                              <1> 
  2480 000085AF A3[08DA0000]        <1> 	mov	[DelFile_FCluster], eax
  2481                              <1> 
  2482                              <1> loc_del_short_name:
  2483 000085B4 C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2484                              <1> 
  2485 000085B7 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2486 000085BE E85AFCFFFF          <1> 	call	save_directory_buffer
  2487 000085C3 723D                <1> 	jc	short loc_delete_direntry_err_return
  2488                              <1>  
  2489                              <1> loc_del_long_name:
  2490 000085C5 0FB615[0EDA0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2491 000085CC 08D2                <1> 	or	dl, dl
  2492 000085CE 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2493                              <1> 
  2494 000085D0 8835[0EDA0000]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2495                              <1>   
  2496 000085D6 0FB705[0CDA0000]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2497 000085DD 29D0                <1> 	sub	eax, edx
  2498                              <1> 	;jnc	short loc_del_long_name_continue
  2499 000085DF 7205                <1> 	jc	short loc_del_dir_entry_update_parent_dir_lm_date   
  2500                              <1> 
  2501                              <1> ;loc_del_direntry_inv_data_return:
  2502                              <1> ;	mov	eax, 0Dh ; Invalid data
  2503                              <1> ;	retn
  2504                              <1> 
  2505                              <1> loc_del_long_name_continue: 
  2506                              <1> 	; AX = Directory Entry Number of the long name last entry
  2507 000085E1 E897FDFFFF          <1> 	call	delete_longname
  2508                              <1> 	;jc	short loc_delete_direntry_err_return
  2509                              <1> 
  2510                              <1> loc_del_dir_entry_update_parent_dir_lm_date:
  2511 000085E6 801D[0EDA0000]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2512                              <1> 
  2513 000085ED E8C6FCFFFF          <1> 	call	update_parent_dir_lmdt
  2514 000085F2 B700                <1> 	mov	bh, 0
  2515 000085F4 80D700              <1> 	adc	bh, 0
  2516                              <1> 
  2517 000085F7 8A1D[0EDA0000]      <1> 	mov	bl, byte [DelFile_LNEL]
  2518                              <1>  
  2519                              <1> loc_delete_direntry_return:
  2520 000085FD A1[08DA0000]        <1> 	mov	eax, [DelFile_FCluster]
  2521                              <1> loc_delete_direntry_err_return:
  2522 00008602 C3                  <1> 	retn
  2523                              <1> 
  2524                              <1> rename_directory_entry:
  2525                              <1> 	; 06/03/2016 (TRDOS 386 = TRDOS v2.0)
  2526                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_rename_directory_entry')
  2527                              <1> 	; 19/11/2010
  2528                              <1> 	; INPUT -> (Current Directory)
  2529                              <1> 	;	CX = Directory Entry Number
  2530                              <1> 	;      EAX = First Cluster number of file or directory
  2531                              <1> 	;      EBX = Longname Length (dir entry count) (< 256)
  2532                              <1> 	;      ESI = New file (or directory) name (no path).
  2533                              <1> 	;           (ASCIIZ string)  
  2534                              <1> 	; OUTPUT -> 
  2535                              <1> 	;      CF = 0 -> successfull
  2536                              <1> 	;      CF = 1 -> error code in EAX (AL)
  2537                              <1> 	;
  2538                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2539                              <1> 
  2540 00008603 803D[A1CF0000]00    <1> 	cmp	byte [Current_FATType], 0
  2541 0000860A 7706                <1> 	ja	short loc_rename_directory_entry
  2542                              <1> 
  2543 0000860C E8990E0000          <1> 	call	rename_fs_file_or_directory
  2544 00008611 C3                  <1> 	retn 
  2545                              <1> 	
  2546                              <1> loc_rename_directory_entry:
  2547 00008612 881D[0EDA0000]      <1> 	mov	[DelFile_LNEL], bl
  2548 00008618 66890D[0CDA0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2549 0000861F A3[08DA0000]        <1> 	mov	[DelFile_FCluster], eax
  2550                              <1> 
  2551 00008624 0FB7C1              <1> 	movzx	eax, cx
  2552 00008627 E8BBFDFFFF          <1> 	call	locate_current_dir_entry
  2553 0000862C 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2554                              <1> 
  2555                              <1> loc_rename_direntry_pop_retn:
  2556 0000862E C3                  <1> 	retn
  2557                              <1> 
  2558                              <1> loc_rename_direntry_pop_invd_retn:
  2559 0000862F F9                  <1> 	stc
  2560                              <1> loc_rename_direntry_invd_retn:
  2561 00008630 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  2562                              <1> loc_rename_retn:
  2563 00008635 C3                  <1> 	retn 
  2564                              <1> 
  2565                              <1> loc_rename_direntry_check_fcluster:
  2566 00008636 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2567 0000863A 66C1E210            <1> 	shl	dx, 16
  2568 0000863E 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2569 00008642 3B15[08DA0000]      <1> 	cmp	edx, [DelFile_FCluster]
  2570 00008648 75E5                <1> 	jne	short loc_rename_direntry_pop_invd_retn
  2571                              <1> 	; ESI = New file (or directory) name. (ASCIIZ string)
  2572                              <1> 	; 06/03/2016
  2573                              <1> 	; TRDOS v2 - NOTE: 'convert_file_name' procedure
  2574                              <1> 	; has been modified for eliminating following situation.
  2575                              <1> 	; 
  2576                              <1> 	; TRDOS v1 - NOTE: If file/dir name is more than 11 bytes
  2577                              <1> 	; without a dot, attributes (edi+11) byte will be overwritten !
  2578                              <1> 	; (Dot file name input must be proper for 11 byte dir entry
  2579                              <1> 	;  type file name output.) 
  2580 0000864A E89FF6FFFF          <1> 	call	convert_file_name
  2581                              <1> 
  2582 0000864F C605[CCD70000]02    <1>         mov     byte [DirBuff_ValidData], 2
  2583 00008656 E8C2FBFFFF          <1> 	call	save_directory_buffer
  2584 0000865B 72D8                <1> 	jc	short loc_rename_retn
  2585                              <1> 
  2586                              <1> loc_rename_direntry_del_ln:
  2587 0000865D 0FB615[0EDA0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2588 00008664 08D2                <1> 	or	dl, dl
  2589 00008666 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2590                              <1> 
  2591 00008668 0FB705[0CDA0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2592 0000866F 29D0                <1> 	sub	eax, edx
  2593 00008671 72BD                <1> 	jc	short loc_rename_direntry_invd_retn
  2594                              <1> 
  2595                              <1> loc_rename_direntry_del_ln_continue: 
  2596                              <1> 	; EAX = Directory Entry Number of the long name last entry
  2597 00008673 E805FDFFFF          <1> 	call	delete_longname
  2598                              <1> 
  2599                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2600 00008678 E83BFCFFFF          <1> 	call	update_parent_dir_lmdt
  2601 0000867D 31C0                <1> 	xor	eax, eax 
  2602 0000867F C3                  <1> 	retn
  2603                              <1> 
  2604                              <1> move_source_file_to_destination_file:
  2605                              <1> 	; 11/03/2016
  2606                              <1> 	; 10/03/2016 (TRDOS 386 = TRDOS v2.0)
  2607                              <1> 	; 01/08/2011 (FILE.ASM)
  2608                              <1> 	; 04/08/2010
  2609                              <1> 	;
  2610                              <1> 	;   Phase 1 -> Check destination file, 
  2611                              <1> 	;              'not found' is required
  2612                              <1> 	;   Phase 2 -> Check source file
  2613                              <1> 	;              'found' and proper attributes is required
  2614                              <1> 	;   Phase 3 -> Make destination directory entry,
  2615                              <1> 	;           add new dir cluster or section if it is required
  2616                              <1> 	;   Phase 4 -> Delete source directory entry.
  2617                              <1> 	;       cf = 1 causes to return before the phase 4.
  2618                              <1> 	;    (source file protection against any possible errors)    
  2619                              <1> 	;
  2620                              <1> 	; 08/05/2011 major modification
  2621                              <1> 	;            -> destination file deleting is removed   
  2622                              <1> 	;            for msdos move/rename compatibility.
  2623                              <1> 	;            (Access denied error will return if
  2624                              <1> 	;            the destination file is found...)
  2625                              <1> 	; INPUT ->
  2626                              <1> 	;	 ESI = Source File Pathname (Asciiz)
  2627                              <1> 	;        EDI = Destination File Pathname (Asciiz)
  2628                              <1> 	;        AL = 0 --> Interrupt (System call)
  2629                              <1> 	;        AL > 0 --> Command Interpreter (Question)
  2630                              <1> 	;        AL = 1 --> Question Phase
  2631                              <1> 	;        AL = 2 --> Progress Phase        
  2632                              <1> 	; OUTPUT -> 
  2633                              <1> 	;	 cf = 0 -> OK
  2634                              <1> 	;        EAX = Destination directory first cluster
  2635                              <1> 	;        ESI = Logical DOS drive description table 
  2636                              <1> 	;        EBX = Destination file structure offset
  2637                              <1> 	;        CX = 0 (CX > 0 --> calculate free space error)
  2638                              <1> 	;        cf = 1 -> Error code in EAX (AL) 
  2639                              <1> 	;
  2640                              <1> 	;  (EDX, ECX, EBX, ESI, EDI will be changed)
  2641                              <1> 
  2642 00008680 3C02                <1> 	cmp	al, 2
  2643 00008682 0F846D010000        <1> 	je	msftdf_df2_check_directory
  2644 00008688 A2[8ADB0000]        <1> 	mov	[move_cmd_phase], al
  2645                              <1> 
  2646                              <1> msftdf_parse_sf_path:
  2647                              <1> 	; ESI = ASCIIZ pathname (Source)
  2648 0000868D 57                  <1> 	push	edi 
  2649 0000868E BF[88DA0000]        <1> 	mov	edi, SourceFile_Drv
  2650 00008693 E821F7FFFF          <1> 	call	parse_path_name
  2651 00008698 5E                  <1> 	pop	esi
  2652 00008699 7211                <1> 	jc	short msftdf_psf_retn
  2653                              <1> 
  2654                              <1> msftdf_parse_df_path:
  2655                              <1> 	; ESI = ASCIIZ pathname	(Destination)
  2656 0000869B BF[08DB0000]        <1> 	mov	edi, DestinationFile_Drv
  2657 000086A0 E814F7FFFF          <1> 	call	parse_path_name
  2658 000086A5 7306                <1> 	jnc	short msftdf_check_sf_drv
  2659                              <1> 
  2660 000086A7 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  2661 000086A9 7602                <1> 	jna	short msftdf_check_sf_drv
  2662                              <1> 
  2663                              <1> msftdf_stc_retn:
  2664 000086AB F9                  <1> 	stc
  2665                              <1> msftdf_psf_retn:
  2666 000086AC C3                  <1> 	retn 
  2667                              <1> 
  2668                              <1> msftdf_check_sf_drv:
  2669 000086AD A0[88DA0000]        <1> 	mov	al, [SourceFile_Drv]
  2670                              <1> 
  2671                              <1> msftdf_check_df_drv:
  2672 000086B2 8A15[08DB0000]      <1> 	mov	dl, [DestinationFile_Drv]
  2673                              <1> 
  2674                              <1> msftdf_compare_sf_df_drv:
  2675 000086B8 29DB                <1> 	sub	ebx, ebx
  2676 000086BA 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  2677 000086C0 38C2                <1> 	cmp	dl, al
  2678 000086C2 7409                <1> 	je	short msftdf_check_sf_df_drv_ok
  2679                              <1> 
  2680                              <1> msftdf_not_same_drv:
  2681                              <1>         ; DL = source file's drive number
  2682 000086C4 88C6                <1> 	mov	dh, al ; destination file's drive number
  2683 000086C6 B811000000          <1> 	mov	eax, 11h ; Not the same drive
  2684 000086CB F9                  <1> 	stc
  2685 000086CC C3                  <1> 	retn 
  2686                              <1> 
  2687                              <1> msftdf_check_sf_df_drv_ok:
  2688 000086CD 8815[8BDB0000]      <1> 	mov	[msftdf_sf_df_drv], dl
  2689                              <1> 
  2690 000086D3 29C0                <1>         sub	eax, eax
  2691 000086D5 88D4                <1> 	mov	ah, dl
  2692 000086D7 0500010900          <1> 	add	eax, Logical_DOSDisks
  2693 000086DC A3[8CDB0000]        <1> 	mov	[msftdf_drv_offset], eax
  2694                              <1> 
  2695 000086E1 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  2696 000086E3 7407                <1> 	je	short msftdf_df_check_directory
  2697                              <1> 
  2698                              <1> msftdf_change_drv:
  2699 000086E5 E839C1FFFF          <1> 	call 	change_current_drive
  2700 000086EA 725B                <1> 	jc	short msftdf_df_error_retn
  2701                              <1> 	  
  2702                              <1> msftdf_check_destination_file:
  2703                              <1> msftdf_df_check_directory:
  2704 000086EC BE[09DB0000]        <1> 	mov	esi, DestinationFile_Directory
  2705 000086F1 803E20              <1> 	cmp	byte [esi], 20h
  2706 000086F4 760F                <1> 	jna	short msftdf_df_find_1
  2707                              <1> 
  2708                              <1> msftdf_df_change_directory:
  2709 000086F6 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2710 000086FC 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2711 000086FE E8A2F0FFFF          <1> 	call	change_current_directory
  2712 00008703 7242                <1> 	jc	short msftdf_df_error_retn
  2713                              <1> 
  2714                              <1> ;msftdf_df_change_prompt_dir_string:
  2715                              <1> ;	call 	change_prompt_dir_string
  2716                              <1> 
  2717                              <1> msftdf_df_find_1:
  2718 00008705 BE[4ADB0000]        <1>         mov     esi, DestinationFile_Name
  2719 0000870A 803E20              <1> 	cmp	byte [esi], 20h
  2720 0000870D 761F                <1> 	jna	short msftdf_df_copy_sf_name
  2721                              <1> 
  2722                              <1> msftdf_df_find_2:
  2723 0000870F 6631C0              <1> 	xor	ax, ax ; DestinationFile_AttributesMask -> any/zero
  2724 00008712 E8A2D4FFFF          <1> 	call	find_first_file
  2725 00008717 737F                <1> 	jnc	short msftdf_permission_denied_retn
  2726                              <1> 
  2727                              <1> msftdf_df_check_error_code:
  2728                              <1> 	;cmp	eax, 2 ; File not found error
  2729 00008719 3C02                <1> 	cmp	al, 2
  2730 0000871B 7529                <1> 	jne	short msftdf_df_stc_retn
  2731                              <1>               
  2732                              <1> msftdf_convert_df_direntry_name:
  2733 0000871D BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  2734 00008722 BF[5ADB0000]        <1> 	mov	edi, DestinationFile_DirEntry
  2735 00008727 E8C2F5FFFF          <1> 	call	convert_file_name
  2736 0000872C EB1A                <1>   	jmp	short msftdf_restore_current_dir_1
  2737                              <1> 
  2738                              <1> msftdf_df_copy_sf_name:
  2739 0000872E 89F7                <1> 	mov	edi, esi
  2740 00008730 57                  <1> 	push	edi 
  2741 00008731 BE[CADA0000]        <1>         mov     esi, SourceFile_Name
  2742 00008736 B90C000000          <1> 	mov	ecx, 12
  2743                              <1> msftdf_df_copy_sf_name_loop:
  2744 0000873B AC                  <1> 	lodsb
  2745 0000873C AA                  <1>         stosb
  2746 0000873D 08C0                <1> 	or	al, al
  2747 0000873F 7402                <1> 	jz	short msftdf_df_copy_sf_name_ok	
  2748 00008741 E2F8                <1>         loop    msftdf_df_copy_sf_name_loop
  2749                              <1> msftdf_df_copy_sf_name_ok:	
  2750 00008743 5E                  <1> 	pop	esi  
  2751 00008744 EBC9                <1> 	jmp	short msftdf_df_find_2
  2752                              <1> 
  2753                              <1> msftdf_df_stc_retn:
  2754 00008746 F9                  <1> 	stc
  2755                              <1> msftdf_restore_cdir_failed:
  2756                              <1> msftdf_df_error_retn:
  2757 00008747 C3                  <1> 	retn
  2758                              <1> 
  2759                              <1> msftdf_restore_current_dir_1:
  2760 00008748 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2761 0000874F 760D                <1> 	jna	short msftdf_sf_check_directory
  2762 00008751 8B35[8CDB0000]      <1> 	mov	esi, [msftdf_drv_offset] 
  2763 00008757 E879C1FFFF          <1> 	call	restore_current_directory
  2764 0000875C 72E9                <1> 	jc	short msftdf_restore_cdir_failed
  2765                              <1> 
  2766                              <1> msftdf_sf_check_directory:
  2767 0000875E BE[89DA0000]        <1> 	mov	esi, SourceFile_Directory
  2768 00008763 803E20              <1> 	cmp	byte [esi], 20h
  2769 00008766 760F                <1> 	jna	short msftdf_sf_find
  2770                              <1> msftdf_sf_change_directory:
  2771 00008768 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2772 0000876E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2773 00008770 E830F0FFFF          <1> 	call	change_current_directory
  2774 00008775 7227                <1> 	jc	short msftdf_return
  2775                              <1> 
  2776                              <1> ;msftdf_sf_change_prompt_dir_string:
  2777                              <1> ;	call	change_prompt_dir_string
  2778                              <1> 
  2779                              <1> msftdf_sf_find:
  2780 00008777 BE[CADA0000]        <1>         mov     esi, SourceFile_Name  ; Offset 66
  2781 0000877C 66B80018            <1> 	mov	ax, 1800h ; Only files
  2782 00008780 E834D4FFFF          <1> 	call	find_first_file
  2783 00008785 7217                <1> 	jc	short msftdf_return
  2784                              <1> 
  2785                              <1> msftdf_sf_ambgfn_check:
  2786 00008787 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  2787 0000878A 7407                <1> 	jz	short msftdf_sf_found
  2788                              <1> 
  2789                              <1> msftdf_ambiguous_file_name_error:
  2790 0000878C B802000000          <1> 	mov	eax, 2 ; File not found error
  2791 00008791 F9                  <1> 	stc
  2792 00008792 C3                  <1> 	retn
  2793                              <1> 
  2794                              <1> msftdf_sf_found:
  2795 00008793 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  2796 00008796 7416                <1> 	jz	short msftdf_save_sf_structure
  2797                              <1> 
  2798                              <1> msftdf_permission_denied_retn:
  2799 00008798 B805000000          <1> 	mov	eax, 05h ; Access (Permission) denied !
  2800 0000879D F9                  <1> 	stc
  2801                              <1> msftdf_rest_cdir_err_retn:
  2802                              <1> msftdf_return:
  2803 0000879E C3                  <1> 	retn
  2804                              <1> 
  2805                              <1> msftdf_phase_1_return:
  2806 0000879F 31C0                <1> 	xor	eax, eax
  2807 000087A1 A2[8ADB0000]        <1> 	mov	[move_cmd_phase], al ; 0
  2808 000087A6 FEC0                <1> 	inc	al ; mov al, 1
  2809 000087A8 BB[F5870000]        <1> 	mov	ebx, msftdf_df2_check_directory
  2810                              <1> 	;mov	edx, 0FFFFFFFFh 
  2811 000087AD C3                  <1> 	retn
  2812                              <1> 
  2813                              <1> msftdf_save_sf_structure:
  2814 000087AE BE[98D90000]        <1> 	mov	esi, FindFile_DirEntry
  2815 000087B3 BF[DADA0000]        <1> 	mov	edi, SourceFile_DirEntry
  2816 000087B8 B908000000          <1> 	mov	ecx, 8
  2817 000087BD F3A5                <1> 	rep	movsd
  2818                              <1> 
  2819                              <1> msftdf_df_copy_sf_parameters:
  2820 000087BF BE0B000000          <1> 	mov	esi, 11
  2821 000087C4 89F7                <1> 	mov	edi, esi
  2822 000087C6 81C6[DADA0000]      <1> 	add	esi, SourceFile_DirEntry
  2823 000087CC 81C7[5ADB0000]      <1> 	add	edi, DestinationFile_DirEntry
  2824                              <1> 	;mov	ecx, 21
  2825 000087D2 B115                <1> 	mov	cl, 21
  2826 000087D4 F3A4                <1> 	rep	movsb
  2827                              <1> 
  2828                              <1> msftdf_restore_current_dir_2:
  2829 000087D6 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2830 000087DD 760D                <1> 	jna	short msftdf_df2_check_move_cmd_phase
  2831 000087DF 8B35[8CDB0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2832 000087E5 E8EBC0FFFF          <1> 	call	restore_current_directory
  2833 000087EA 72B2                <1> 	jc	short msftdf_rest_cdir_err_retn
  2834                              <1> 
  2835                              <1> msftdf_df2_check_move_cmd_phase:
  2836 000087EC 803D[8ADB0000]01    <1> 	cmp	byte [move_cmd_phase], 1
  2837 000087F3 74AA                <1> 	je	short msftdf_phase_1_return
  2838                              <1> 
  2839                              <1> msftdf_df2_check_directory:
  2840 000087F5 BE[09DB0000]        <1> 	mov	esi, DestinationFile_Directory
  2841 000087FA 803E20              <1> 	cmp	byte [esi], 20h
  2842 000087FD 760F                <1> 	jna	short msftdf_make_dfde_locate_ffe_on_directory
  2843                              <1> msftdf_df2_change_directory:
  2844 000087FF FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2845 00008805 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2846 00008807 E899EFFFFF          <1> 	call	change_current_directory
  2847 0000880C 7290                <1> 	jc	short msftdf_return
  2848                              <1> 
  2849                              <1> ;msftdf_df2_change_prompt_dir_string:
  2850                              <1> ;	call	change_prompt_dir_string
  2851                              <1> 
  2852                              <1> msftdf_make_dfde_locate_ffe_on_directory:
  2853                              <1> 	; Current directory fcluster <> Directory buffer cluster
  2854                              <1> 	; Current directory will be reloaded by
  2855                              <1> 	; 'locate_current_dir_file' procedure
  2856                              <1> 	;
  2857                              <1> 	;xor	ax, ax
  2858 0000880E 31C0                <1> 	xor	eax, eax
  2859 00008810 89C1                <1> 	mov	ecx, eax
  2860 00008812 6649                <1> 	dec	cx ; FFFFh  
  2861                              <1> 		; CX = FFFFh -> find first deleted or free entry
  2862                              <1> 		; ESI would be ASCIIZ filename address if the call
  2863                              <1> 		; would not be for first free or deleted dir entry  
  2864 00008814 E8E0F1FFFF          <1> 	call	locate_current_dir_file
  2865 00008819 733F                <1> 	jnc	msftdf_make_dfde_set_ff_dir_entry
  2866                              <1> 	
  2867                              <1> 	;cmp	eax, 2
  2868 0000881B 3C02                <1>         cmp	al, 2
  2869 0000881D 7537                <1> 	jne	short msftdf_error_retn
  2870                              <1> 
  2871                              <1> msftdf_add_new_dir_entry_check_fs:
  2872 0000881F 8B35[8CDB0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2873 00008825 A1[D1D70000]        <1> 	mov 	eax, [DirBuff_Cluster]
  2874 0000882A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2875 0000882E 7711                <1> 	ja	short msftdf_add_new_subdir_cluster
  2876                              <1> 
  2877                              <1> msftdf_add_new_fs_subdir_section:
  2878                              <1> 	;CL=0, CH=E5h --> deleted entry, CH=0 --> free entry
  2879                              <1>         ;xor	cx, cx
  2880 00008830 30ED                <1> 	xor	ch, ch ; cx = 0 --> add a new subdir section
  2881 00008832 E8750C0000          <1> 	call	add_new_fs_section
  2882 00008837 721E                <1>         jc	short msftdf_dsfde_error_retn
  2883                              <1> 	;mov	[createfile_LastDirCluster], eax
  2884                              <1> 
  2885 00008839 E8950E0000          <1> 	call	load_FS_sub_directory 
  2886                              <1> 	;mov	ebx, Directory_Buffer 
  2887 0000883E 7318                <1> 	jnc	short msftdf_add_new_fs_subdir_section_ok
  2888 00008840 C3                  <1> 	retn	 
  2889                              <1> 
  2890                              <1> msftdf_add_new_subdir_cluster:
  2891 00008841 E863150000          <1> 	call	add_new_cluster
  2892 00008846 720F                <1> 	jc	short msftdf_dsfde_error_retn
  2893                              <1> 	
  2894                              <1> 	;mov	[createfile_LastDirCluster], eax
  2895                              <1> 
  2896 00008848 E8490E0000          <1> 	call	load_FAT_sub_directory
  2897 0000884D 7309                <1> 	jnc	short msftdf_add_new_subdir_cluster_ok
  2898                              <1> 	; EBX = Directory buffer address
  2899                              <1> 
  2900                              <1> msftdf_ansdc_update_parent_dir_lmdt:
  2901                              <1> msftdf_make_dfde_err_upd_pdir_lmdt:
  2902 0000884F 50                  <1> 	push	eax
  2903 00008850 E863FAFFFF          <1> 	call	update_parent_dir_lmdt
  2904 00008855 58                  <1> 	pop	eax
  2905                              <1> 
  2906                              <1> msftdf_error_retn:
  2907 00008856 F9                  <1> 	stc
  2908                              <1> msftdf_dsfde_restore_cdir_failed:
  2909                              <1> msftdf_dsfde_error_retn:
  2910 00008857 C3                  <1> 	retn
  2911                              <1> 
  2912                              <1> msftdf_add_new_fs_subdir_section_ok:
  2913                              <1> msftdf_add_new_subdir_cluster_ok:
  2914 00008858 89DF                <1> 	mov	edi, ebx ; Directory buffer address
  2915                              <1> 
  2916                              <1> msftdf_make_dfde_set_ff_dir_entry:
  2917 0000885A 8B15[9CCF0000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2918 00008860 8915[F0DB0000]      <1> 	mov	[createfile_FFCluster], edx
  2919                              <1> 	; EDI = Directory entry offset
  2920 00008866 BE[5ADB0000]        <1> 	mov	esi, DestinationFile_DirEntry
  2921 0000886B B908000000          <1> 	mov	ecx, 8
  2922 00008870 F3A5                <1> 	rep	movsd
  2923                              <1> 
  2924 00008872 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  2925 00008879 E89FF9FFFF          <1> 	call	save_directory_buffer
  2926 0000887E 72CF                <1> 	jc	short msftdf_make_dfde_err_upd_pdir_lmdt
  2927                              <1> 
  2928                              <1> msftdf_make_dfde_update_pdir_lmdt:
  2929 00008880 E833FAFFFF          <1> 	call	update_parent_dir_lmdt
  2930                              <1> 
  2931                              <1> msftdf_dsfde_restore_current_dir_1:
  2932 00008885 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2933 0000888C 760D                <1> 	jna	short msftdf_dsfde_check_directory
  2934 0000888E 8B35[8CDB0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2935 00008894 E83CC0FFFF          <1> 	call	restore_current_directory
  2936 00008899 72BC                <1> 	jc	short msftdf_dsfde_restore_cdir_failed
  2937                              <1> 
  2938                              <1> msftdf_dsfde_check_directory:
  2939 0000889B BE[89DA0000]        <1> 	mov	esi, SourceFile_Directory
  2940 000088A0 803E20              <1> 	cmp	byte [esi], 20h
  2941 000088A3 760F                <1> 	jna	short msftdf_dsfde_find_file
  2942                              <1> 
  2943                              <1> msftdf_dsfde_change_directory:
  2944 000088A5 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  2945 000088AB 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  2946 000088AD E8F3EEFFFF          <1> 	call	change_current_directory
  2947 000088B2 72A3                <1> 	jc	short msftdf_dsfde_error_retn
  2948                              <1> 
  2949                              <1> ;msftdf_dsfde_sf_change_prompt_dir_string:
  2950                              <1> ;	call	change_prompt_dir_string
  2951                              <1> 
  2952                              <1> msftdf_dsfde_find_file:
  2953 000088B4 BE[CADA0000]        <1> 	mov	esi, SourceFile_Name  ; Offset 66
  2954 000088B9 668B460E            <1> 	mov	ax, [esi+14] ; 80 -> SourceFile_AttributesMask
  2955 000088BD E8F7D2FFFF          <1> 	call	find_first_file
  2956 000088C2 7293                <1> 	jc	short msftdf_dsfde_error_retn
  2957                              <1> 
  2958                              <1> msftdf_dsfde_delete_direntry:
  2959 000088C4 8B35[8CDB0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2960                              <1> 	
  2961 000088CA 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2962 000088CE 770A                <1> 	ja	short msftdf_delete_FAT_direntry
  2963                              <1> 	
  2964 000088D0 30DB                <1> 	xor	bl, bl
  2965                              <1> 	; BL = 0 -> File
  2966                              <1> 	; EDI -> Directory buffer entry offset/address 
  2967 000088D2 E8D60B0000          <1> 	call	delete_fs_directory_entry
  2968 000088D7 7315                <1> 	jnc	short msftdf_dsfde_restore_current_dir_2
  2969 000088D9 C3                  <1> 	retn
  2970                              <1> 
  2971                              <1> msftdf_delete_FAT_direntry:	
  2972 000088DA 8A1D[95D90000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  2973 000088E0 668B0D[C0D90000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  2974                              <1> 	; ESI = Logical DOS drive description table address
  2975                              <1> 	; EDI = Directory buffer entry offset/address 
  2976 000088E7 E8ABFCFFFF          <1> 	call	delete_directory_entry
  2977 000088EC 721C                <1> 	jc	short msftdf_retn
  2978                              <1> 
  2979                              <1> msftdf_dsfde_restore_current_dir_2:
  2980 000088EE 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2981 000088F5 7607                <1> 	jna	short msftdf_new_dir_fcluster_retn
  2982                              <1> 	;mov	esi, [msftdf_drv_offset]
  2983 000088F7 E8D9BFFFFF          <1> 	call	restore_current_directory
  2984 000088FC 720C                <1> 	jc	short msftdf_retn
  2985                              <1> 
  2986                              <1> msftdf_new_dir_fcluster_retn:
  2987 000088FE 31C9                <1> 	xor	ecx, ecx 
  2988 00008900 A1[F0DB0000]        <1> 	mov	eax, [createfile_FFCluster]
  2989 00008905 BB[08DB0000]        <1> 	mov	ebx, DestinationFile_Drv
  2990                              <1> 
  2991                              <1> msftdf_retn:
  2992 0000890A C3                  <1> 	retn
  2993                              <1> 
  2994                              <1> 
  2995                              <1> copy_source_file_to_destination_file:
  2996                              <1> 	; 31/03/2016
  2997                              <1> 	; 30/03/2016
  2998                              <1> 	; 24/03/2016, 25/03/2016, 28/03/2016
  2999                              <1> 	; 21/03/2016, 22/03/2016, 23/03/2016
  3000                              <1> 	; 16/03/2016, 17/03/2016, 18/03/2016
  3001                              <1> 	; 15/03/2016 (TRDOS 386 = TRDOS v2.0)
  3002                              <1> 	; 02/09/2011 (FILE.ASM 'copy_source_file_to_destination_file')
  3003                              <1> 	; 01/08/2010 - 18/05/2011
  3004                              <1> 	;
  3005                              <1> 	;   Command Interpreter phase 1 enter ->
  3006                              <1> 	;           AL = 1 -> Caller is command interpreter
  3007                              <1> 	;           AL = 2 -> The second call, re-enter/continue
  3008                              <1> 	;   Phase 1 -> Check source file
  3009                              <1> 	;              'found' is required
  3010                              <1> 	;   Phase 2 -> Check destination file, 
  3011                              <1> 	;              save 'found' or 'not found' status
  3012                              <1> 	;              'permission denied' error will be return
  3013                              <1> 	;              if attributes have not for ordinary file 
  3014                              <1> 	;              without readonly attribute
  3015                              <1> 	;   Command Interpreter phase 1 return ->
  3016                              <1> 	;              DH = Source file attributes
  3017                              <1> 	;              DL = Destination file found status
  3018                              <1> 	;              EAX = 0 
  3019                              <1> 	;   Command Interpeter phase 2 enter ->
  3020                              <1> 	;              AL = 2 -> Continue from the last position
  3021                              <1> 	;              AH = 
  3022                              <1> 	;   Phase 3 -> Load source file or use read/write cluster method
  3023                              <1> 	;   Phase 4 -> Create destination file if it is not found
  3024                              <1> 	;   Phase 5 -> Open destination file
  3025                              <1> 	;   Phase 6 -> Read from source and write to destination
  3026                              <1> 	;   Phase 7 -> Unload source file, if it is loaded at memory
  3027                              <1> 	;       cf = 1 causes to return before the phase 7
  3028                              <1> 	;              but loaded file will be unloaded
  3029                              <1> 	;	       (allocated memory block will be deallocated) 
  3030                              <1> 	;
  3031                              <1> 	; INPUT -> 
  3032                              <1> 	;	 ESI = Source File Pathname (Asciiz)
  3033                              <1> 	;        EDI = Destination File Pathname (Asciiz)
  3034                              <1> 	;        AL = 0 --> Interrupt (System call)
  3035                              <1> 	;        AL > 0 --> Command Interpreter (Question)
  3036                              <1> 	;        AL = 1 --> Question Phase
  3037                              <1> 	;        AL = 2 --> Progress Phase        
  3038                              <1> 	;
  3039                              <1> 	; OUTPUT -> 
  3040                              <1> 	;	cf = 0 -> OK
  3041                              <1> 	;	EAX = Destination file first cluster
  3042                              <1> 	;
  3043                              <1> 	;        CL > 0 if there is file reading error before EOF
  3044                              <1> 	;	        (incomplete copy) 
  3045                              <1> 	;        CH > 0 if file is (full) loaded at memory
  3046                              <1> 	;
  3047                              <1> 	;	cf = 1 -> Error code in AL (EAX) 
  3048                              <1> 	;
  3049                              <1> 	; (EBX, ECX, ESI, EDI register contents will be changed)           
  3050                              <1> 
  3051                              <1> 
  3052 0000890B 3C02                <1> 	cmp	al, 2
  3053 0000890D 0F844C020000        <1> 	je	csftdf2_check_cdrv
  3054                              <1> 
  3055                              <1> ; Phase 1
  3056                              <1> 
  3057 00008913 A2[B0DB0000]        <1> 	mov	byte [copy_cmd_phase], al
  3058                              <1> 
  3059 00008918 57                  <1> 	push	edi ; *
  3060                              <1> 
  3061                              <1> csftdf_parse_sf_path:
  3062 00008919 BF[88DA0000]        <1> 	mov	edi, SourceFile_Drv
  3063 0000891E E896F4FFFF          <1> 	call	parse_path_name
  3064 00008923 721C                <1> 	jc	short csftdf_parse_sf_path_failed
  3065                              <1> 
  3066                              <1> csftdf_parse_df_path:	
  3067 00008925 5E                  <1> 	pop	esi ; * (pushed edi) 
  3068                              <1> 
  3069                              <1> csftdf_sf_check_filename_exists:
  3070 00008926 803D[CADA0000]21    <1> 	cmp	byte [SourceFile_Name], 21h
  3071 0000892D 7215                <1> 	jb	short csftdf_sf_file_not_found_error
  3072                              <1> 
  3073 0000892F BF[08DB0000]        <1> 	mov	edi, DestinationFile_Drv
  3074 00008934 E880F4FFFF          <1> 	call	parse_path_name
  3075 00008939 7310                <1> 	jnc	short csftdf_check_sf_cdrv
  3076                              <1> 	
  3077 0000893B 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  3078 0000893D 760C                <1> 	jna	short csftdf_check_sf_cdrv
  3079                              <1> 
  3080                              <1> csftdf_parse_df_path_failed:
  3081 0000893F F9                  <1> 	stc 
  3082                              <1> csftdf_sf_error_retn: 
  3083 00008940 C3                  <1> 	retn
  3084                              <1> 
  3085                              <1> csftdf_parse_sf_path_failed:	
  3086 00008941 5F                  <1> 	pop	edi ; *
  3087 00008942 EBFC                <1> 	jmp	short csftdf_sf_error_retn
  3088                              <1> 
  3089                              <1> csftdf_sf_file_not_found_error:
  3090 00008944 B802000000          <1> 	mov	eax, 2 ; File not found 
  3091 00008949 EBF5                <1> 	jmp	short csftdf_sf_error_retn
  3092                              <1> 
  3093                              <1> csftdf_check_sf_cdrv:
  3094 0000894B 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  3095                              <1> 
  3096 00008951 883D[B3DB0000]      <1> 	mov	[csftdf_cdrv], bh ; 23/03/2016
  3097                              <1> 
  3098 00008957 8A15[88DA0000]      <1> 	mov	dl, [SourceFile_Drv]
  3099 0000895D 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  3100 0000895F 7407                <1> 	je	short csftdf_sf_check_directory
  3101                              <1> 
  3102 00008961 E8BDBEFFFF          <1> 	call	change_current_drive
  3103 00008966 72D8                <1> 	jc	short csftdf_sf_error_retn
  3104                              <1> 
  3105                              <1> csftdf_sf_check_directory:
  3106 00008968 BE[89DA0000]        <1> 	mov	esi, SourceFile_Directory
  3107 0000896D 803E20              <1> 	cmp	byte [esi], 20h
  3108 00008970 760F                <1> 	jna	short csftdf_find_sf
  3109                              <1> 
  3110                              <1> csftdf_sf_change_directory:
  3111 00008972 FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3112 00008978 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3113 0000897A E826EEFFFF          <1> 	call	change_current_directory
  3114 0000897F 72BF                <1> 	jc	short csftdf_sf_error_retn
  3115                              <1> 
  3116                              <1> ;csftdf_sf_change_prompt_dir_string:
  3117                              <1> ;	call	change_prompt_dir_string
  3118                              <1> 
  3119                              <1> csftdf_find_sf:
  3120 00008981 BE[CADA0000]        <1> 	mov	esi, SourceFile_Name
  3121 00008986 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3122 0000898A E82AD2FFFF          <1> 	call	find_first_file
  3123 0000898F 72AF                <1> 	jc	short csftdf_sf_error_retn
  3124                              <1> 
  3125                              <1> csftdf_sf_ambgfn_check:
  3126 00008991 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3127 00008994 7407                <1> 	jz	short csftdf_sf_found
  3128                              <1> 
  3129                              <1> csftdf_ambiguous_file_name_error:
  3130 00008996 B802000000          <1> 	mov	eax, 2 ; File not found error
  3131 0000899B F9                  <1> 	stc
  3132 0000899C C3                  <1> 	retn
  3133                              <1> 
  3134                              <1> csftdf_sf_found:
  3135 0000899D A3[B4DB0000]        <1> 	mov	[csftdf_filesize], eax
  3136                              <1> 
  3137 000089A2 09C0                <1> 	or	eax, eax
  3138 000089A4 7507                <1> 	jnz	short csftdf_set_source_file_direnry
  3139                              <1> 
  3140                              <1> csftdf_sf_file_size_zero:
  3141 000089A6 B80E000000          <1> 	mov	eax, 0Eh ; TRDOS zero length error
  3142 000089AB F9                  <1> 	stc
  3143 000089AC C3                  <1> 	retn
  3144                              <1> 
  3145                              <1> csftdf_set_source_file_direnry:
  3146 000089AD BE[98D90000]        <1> 	mov	esi, FindFile_DirEntry
  3147 000089B2 BF[DADA0000]        <1> 	mov	edi, SourceFile_DirEntry
  3148 000089B7 B908000000          <1> 	mov	ecx, 8
  3149 000089BC F3A5                <1> 	rep	movsd
  3150                              <1> 
  3151                              <1> csftdf_sf_restore_cdrv:
  3152                              <1> 	; 22/03/2016
  3153 000089BE 8A15[B3DB0000]      <1> 	mov	dl, [csftdf_cdrv]
  3154 000089C4 3A15[A2CF0000]      <1> 	cmp	dl, [Current_Drv]
  3155 000089CA 7407                <1> 	je	short csftdf_sf_restore_cdir
  3156 000089CC E852BEFFFF          <1> 	call	change_current_drive 
  3157 000089D1 724F                <1> 	jc	short csftdf_df_error_retn ; 30/03/2016
  3158                              <1> 
  3159                              <1> csftdf_sf_restore_cdir:
  3160 000089D3 803D[C6BD0000]00    <1> 	cmp	byte [Restore_CDIR], 0
  3161 000089DA 7612                <1> 	jna	short csftdf_df_check_filename_exists
  3162 000089DC 29C0                <1> 	sub	eax, eax
  3163 000089DE BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3164 000089E3 88D4                <1> 	mov	ah, dl ; byte [csftdf_cdrv]
  3165 000089E5 01C6                <1> 	add	esi, eax
  3166 000089E7 E8E9BEFFFF          <1> 	call	restore_current_directory
  3167 000089EC 7234                <1> 	jc	short csftdf_df_error_retn
  3168                              <1>   
  3169                              <1> csftdf_df_check_filename_exists:
  3170 000089EE 803D[4ADB0000]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  3171 000089F5 7716                <1> 	ja	short csftdf_check_df_cdrv
  3172                              <1> 
  3173                              <1> csftdf_copy_sf_name:
  3174 000089F7 BF[4ADB0000]        <1> 	mov	edi, DestinationFile_Name
  3175 000089FC BE[CADA0000]        <1> 	mov	esi, SourceFile_Name
  3176 00008A01 B10C                <1> 	mov	cl, 12
  3177                              <1> 
  3178                              <1> csftdf_df_copy_sf_name_loop:
  3179 00008A03 AC                  <1> 	lodsb
  3180 00008A04 AA                  <1> 	stosb
  3181 00008A05 08C0                <1> 	or	al, al
  3182 00008A07 7404                <1> 	jz	short csftdf_check_df_cdrv             
  3183 00008A09 FEC9                <1> 	dec	cl
  3184 00008A0B 75F6                <1> 	jnz	csftdf_df_copy_sf_name_loop
  3185                              <1> 
  3186                              <1> csftdf_check_df_cdrv:
  3187 00008A0D 8A15[08DB0000]      <1> 	mov	dl, [DestinationFile_Drv]
  3188 00008A13 3A15[A2CF0000]      <1> 	cmp	dl, [Current_Drv]
  3189 00008A19 7408                <1> 	je	short csftdf_df_check_directory
  3190                              <1> 
  3191 00008A1B E803BEFFFF          <1> 	call	change_current_drive
  3192 00008A20 7301                <1> 	jnc	short csftdf_df_check_directory
  3193                              <1> 
  3194                              <1> csftdf_df_error_retn:
  3195 00008A22 C3                  <1> 	retn
  3196                              <1> 
  3197                              <1> csftdf_df_check_directory:
  3198 00008A23 BE[09DB0000]        <1> 	mov	esi, DestinationFile_Directory
  3199 00008A28 803E20              <1>         cmp     byte [esi], 20h
  3200 00008A2B 760F                <1> 	jna	short csftdf_find_df
  3201                              <1> 
  3202                              <1> csftdf_df_change_directory:
  3203 00008A2D FE05[C6BD0000]      <1> 	inc	byte [Restore_CDIR]
  3204 00008A33 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  3205 00008A35 E86BEDFFFF          <1> 	call	change_current_directory
  3206 00008A3A 72E6                <1> 	jc	short csftdf_df_error_retn
  3207                              <1> 
  3208                              <1> ;csftdf_df_change_prompt_dir_string:
  3209                              <1> ;	call	change_prompt_dir_string
  3210                              <1> 
  3211                              <1> csftdf_find_df:
  3212                              <1> 	; 23/03/2016
  3213 00008A3C 29DB                <1> 	sub	ebx, ebx
  3214 00008A3E 8A3D[08DB0000]      <1> 	mov	bh,  [DestinationFile_Drv]
  3215 00008A44 81C300010900        <1> 	add	ebx, Logical_DOSDisks
  3216 00008A4A 891D[E0DB0000]      <1> 	mov	[csftdf_df_drv_dt], ebx
  3217                              <1> 
  3218 00008A50 BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  3219 00008A55 6631C0              <1> 	xor	ax, ax 
  3220                              <1> 		; DestinationFile_AttributesMask -> any/zero
  3221 00008A58 E85CD1FFFF          <1> 	call	find_first_file
  3222 00008A5D 7218                <1> 	jc	short csftdf_df_check_error_code
  3223                              <1> 
  3224                              <1> csftdf_df_ambgfn_check:
  3225 00008A5F 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3226 00008A62 7511                <1> 	jnz	short csftdf_df_error_stc_retn
  3227                              <1> 	
  3228                              <1> csftdf_df_found:
  3229 00008A64 C605[B2DB0000]01    <1> 	mov	byte [DestinationFileFound], 1
  3230 00008A6B 80E11F              <1> 	and	cl, 1Fh ; Attributes, D-V-S-H-R
  3231 00008A6E 7451                <1> 	jz	short csftdf_df_save_first_cluster
  3232                              <1> 
  3233                              <1> csftdf_df_permission_denied_retn:	 
  3234 00008A70 B805000000          <1> 	mov	eax, 05h ; Access/Permisson denied.
  3235                              <1> csftdf_df_error_stc_retn:
  3236 00008A75 F9                  <1> 	stc
  3237 00008A76 C3                  <1> 	retn
  3238                              <1> 
  3239                              <1> csftdf_df_check_error_code:
  3240                              <1> 	;cmp	eax, 2
  3241 00008A77 3C02                <1> 	cmp	al, 2
  3242 00008A79 75FA                <1> 	jne	short csftdf_df_error_stc_retn
  3243                              <1> 
  3244                              <1> 	; 21/03/2016
  3245                              <1> 	; (Capitalized file name)
  3246 00008A7B BE[88D90000]        <1> 	mov	esi, FindFile_Name
  3247 00008A80 BF[4ADB0000]        <1> 	mov	edi, DestinationFile_Name
  3248 00008A85 A5                  <1> 	movsd
  3249 00008A86 A5                  <1> 	movsd	
  3250 00008A87 A5                  <1> 	movsd
  3251                              <1> 	;movsb
  3252                              <1> 
  3253 00008A88 C605[B2DB0000]00    <1> 	mov	byte [DestinationFileFound], 0
  3254                              <1> 
  3255                              <1> csftdf_check_disk_free_size_0:
  3256 00008A8F A1[F6DA0000]        <1> 	mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3257                              <1> 
  3258                              <1> csftdf_check_disk_free_size_1:
  3259                              <1> 	;sub	ebx, ebx
  3260                              <1> 	;mov 	esi, Logical_DOSDisks
  3261                              <1> 	;mov	bh,  [DestinationFile_Drv]
  3262                              <1> 	;add	esi, ebx
  3263                              <1> 	
  3264 00008A94 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3265                              <1> 
  3266 00008A9A 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3267 00008A9E 01C8                <1> 	add	eax, ecx
  3268 00008AA0 48                  <1> 	dec	eax  ; file size (additional bytes) + 511 (round up)
  3269                              <1> csftdf_check_disk_free_size_3: ; 16/03/2016
  3270 00008AA1 29D2                <1> 	sub	edx, edx
  3271 00008AA3 F7F1                <1> 	div	ecx ; bytes per sector
  3272                              <1> 
  3273                              <1> csftdf_check_disk_free_size:
  3274 00008AA5 3B4674              <1> 	cmp	eax, [esi+LD_FreeSectors]
  3275 00008AA8 0F8294000000        <1>         jb      csftdf_check_disk_free_size_ok
  3276 00008AAE 770A                <1> 	ja	short csftdf_df_insufficient_disk_space
  3277                              <1> 
  3278 00008AB0 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0 ; FS needs FDT sector also.
  3279 00008AB4 0F8788000000        <1>         ja      csftdf_check_disk_free_size_ok 
  3280                              <1> 
  3281                              <1> csftdf_df_insufficient_disk_space:
  3282 00008ABA B827000000          <1> 	mov	eax, 27h ; insufficient disk space
  3283 00008ABF EBB4                <1> 	jmp	short csftdf_df_error_stc_retn
  3284                              <1> 
  3285                              <1> csftdf_df_save_first_cluster:
  3286                              <1> 	; ESI = FindFile_DirEntry (for the old destination file)
  3287                              <1> 	; EAX = Old destination file size
  3288                              <1> 	; 24/03/2016
  3289                              <1> 	; EDI = Directory entry address (within Dir Buffer boundaries)
  3290 00008AC1 81EF00000800        <1> 	sub	edi, Directory_Buffer  ; (<65536)
  3291 00008AC7 66C1EF05            <1> 	shr	di, 5 ; Convert entry offset to entry index/number
  3292 00008ACB 66893D[82DB0000]    <1> 	mov	[DestinationFile_DirEntryNumber], di ; (<2048)
  3293                              <1> 
  3294                              <1> csftdf_df_check_sf_df_fcluster:
  3295 00008AD2 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  3296 00008AD6 C1E210              <1> 	shl	edx, 16
  3297 00008AD9 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  3298 00008ADD 8915[C4DB0000]      <1> 	mov	[csftdf_df_cluster], edx
  3299                              <1> csftdf_df_check_sf_df_fcluster_1:
  3300 00008AE3 668B15[EEDA0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3301 00008AEA C1E210              <1> 	shl	edx, 16
  3302 00008AED 668B15[F4DA0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3303 00008AF4 3B15[C4DB0000]      <1> 	cmp	edx, [csftdf_df_cluster]
  3304 00008AFA 7512                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3305                              <1> csftdf_df_check_sf_df_drv:
  3306 00008AFC 8A15[88DA0000]      <1> 	mov	dl, [SourceFile_Drv]
  3307 00008B02 3A15[08DB0000]      <1> 	cmp	dl, [DestinationFile_Drv]
  3308 00008B08 7504                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3309                              <1> 
  3310                              <1> 	; source and destination files are same !
  3311                              <1> 	; (they have same first cluster value on same logical disk)
  3312                              <1> 
  3313 00008B0A 31C0                <1> 	xor	eax, eax ; mov eax, 0 -> Bad command or file name !
  3314 00008B0C F9                  <1> 	stc
  3315 00008B0D C3                  <1> 	retn 
  3316                              <1>    
  3317                              <1> csftdf_df_check_sf_df_fcluster_ok:
  3318                              <1> csftdf_df_move_findfile_struct:
  3319                              <1> 	; mov	esi, FindFile_DirEntry
  3320 00008B0E BF[5ADB0000]        <1> 	mov	edi, DestinationFile_DirEntry
  3321 00008B13 B908000000          <1> 	mov	ecx, 8
  3322 00008B18 F3A5                <1> 	rep	movsd
  3323                              <1> 	
  3324                              <1> csftdf_check_disk_free_size_2:
  3325 00008B1A 89C2                <1> 	mov	edx, eax ; Old destination file size
  3326                              <1> 
  3327                              <1> 	;mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3328 00008B1C A1[B4DB0000]        <1> 	mov	eax, [csftdf_filesize] ; 23/03/2016
  3329                              <1> 
  3330                              <1> 	;;sub	ecx, ecx ; 0
  3331                              <1> 	;mov 	esi, Logical_DOSDisks
  3332                              <1> 	;mov	ch,  [DestinationFile_Drv]
  3333                              <1> 	;add	esi, ecx
  3334                              <1> 	;
  3335                              <1> 	;mov	[csftdf_df_drv_dt], esi
  3336                              <1> 
  3337 00008B21 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3338                              <1> 
  3339 00008B27 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3340 00008B2B 01CA                <1> 	add	edx, ecx ; + 512
  3341 00008B2D 01C8                <1> 	add	eax, ecx ; + 512
  3342 00008B2F 4A                  <1> 	dec	edx ; old file size + 511 (round up)
  3343 00008B30 48                  <1> 	dec	eax ; new file size + 511 (round up)
  3344 00008B31 F7D9                <1> 	neg	ecx ; -512 ; 0FFFFFE00h
  3345 00008B33 21CA                <1> 	and	edx, ecx ; = old sector count * 512 
  3346 00008B35 21C8                <1> 	and	eax, ecx ; = new sector count * 512 
  3347                              <1> 
  3348 00008B37 29D0                <1> 	sub	eax, edx ; new file size - old file size (on disk)
  3349 00008B39 7607                <1> 	jna	short csftdf_check_disk_free_size_ok
  3350                              <1> 
  3351 00008B3B F7D9                <1> 	neg	ecx ; 512 (bytes per sector) ; 200h
  3352                              <1> 	; check free space for additional sectors
  3353                              <1> 	; eax = number of additional sectors * bytes per sector
  3354                              <1> 	; esi = Logical DOS drive number (of destination disk)
  3355 00008B3D E95FFFFFFF          <1>         jmp     csftdf_check_disk_free_size_3
  3356                              <1>  
  3357                              <1> csftdf_check_disk_free_size_ok:
  3358                              <1> 	; 18/03/2016
  3359                              <1> csftdf_df_check_copy_cmd_phase:
  3360 00008B42 A0[B0DB0000]        <1> 	mov	al, [copy_cmd_phase]
  3361 00008B47 3C01                <1> 	cmp	al, 1
  3362 00008B49 7514                <1> 	jne	short csftdf2_check_cdrv
  3363                              <1> 	
  3364 00008B4B 31C0                <1> 	xor	eax, eax
  3365 00008B4D A2[B0DB0000]        <1> 	mov	[copy_cmd_phase], al ; 0
  3366                              <1> 
  3367 00008B52 8A15[B2DB0000]      <1> 	mov	dl, [DestinationFileFound]            
  3368 00008B58 8A35[E5DA0000]      <1> 	mov	dh, [SourceFile_DirEntry+11] ; Attributes
  3369                              <1>  
  3370                              <1> csftdf_return:	
  3371 00008B5E C3                  <1> 	retn
  3372                              <1> 
  3373                              <1> ; Phase 2
  3374                              <1> 
  3375                              <1> csftdf2_check_cdrv:
  3376                              <1> 	; 18/03/2016
  3377                              <1> 	; Here, destination drive and directory are ready !
  3378                              <1> 	; (checking/restoring is not needed)
  3379                              <1> 	; (Since at the end of the phase 1)
  3380                              <1> 
  3381                              <1> ;	mov	dl, [DestinationFile_Drv]
  3382                              <1> ;	cmp	dl, [Current_Drv]
  3383                              <1> ;	je	short csftdf2_df_check_directory
  3384                              <1> ;
  3385                              <1> ;	call	change_current_drive
  3386                              <1> ;	jc	short csftdf2_read_error
  3387                              <1> ;
  3388                              <1> ;csftdf2_df_check_directory:
  3389                              <1> ;	mov	esi, DestinationFile_Directory  
  3390                              <1> ;	cmp	byte [esi], 20h
  3391                              <1> ;	jna	short csftdf2_df_check_found_or_not
  3392                              <1> ;
  3393                              <1> ;csftdf2_df_change_directory:
  3394                              <1> ;	inc	byte [Restore_CDIR]
  3395                              <1> ;	xor	ah, ah ; CD_COMMAND sign -> 0 
  3396                              <1> ;	call	change_current_directory
  3397                              <1> ;	jc	short csftdf2_stc_return
  3398                              <1> ;
  3399                              <1> ;;csftdf2_df_change_prompt_dir_string:
  3400                              <1> ;;	call	change_prompt_dir_string
  3401                              <1> 
  3402                              <1> csftdf2_df_check_found_or_not:
  3403                              <1> 	; 21/03/2016
  3404 00008B5F 803D[B2DB0000]00    <1> 	cmp	byte [DestinationFileFound], 0 
  3405 00008B66 7739                <1> 	ja	short csftdf2_set_sf_percentage
  3406                              <1> 
  3407                              <1> csftdf2_create_file:
  3408 00008B68 BE[4ADB0000]        <1> 	mov	esi, DestinationFile_Name
  3409 00008B6D A1[B4DB0000]        <1> 	mov	eax, [csftdf_filesize]
  3410 00008B72 30C9                <1> 	xor	cl, cl ; 0
  3411                              <1> 
  3412 00008B74 31DB                <1> 	xor	ebx, ebx ; 0
  3413 00008B76 4B                  <1> 	dec	ebx ; 0FFFFFFFFh 
  3414                              <1> 
  3415                              <1> 	; INPUT ->
  3416                              <1> 	; 	EAX -> File Size
  3417                              <1> 	; 	ESI = ASCIIZ File name
  3418                              <1> 	;	 CL = File attributes
  3419                              <1> 	;	EBX = FFFFFFFFh -> empty file sign for FAT fs
  3420                              <1> 	;	EBX <> FFFFFFFFh -> use file size for FAT fs 
  3421                              <1> 	;
  3422                              <1> 	; OUTPUT ->
  3423                              <1> 	;	EAX = New file's first cluster
  3424                              <1> 	;	ESI = Logical Dos Drv Descr. Table Addr.
  3425                              <1> 	;	EBX = CreateFile_Size address
  3426                              <1> 	;	ECX = Sectors per cluster (<256)
  3427                              <1> 	;	EDX = Directory Entry Index/Number (<65536)
  3428                              <1> 	;		
  3429                              <1> 	;	cf = 1 -> error code in AL (EAX)
  3430                              <1> 
  3431 00008B77 E8EC050000          <1> 	call	create_file
  3432                              <1> 	;pop	esi
  3433 00008B7C 0F82A3050000        <1>         jc      csftdf2_rw_error
  3434                              <1> 
  3435                              <1> csftdf2_create_file_OK:
  3436 00008B82 A3[C4DB0000]        <1> 	mov	[csftdf_df_cluster], eax
  3437                              <1> 	
  3438                              <1> 	; 24/03/2016
  3439 00008B87 668915[82DB0000]    <1> 	mov	[DestinationFile_DirEntryNumber], dx 
  3440                              <1> 
  3441                              <1> 	; 21/03/2016
  3442 00008B8E BE00000800          <1> 	mov	esi, Directory_Buffer
  3443 00008B93 C1E205              <1> 	shl	edx, 5 ; 32 * index number
  3444 00008B96 01D6                <1> 	add	esi, edx
  3445 00008B98 BF[5ADB0000]        <1> 	mov	edi, DestinationFile_DirEntry	
  3446 00008B9D B108                <1> 	mov	cl, 8 ; 32 bytes
  3447 00008B9F F3A5                <1> 	rep	movsd
  3448                              <1> 
  3449                              <1> csftdf2_set_sf_percentage:
  3450                              <1> 	; 17/03/2016
  3451 00008BA1 31C0                <1> 	xor	eax, eax	
  3452 00008BA3 A2[D8DB0000]        <1> 	mov 	[csftdf_percentage], al ; 0, reset
  3453                              <1> 
  3454 00008BA8 A3[D0DB0000]        <1> 	mov	[csftdf_sf_rbytes], eax ; 0, reset
  3455 00008BAD A3[D4DB0000]        <1> 	mov	[csftdf_df_wbytes], eax ; 0, reset
  3456                              <1> 
  3457 00008BB2 8A25[88DA0000]      <1> 	mov	ah, [SourceFile_Drv]	
  3458 00008BB8 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3459 00008BBD 01C6                <1> 	add	esi, eax
  3460                              <1> 	
  3461 00008BBF 8935[DCDB0000]      <1> 	mov	[csftdf_sf_drv_dt], esi ; 23/03/2016
  3462                              <1> 
  3463 00008BC5 668B15[EEDA0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3464 00008BCC C1E210              <1> 	shl	edx, 16
  3465 00008BCF 668B15[F4DA0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3466 00008BD6 8915[C0DB0000]      <1> 	mov	[csftdf_sf_cluster], edx
  3467                              <1> 
  3468                              <1> 	; 16/03/2016
  3469                              <1> 	; Note: Singlix FS boot sector parameters (for cluster
  3470                              <1> 	;	related calculations) has same offset
  3471                              <1> 	;	values from LD_BPB as in FAT file system.
  3472                              <1> 	;	[esi+LD_BPB+SecPerClust] is 1 for Singlix FS.
  3473                              <1> 	;	
  3474 00008BDC 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  3475 00008BE0 880D[06DB0000]      <1> 	mov	[SourceFile_SecPerClust], cl
  3476                              <1> 
  3477                              <1> 	; 17/03/2016
  3478 00008BE6 386E03              <1> 	cmp	[esi+LD_FATType], ch ; 0
  3479 00008BE9 7707                <1> 	ja	short csftdf2_set_sf_percent_rsize1
  3480                              <1> 
  3481 00008BEB B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3482 00008BF0 EB06                <1> 	jmp	short csftdf2_set_sf_percent_rsize2	
  3483                              <1>  
  3484                              <1> csftdf2_set_sf_percent_rsize1:
  3485 00008BF2 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  3486 00008BF6 F7E1                <1> 	mul	ecx
  3487                              <1> 	;sub	edx, edx
  3488                              <1> csftdf2_set_sf_percent_rsize2:
  3489 00008BF8 A3[C8DB0000]        <1> 	mov	[csftdf_r_size], eax
  3490                              <1> 
  3491                              <1> csftdf2_set_df_percentage:
  3492                              <1> 	;sub	eax, eax
  3493                              <1> 	;mov	ah, [DestinationFile_Drv]	
  3494                              <1> 	;mov	edi, Logical_DOSDisks
  3495                              <1> 	;add	edi, eax
  3496                              <1> 	;mov	[csftdf_df_drv_dt], edi ; 17/03/2016
  3497                              <1> 
  3498 00008BFD 8B3D[E0DB0000]      <1> 	mov	edi, [csftdf_df_drv_dt] ; 23/03/2016
  3499                              <1> 
  3500                              <1> 	; 16/03/2016
  3501                              <1> 	; Note: Singlix FS boot sector parameters (for cluster
  3502                              <1> 	;	related calculations) has same offset
  3503                              <1> 	;	values from LD_BPB as in FAT file system.
  3504                              <1> 	;	[edi+LD_BPB+SecPerClust] is 1 for Singlix FS.
  3505                              <1> 	;	
  3506                              <1> 	;movzx	ecx, byte [edi+LD_BPB+SecPerClust]
  3507 00008C03 8A4F13              <1> 	mov	cl, [edi+LD_BPB+SecPerClust]
  3508 00008C06 880D[86DB0000]      <1> 	mov	[DestinationFile_SecPerClust], cl
  3509                              <1> 
  3510                              <1> 	; 17/03/2016
  3511 00008C0C 386F03              <1> 	cmp	[edi+LD_FATType], ch ; 0
  3512 00008C0F 7707                <1> 	ja	short csftdf2_set_df_percent_wsize1
  3513                              <1> 	
  3514 00008C11 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3515 00008C16 EB06                <1> 	jmp	short csftdf2_set_df_percent_wsize2	
  3516                              <1> 
  3517                              <1> csftdf2_set_df_percent_wsize1:
  3518 00008C18 0FB74711            <1> 	movzx	eax, word [edi+LD_BPB+BytesPerSec]
  3519 00008C1C F7E1                <1> 	mul	ecx
  3520                              <1> 	;sub	edx, edx
  3521                              <1> csftdf2_set_df_percent_wsize2:
  3522 00008C1E A3[CCDB0000]        <1> 	mov	[csftdf_w_size], eax
  3523                              <1> 
  3524 00008C23 A1[B4DB0000]        <1> 	mov	eax, [csftdf_filesize]
  3525                              <1> 
  3526 00008C28 3D00000100          <1> 	cmp	eax, 65536 ; 64KB	; small file
  3527 00008C2D 721F                <1> 	jb	short csftdf2_load_file ; do not display percentage
  3528                              <1> 	
  3529                              <1> csftdf2_reset_wf_percent_ptr_chk_64k:
  3530 00008C2F B201                <1> 	mov	dl, 1 ; 25/03/2016
  3531                              <1> 
  3532 00008C31 3D00000400          <1> 	cmp	eax, 65536*4 ; 256KB
  3533 00008C36 7310                <1> 	jnb	short csftdf2_enable_percentage_display ; big file
  3534                              <1> 
  3535                              <1> 	; 64-128KB file size for floppy disks
  3536 00008C38 3815[88DA0000]      <1> 	cmp	byte [SourceFile_Drv], dl ; 1 ; read from floppy disk ?
  3537 00008C3E 7608                <1> 	jna	short csftdf2_enable_percentage_display
  3538                              <1> 
  3539 00008C40 3815[08DB0000]      <1> 	cmp	byte [DestinationFile_Drv], dl ; 1 ; write to floppy disk ?
  3540 00008C46 7706                <1> 	ja	short csftdf2_load_file
  3541                              <1> 
  3542                              <1> csftdf2_enable_percentage_display:	
  3543 00008C48 8815[D8DB0000]      <1> 	mov	[csftdf_percentage], dl ; 1	
  3544                              <1> 	
  3545                              <1> csftdf2_load_file:
  3546                              <1> 	; 19/03/2016
  3547                              <1> 	; 18/03/2016
  3548                              <1> 	; 17/03/2016
  3549 00008C4E B40F                <1> 	mov	ah, 0Fh
  3550 00008C50 E8FB87FFFF          <1> 	call	int10h
  3551 00008C55 881D[D9DB0000]      <1> 	mov	[csftdf_videopage], bl ; active video page
  3552 00008C5B B403                <1> 	mov	ah, 03h
  3553 00008C5D E8EE87FFFF          <1> 	call	int10h
  3554 00008C62 668915[DADB0000]    <1> 	mov	[csftdf_cursorpos], dx
  3555                              <1> 
  3556 00008C69 29C0                <1> 	sub	eax, eax
  3557 00008C6B A2[B1DB0000]        <1> 	mov	[csftdf_rw_err], al ; 0 
  3558                              <1> 
  3559                              <1> ; ///
  3560                              <1> csftdf_sf_amb: ; 15/03/2016
  3561 00008C70 8B0D[B4DB0000]      <1> 	mov	ecx, [csftdf_filesize]	; 23/03/2016
  3562                              <1> 
  3563                              <1> 	; TRDOS 386 (TRDOS v2.0)
  3564                              <1> 	; Allocate contiguous memory block for loading the file
  3565                              <1> 	
  3566                              <1> 	;mov	ecx, [SourceFile_DirEntry+DirEntry_FileSize]
  3567                              <1> 	
  3568                              <1> 	;sub	eax, eax ; First free memory aperture
  3569                              <1> 	
  3570                              <1> 	; eax = 0 (Allocate memory from the beginning)
  3571                              <1> 	; ecx = File (Allocation) size in bytes
  3572                              <1> 	
  3573 00008C76 E880ACFFFF          <1> 	call	allocate_memory_block
  3574 00008C7B 7304                <1> 	jnc	short loc_check_sf_save_loading_parms
  3575                              <1> 
  3576 00008C7D 29C0                <1> 	sub	eax, eax
  3577 00008C7F 29C9                <1> 	sub	ecx, ecx
  3578                              <1> 	
  3579                              <1> loc_check_sf_save_loading_parms:
  3580 00008C81 A3[B8DB0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  3581 00008C86 890D[BCDB0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  3582                              <1> ; ///   
  3583                              <1> 	; 19/03/2016
  3584 00008C8C 8B35[DCDB0000]      <1> 	mov	esi, [csftdf_sf_drv_dt] ; logical dos drv desc. tbl.
  3585                              <1> 
  3586                              <1> 	; 17/03/2016
  3587 00008C92 09C0                <1> 	or	eax, eax ; contiguous free memory block address 
  3588 00008C94 0F845B010000        <1>         jz      csftdf2_read_sf_cluster
  3589                              <1> 
  3590                              <1> 	; 18/03/2016
  3591 00008C9A 8B1D[B8DB0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3592                              <1> 
  3593 00008CA0 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3594 00008CA4 0F8605020000        <1>         jna     csftdf2_load_fs_file
  3595                              <1> 
  3596                              <1> csftdf2_load_fat_file:
  3597 00008CAA 53                  <1> 	push	ebx ; *
  3598                              <1> 
  3599                              <1> csftdf2_load_fat_file_next:
  3600 00008CAB BE[1BC40000]        <1> 	mov	esi, msg_reading
  3601 00008CB0 E86AB2FFFF          <1> 	call	print_msg
  3602                              <1> 
  3603 00008CB5 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3604 00008CBC 7605                <1> 	jna	short csftdf2_load_fat_file_1
  3605                              <1> 	
  3606 00008CBE E87C000000          <1> 	call	csftdf2_print_percentage ; 19/03/2016
  3607                              <1> 
  3608                              <1> csftdf2_load_fat_file_1:
  3609 00008CC3 8B35[DCDB0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3610 00008CC9 5B                  <1> 	pop	ebx ; *
  3611                              <1> 
  3612                              <1> csftdf2_load_fat_file_2:
  3613 00008CCA E8B8000000          <1> 	call	csftdf2_read_fat_file_sectors ; 19/03/2016
  3614 00008CCF 0F8250040000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3615                              <1> 
  3616 00008CD5 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3617 00008CD7 7520                <1> 	jnz	short csftdf2_load_fat_file_ok
  3618                              <1> 
  3619 00008CD9 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3620 00008CE0 76E8                <1> 	jna	short csftdf2_load_fat_file_2
  3621                              <1> 
  3622 00008CE2 53                  <1> 	push	ebx ; *	
  3623                              <1> 
  3624                              <1> 	; Set cursor position
  3625                              <1> 	; AH= 02h, BL= Page Number, DH= Row, DL= Column
  3626 00008CE3 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  3627 00008CE9 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3628 00008CF0 B402                <1> 	mov	ah, 2
  3629 00008CF2 E85987FFFF          <1> 	call	int10h
  3630 00008CF7 EBB2                <1> 	jmp	short csftdf2_load_fat_file_next
  3631                              <1> 	
  3632                              <1> csftdf2_load_fat_file_ok:
  3633 00008CF9 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3634 00008D00 0F8651020000        <1>         jna     csftdf2_save_file ; 25/03/2016
  3635                              <1> 	
  3636                              <1> 	; "Reading... 100%"
  3637 00008D06 BF[33C40000]        <1> 	mov	edi, percentagestr
  3638 00008D0B B031                <1> 	mov	al, '1'
  3639 00008D0D AA                  <1> 	stosb
  3640 00008D0E B030                <1> 	mov	al, '0'
  3641 00008D10 AA                  <1> 	stosb
  3642 00008D11 AA                  <1> 	stosb
  3643                              <1> 
  3644 00008D12 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  3645 00008D18 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3646 00008D1F B402                <1> 	mov	ah, 2
  3647 00008D21 E82A87FFFF          <1> 	call	int10h
  3648                              <1> 
  3649 00008D26 BE[1BC40000]        <1> 	mov	esi, msg_reading
  3650 00008D2B E8EFB1FFFF          <1> 	call	print_msg
  3651                              <1> 	
  3652 00008D30 BE[33C40000]        <1> 	mov	esi, percentagestr
  3653 00008D35 E8E5B1FFFF          <1> 	call	print_msg
  3654                              <1> 
  3655 00008D3A E918020000          <1>         jmp     csftdf2_save_file ; 25/03/2016
  3656                              <1> 
  3657                              <1> csftdf2_print_percentage:
  3658                              <1> 	; 19/03/2016
  3659                              <1> 	; 18/03/2016
  3660 00008D3F B020                <1> 	mov	al, 20h
  3661 00008D41 BF[33C40000]        <1> 	mov	edi, percentagestr
  3662 00008D46 AA                  <1> 	stosb
  3663 00008D47 AA                  <1> 	stosb
  3664 00008D48 A1[D0DB0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3665 00008D4D BA64000000          <1> 	mov	edx, 100
  3666 00008D52 F7E2                <1> 	mul	edx
  3667 00008D54 8B0D[B4DB0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3668 00008D5A F7F1                <1> 	div	ecx
  3669 00008D5C B10A                <1> 	mov	cl, 10
  3670 00008D5E F6F1                <1> 	div	cl
  3671 00008D60 80C430              <1> 	add	ah, '0'
  3672 00008D63 8827                <1> 	mov	[edi], ah
  3673 00008D65 20C0                <1> 	and	al, al
  3674 00008D67 740A                <1> 	jz	short csftdf2_print_percent_1
  3675 00008D69 4F                  <1> 	dec	edi
  3676 00008D6A 6698                <1> 	cbw
  3677 00008D6C F6F1                <1> 	div	cl
  3678 00008D6E 80C430              <1> 	add	ah, '0'
  3679 00008D71 8827                <1> 	mov	[edi], ah
  3680                              <1> 	;and	al, al
  3681                              <1> 	;jz	short csftdf2_print_percent_1
  3682                              <1> 	;dec	edi
  3683                              <1> 	;mov	[edi], '1' ; 100%		
  3684                              <1> 
  3685                              <1> csftdf2_print_percent_1:
  3686 00008D73 BE[33C40000]        <1> 	mov	esi, percentagestr
  3687                              <1> 	;call	print_msg
  3688                              <1> 	;retn
  3689 00008D78 E9A2B1FFFF          <1> 	jmp	print_msg
  3690                              <1> 
  3691                              <1> csftdf2_read_file_sectors:
  3692                              <1> 	; 19/03/2016
  3693 00008D7D 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3694 00008D81 0F8627070000        <1>         jna     csftdf2_read_fs_file_sectors
  3695                              <1> 
  3696                              <1> csftdf2_read_fat_file_sectors:
  3697                              <1> 	; 19/03/2016
  3698                              <1> 	; 18/03/2016
  3699                              <1> 	; return:
  3700                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3701                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3702                              <1> 	;   CF = 1 -> read error (error code in AL)	
  3703                              <1> 
  3704                              <1> csftdf2_read_fat_file_secs_0:
  3705 00008D87 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  3706 00008D8D 2B15[D0DB0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  3707 00008D93 3B15[C8DB0000]      <1> 	cmp	edx, [csftdf_r_size]	
  3708 00008D99 7306                <1> 	jnb	short csftdf2_read_fat_file_secs_1
  3709 00008D9B 8915[C8DB0000]      <1> 	mov	[csftdf_r_size], edx
  3710                              <1> 		
  3711                              <1> csftdf2_read_fat_file_secs_1:
  3712 00008DA1 A1[C8DB0000]        <1> 	mov	eax, [csftdf_r_size]
  3713 00008DA6 29D2                <1> 	sub	edx, edx
  3714 00008DA8 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3715 00008DAC 01C8                <1> 	add	eax, ecx
  3716 00008DAE 48                  <1> 	dec	eax
  3717 00008DAF F7F1                <1> 	div	ecx
  3718 00008DB1 89C1                <1> 	mov	ecx, eax ; sector count
  3719 00008DB3 A1[C0DB0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3720                              <1> 
  3721                              <1> 	; EBX = memory block address (current)
  3722                              <1> 	
  3723 00008DB8 E821090000          <1> 	call	read_fat_file_sectors
  3724 00008DBD 7235                <1> 	jc	short csftdf2_read_fat_file_secs_3
  3725                              <1> 
  3726                              <1> 	; EBX = next memory address
  3727                              <1> 
  3728 00008DBF A1[D0DB0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3729 00008DC4 0305[C8DB0000]      <1> 	add	eax, [csftdf_r_size]
  3730 00008DCA 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  3731 00008DD0 39D0                <1> 	cmp	eax, edx
  3732 00008DD2 7320                <1> 	jnb	short csftdf2_read_fat_file_secs_3 ; edx > 0
  3733 00008DD4 A3[D0DB0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  3734                              <1> 
  3735 00008DD9 53                  <1> 	push	ebx ; *
  3736                              <1> 	; get next cluster (csftdf_r_size! bytes)
  3737 00008DDA A1[C0DB0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3738 00008DDF E8CC060000          <1> 	call	get_next_cluster
  3739 00008DE4 5B                  <1> 	pop	ebx ; *
  3740 00008DE5 7306                <1> 	jnc	short csftdf2_read_fat_file_secs_2
  3741                              <1> 
  3742 00008DE7 B815000000          <1> 	mov	eax, 15h ; Read error !
  3743 00008DEC C3                  <1> 	retn
  3744                              <1> 
  3745                              <1> csftdf2_read_fat_file_secs_2:
  3746 00008DED 29D2                <1> 	sub	edx, edx ; 0
  3747 00008DEF A3[C0DB0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  3748                              <1> 
  3749                              <1> csftdf2_read_fat_file_secs_3:
  3750 00008DF4 C3                  <1> 	retn
  3751                              <1> 
  3752                              <1> csftdf2_read_sf_cluster:
  3753                              <1> 	; 19/03/2016
  3754 00008DF5 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3755                              <1> 
  3756 00008DFA 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3757 00008E01 760D                <1> 	jna	short csftdf2_read_sf_clust_2
  3758                              <1> 
  3759 00008E03 53                  <1> 	push	ebx ; *	
  3760                              <1> 
  3761                              <1> csftdf2_read_sf_clust_next:
  3762 00008E04 E836FFFFFF          <1> 	call	csftdf2_print_percentage
  3763                              <1> 
  3764                              <1> csftdf2_read_sf_clust_0:
  3765 00008E09 8B35[DCDB0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3766                              <1> csftdf2_read_sf_clust_1:
  3767 00008E0F 5B                  <1> 	pop	ebx ; *
  3768                              <1> 
  3769                              <1> csftdf2_read_sf_clust_2:
  3770 00008E10 89DA                <1> 	mov	edx, ebx
  3771 00008E12 0315[C8DB0000]      <1> 	add	edx, [csftdf_r_size]
  3772 00008E18 81FA00000800        <1> 	cmp	edx, Cluster_Buffer + 65536
  3773 00008E1E 772F                <1> 	ja	short csftdf2_write_df_cluster
  3774                              <1> 
  3775 00008E20 E858FFFFFF          <1> 	call	csftdf2_read_file_sectors ; 19/03/2016
  3776 00008E25 0F8280020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3777                              <1> 
  3778 00008E2B 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3779 00008E2D 7520                <1> 	jnz	short csftdf2_write_df_cluster
  3780                              <1> 
  3781 00008E2F 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3782 00008E36 76D8                <1> 	jna	short csftdf2_read_sf_clust_2
  3783                              <1> 
  3784 00008E38 53                  <1> 	push	ebx ; *	
  3785                              <1> 
  3786                              <1> 	; Set cursor position
  3787                              <1> 	; AH= 02h, BL= Page Number, DH= Row, DL= Column
  3788 00008E39 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  3789 00008E3F 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3790 00008E46 B402                <1> 	mov	ah, 2
  3791 00008E48 E80386FFFF          <1> 	call	int10h
  3792 00008E4D EBB5                <1> 	jmp	short csftdf2_read_sf_clust_next
  3793                              <1> 
  3794                              <1> csftdf2_write_df_cluster:
  3795                              <1> 	; 19/03/2016
  3796 00008E4F 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt]	
  3797 00008E55 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3798                              <1> 
  3799                              <1> csftdf2_write_df_clust_next:
  3800 00008E5A E855000000          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016
  3801 00008E5F 0F8246020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3802                              <1> 
  3803 00008E65 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3804 00008E67 750A                <1> 	jnz	short csftdf2_rw_f_clust_ok
  3805                              <1> 
  3806 00008E69 81FB00000800        <1> 	cmp	ebx, Cluster_Buffer + 65536
  3807 00008E6F 72E9                <1> 	jb	short csftdf2_write_df_clust_next
  3808                              <1> 	
  3809 00008E71 EB82                <1> 	jmp	short csftdf2_read_sf_cluster
  3810                              <1>  
  3811                              <1> csftdf2_rw_f_clust_ok:
  3812 00008E73 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3813 00008E7A 0F86B2010000        <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  3814                              <1> 
  3815                              <1> 	; "100%"
  3816 00008E80 BF[33C40000]        <1> 	mov	edi, percentagestr
  3817 00008E85 B031                <1> 	mov	al, '1'
  3818 00008E87 AA                  <1> 	stosb
  3819 00008E88 B030                <1> 	mov	al, '0'
  3820 00008E8A AA                  <1> 	stosb
  3821 00008E8B AA                  <1> 	stosb
  3822                              <1> 
  3823 00008E8C 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  3824 00008E92 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3825 00008E99 B402                <1> 	mov	ah, 2
  3826 00008E9B E8B085FFFF          <1> 	call	int10h
  3827                              <1> 
  3828 00008EA0 BE[33C40000]        <1> 	mov	esi, percentagestr
  3829 00008EA5 E875B0FFFF          <1> 	call	print_msg
  3830                              <1> 
  3831 00008EAA E983010000          <1>         jmp     csftdf2_save_fat_file_4
  3832                              <1> 
  3833                              <1> csftdf2_load_fs_file:
  3834                              <1> 	; temporary - 18/03/2016
  3835 00008EAF E96F020000          <1>         jmp     csftdf2_read_error
  3836                              <1> 
  3837                              <1> csftdf2_write_file_sectors:
  3838                              <1> 	; 19/03/2016
  3839 00008EB4 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3840 00008EB8 0F86F1050000        <1>         jna     csftdf2_write_fs_file_sectors
  3841                              <1> 
  3842                              <1> csftdf2_write_fat_file_sectors:
  3843                              <1> 	; 19/03/2016
  3844                              <1> 	; 18/03/2016
  3845                              <1> 	; return:
  3846                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3847                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3848                              <1> 	;   CF = 1 -> write error (error code in AL)	
  3849                              <1> 
  3850                              <1> csftdf2_write_fat_file_secs_0:
  3851 00008EBE 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  3852 00008EC4 2B15[D4DB0000]      <1> 	sub	edx, [csftdf_df_wbytes]
  3853 00008ECA 3B15[CCDB0000]      <1> 	cmp	edx, [csftdf_w_size]	
  3854 00008ED0 7306                <1> 	jnb	short csftdf2_write_fat_file_secs_1
  3855 00008ED2 8915[CCDB0000]      <1> 	mov	[csftdf_w_size], edx		
  3856                              <1> 
  3857                              <1> csftdf2_write_fat_file_secs_1:
  3858 00008ED8 A1[CCDB0000]        <1> 	mov	eax, [csftdf_w_size]
  3859 00008EDD 29D2                <1> 	sub	edx, edx
  3860 00008EDF 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3861 00008EE3 01C8                <1> 	add	eax, ecx
  3862 00008EE5 48                  <1> 	dec	eax
  3863 00008EE6 F7F1                <1> 	div	ecx
  3864 00008EE8 89C1                <1> 	mov	ecx, eax ; sector count
  3865 00008EEA A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3866                              <1> 
  3867                              <1> 	; EBX = memory block address (current)	
  3868                              <1> 
  3869 00008EEF E8A10F0000          <1> 	call	write_fat_file_sectors
  3870 00008EF4 7259                <1> 	jc	short csftdf2_write_fat_file_secs_4
  3871                              <1> 
  3872                              <1> 	; EBX = next memory address
  3873                              <1> 
  3874 00008EF6 A1[D4DB0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3875 00008EFB 0305[CCDB0000]      <1> 	add	eax, [csftdf_w_size]
  3876 00008F01 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  3877 00008F07 39D0                <1> 	cmp	eax, edx
  3878 00008F09 7344                <1> 	jnb	short csftdf2_write_fat_file_secs_4
  3879 00008F0B A3[D4DB0000]        <1> 	mov	[csftdf_df_wbytes], eax
  3880                              <1> 	;
  3881 00008F10 A3[76DB0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  3882                              <1> 
  3883 00008F15 53                  <1> 	push	ebx ; *
  3884                              <1> 
  3885 00008F16 803D[B2DB0000]01    <1> 	cmp	byte [DestinationFileFound], 1
  3886 00008F1D 7210                <1> 	jb	short csftdf2_write_fat_file_secs_2
  3887                              <1> 
  3888                              <1> 	; get next cluster (csftdf_w_size! bytes)
  3889 00008F1F A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3890 00008F24 E887050000          <1> 	call	get_next_cluster
  3891 00008F29 731C                <1> 	jnc	short csftdf2_write_fat_file_secs_3
  3892                              <1> 
  3893 00008F2B 21C0                <1> 	and	eax, eax ; end of cluster chain!?
  3894 00008F2D 7521                <1> 	jnz	short csftdf2_write_fat_file_secs_5 ; disk error !
  3895                              <1> 
  3896                              <1> csftdf2_write_fat_file_secs_2:
  3897 00008F2F A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  3898 00008F34 E8700E0000          <1> 	call	add_new_cluster		
  3899 00008F39 7215                <1> 	jc	short csftdf2_write_fat_file_secs_5
  3900                              <1> 
  3901                              <1> 	; NOTE: Destination file size may be bigger than
  3902                              <1> 	; source file size when the last reading fails after here.
  3903                              <1> 	; (The last -empty- cluster of destination file must be 
  3904                              <1> 	; truncated and LMDT must be current date&time for partial
  3905                              <1> 	; copy result!) 
  3906 00008F3B 8B15[CCDB0000]      <1> 	mov	edx, [csftdf_w_size] ; bytes per cluster
  3907 00008F41 0115[76DB0000]      <1> 	add	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  3908                              <1> 
  3909                              <1> csftdf2_write_fat_file_secs_3:
  3910 00008F47 5B                  <1> 	pop	ebx ; *
  3911 00008F48 29D2                <1> 	sub	edx, edx ; 0
  3912 00008F4A A3[C4DB0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  3913                              <1> 
  3914                              <1> csftdf2_write_fat_file_secs_4:
  3915 00008F4F C3                  <1> 	retn
  3916                              <1> 
  3917                              <1> csftdf2_write_fat_file_secs_5:
  3918 00008F50 5B                  <1> 	pop	ebx ; *
  3919 00008F51 B81D000000          <1> 	mov	eax, 1Dh ; Write error !
  3920 00008F56 C3                  <1> 	retn
  3921                              <1> 
  3922                              <1> csftdf2_save_file:
  3923                              <1> 	; 25/03/2016
  3924                              <1> 	; 19/03/2016
  3925                              <1> 	; 18/03/2016
  3926 00008F57 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; logical dos drv desc. tbl.
  3927                              <1> 
  3928 00008F5D 8B1D[B8DB0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3929                              <1> 
  3930 00008F63 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3931 00008F67 0F86F4010000        <1>         jna     csftdf2_save_fs_file
  3932                              <1> 
  3933                              <1> csftdf2_save_fat_file:
  3934 00008F6D 53                  <1> 	push	ebx; *
  3935                              <1> 
  3936 00008F6E 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3937 00008F75 7724                <1> 	ja	short csftdf2_save_fat_file_0
  3938                              <1> 
  3939                              <1> 	; Set cursor position
  3940                              <1> 	; AH= 02h, BL= Page Number, DH= Row, DL= Column
  3941 00008F77 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  3942 00008F7D 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3943 00008F84 B402                <1> 	mov	ah, 2
  3944 00008F86 E8C584FFFF          <1> 	call	int10h
  3945                              <1> 	
  3946 00008F8B BE[27C40000]        <1> 	mov	esi, msg_writing
  3947 00008F90 E88AAFFFFF          <1> 	call	print_msg
  3948                              <1> 
  3949                              <1> csftdf2_save_fat_file_next:
  3950 00008F95 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 25/03/2016
  3951                              <1> 
  3952                              <1> csftdf2_save_fat_file_0:
  3953 00008F9B 5B                  <1> 	pop	ebx ; *
  3954                              <1> 
  3955                              <1> csftdf2_save_fat_file_1:
  3956 00008F9C E813FFFFFF          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016	
  3957 00008FA1 0F827E010000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3958                              <1> 
  3959 00008FA7 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3960 00008FA9 756D                <1>         jnz     short csftdf2_save_fat_file_3 ; 25/03/2016
  3961                              <1> 
  3962 00008FAB 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3963 00008FB2 76E8                <1> 	jna	short csftdf2_save_fat_file_1
  3964                              <1> 
  3965 00008FB4 B020                <1> 	mov	al, 20h
  3966 00008FB6 BF[33C40000]        <1> 	mov	edi, percentagestr
  3967 00008FBB AA                  <1> 	stosb
  3968 00008FBC AA                  <1> 	stosb
  3969 00008FBD A1[D4DB0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3970 00008FC2 BA64000000          <1> 	mov	edx, 100
  3971 00008FC7 F7E2                <1> 	mul	edx
  3972 00008FC9 8B0D[B4DB0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3973 00008FCF F7F1                <1> 	div	ecx
  3974 00008FD1 B10A                <1> 	mov	cl, 10
  3975 00008FD3 F6F1                <1> 	div	cl
  3976 00008FD5 80C430              <1> 	add	ah, '0'
  3977 00008FD8 8827                <1> 	mov	[edi], ah
  3978 00008FDA 20C0                <1> 	and	al, al
  3979 00008FDC 740A                <1> 	jz	short csftdf2_save_fat_file_2
  3980 00008FDE 4F                  <1> 	dec	edi
  3981 00008FDF 6698                <1> 	cbw
  3982 00008FE1 F6F1                <1> 	div	cl
  3983 00008FE3 80C430              <1> 	add	ah, '0'
  3984 00008FE6 8827                <1> 	mov	[edi], ah
  3985                              <1> 	;and	al, al
  3986                              <1> 	;jz	short csftdf2_save_fat_file_2
  3987                              <1> 	;dec	edi
  3988                              <1> 	;mov	[edi], '1' ; 100%		
  3989                              <1> 
  3990                              <1> csftdf2_save_fat_file_2:
  3991 00008FE8 53                  <1> 	push	ebx ; *
  3992                              <1> 
  3993 00008FE9 E802000000          <1> 	call	csftdf2_print_wr_percentage ; 25/03/2016
  3994                              <1> 
  3995 00008FEE EBA5                <1>         jmp     csftdf2_save_fat_file_next
  3996                              <1> 
  3997                              <1> csftdf2_print_wr_percentage:
  3998                              <1> 	; Set cursor position
  3999                              <1> 	; AH= 02h, BL= Page Number, DH= Row, DL= Column
  4000 00008FF0 8A1D[D9DB0000]      <1> 	mov	bl, [csftdf_videopage]
  4001 00008FF6 668B15[DADB0000]    <1> 	mov	dx, [csftdf_cursorpos]
  4002 00008FFD B402                <1> 	mov	ah, 2
  4003 00008FFF E84C84FFFF          <1> 	call	int10h
  4004                              <1> 
  4005 00009004 BE[27C40000]        <1> 	mov	esi, msg_writing
  4006 00009009 E811AFFFFF          <1> 	call	print_msg
  4007                              <1> 
  4008 0000900E BE[33C40000]        <1> 	mov	esi, percentagestr
  4009                              <1> 	;call	print_msg
  4010                              <1> 	;retn
  4011 00009013 E907AFFFFF          <1> 	jmp	print_msg
  4012                              <1> 
  4013                              <1> csftdf2_save_fat_file_3:
  4014 00009018 803D[D8DB0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  4015 0000901F 7611                <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  4016                              <1> 
  4017                              <1> 	; "100%"
  4018 00009021 BF[33C40000]        <1> 	mov	edi, percentagestr
  4019 00009026 B031                <1> 	mov	al, '1'
  4020 00009028 AA                  <1> 	stosb
  4021 00009029 B030                <1> 	mov	al, '0'
  4022 0000902B AA                  <1> 	stosb
  4023 0000902C AA                  <1> 	stosb
  4024                              <1> 
  4025 0000902D E8BEFFFFFF          <1> 	call	csftdf2_print_wr_percentage
  4026                              <1> 
  4027                              <1> csftdf2_save_fat_file_4:
  4028 00009032 803D[B2DB0000]00    <1> 	cmp	byte [DestinationFileFound], 0
  4029 00009039 7647                <1> 	jna	short csftdf2_save_fat_file_6
  4030                              <1> 
  4031 0000903B 8B35[E0DB0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 31/03/2016	
  4032                              <1> 
  4033 00009041 A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4034 00009046 E865040000          <1> 	call	get_next_cluster
  4035 0000904B 7235                <1> 	jc	short csftdf2_save_fat_file_6 ; eocc! or disk error!
  4036                              <1> 
  4037 0000904D A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4038                              <1> 	;xor	ecx, ecx
  4039                              <1> 	;mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  4040                              <1> 	;dec	ecx ; 0FFFFFFFFh
  4041                              <1> 	;shr	ecx, 4 ; 28 bit ; 0FFFFFFFh
  4042 00009052 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4043 00009057 E87E070000          <1> 	call	update_cluster
  4044 0000905C 7224                <1> 	jc	short csftdf2_save_fat_file_6 ; really last cluster!?
  4045                              <1> 
  4046 0000905E A3[C4DB0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  4047                              <1> 	
  4048                              <1> 	; byte [FAT_BuffValidData] = 2 
  4049 00009063 E82F0A0000          <1> 	call	save_fat_buffer
  4050 00009068 730E                <1> 	jnc	short csftdf2_save_fat_file_5
  4051                              <1> 	
  4052 0000906A 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  4053 00009070 8915[76DB0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4054 00009076 EB58                <1> 	jmp	short csftdf2_save_fat_file_err3
  4055                              <1> 
  4056                              <1> csftdf2_save_fat_file_5:
  4057 00009078 A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster]
  4058                              <1> 
  4059                              <1> 	; EAX = First cluster to be truncated/unlinked
  4060                              <1> 	; ESI = Logical dos drive description table address
  4061 0000907D E8480C0000          <1> 	call	truncate_cluster_chain
  4062                              <1> 
  4063                              <1> csftdf2_save_fat_file_6:
  4064                              <1> 	; 28/03/2016
  4065 00009082 BE[E5DA0000]        <1> 	mov	esi, SourceFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4066 00009087 BF[65DB0000]        <1> 	mov	edi, DestinationFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4067 0000908C A4                  <1> 	movsb ; +11
  4068 0000908D A5                  <1> 	movsd ; +12 .. +15
  4069 0000908E 66A5                <1> 	movsw ; +16 .. +17
  4070                              <1> 		; + 18
  4071 00009090 83C604              <1> 	add	esi, 4
  4072 00009093 83C704              <1> 	add	edi, 4
  4073 00009096 A5                  <1> 	movsd	; DirEntry_WrtTime ; +22 .. +25
  4074                              <1> 
  4075 00009097 8B15[B4DB0000]      <1> 	mov	edx, [csftdf_filesize]
  4076 0000909D 8915[76DB0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4077                              <1> 
  4078 000090A3 E8D7F0FFFF          <1> 	call	convert_current_date_time
  4079                              <1> 	; DX = Date in dos dir entry format
  4080                              <1> 	; AX = Time in dos dir entry format
  4081 000090A8 EB4D                <1> 	jmp	short csftdf2_save_fat_file_7
  4082                              <1> 
  4083                              <1> csftdf2_save_fat_file_err1:
  4084 000090AA 5B                  <1> 	pop	ebx ; *	
  4085                              <1> csftdf2_save_fat_file_err2:
  4086 000090AB A1[D4DB0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  4087 000090B0 8B15[76DB0000]      <1> 	mov	edx, [DestinationFile_DirEntry+DirEntry_FileSize]
  4088 000090B6 39C2                <1> 	cmp	edx, eax
  4089 000090B8 7616                <1> 	jna	short csftdf2_save_fat_file_err3
  4090 000090BA A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last (empty) cluster
  4091                              <1> 	; ESI = Logical dos drive description table address
  4092 000090BF E8060C0000          <1> 	call	truncate_cluster_chain
  4093 000090C4 720A                <1> 	jc	short csftdf2_save_fat_file_err3
  4094 000090C6 A1[D4DB0000]        <1> 	mov	eax, [csftdf_df_wbytes]	
  4095 000090CB A3[76DB0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  4096                              <1> csftdf2_save_fat_file_err3:
  4097 000090D0 E8AAF0FFFF          <1> 	call	convert_current_date_time
  4098                              <1> 	; DX = Date in dos dir entry format
  4099                              <1> 	; AX = Time in dos dir entry format
  4100 000090D5 C605[67DB0000]00    <1> 	mov	byte [DestinationFile_DirEntry+DirEntry_CrtTimeTenth], 0
  4101 000090DC 66A3[68DB0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtTime], ax
  4102 000090E2 668915[6ADB0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtDate], dx		
  4103 000090E9 66A3[70DB0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtTime], ax
  4104 000090EF 668915[72DB0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtDate], dx
  4105 000090F6 F9                  <1> 	stc
  4106                              <1> csftdf2_save_fat_file_7:
  4107 000090F7 9C                  <1> 	pushf
  4108 000090F8 668915[6CDB0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_LastAccDate], dx
  4109 000090FF BE[5ADB0000]        <1> 	mov	esi, DestinationFile_DirEntry
  4110 00009104 BF00000800          <1> 	mov	edi, Directory_Buffer
  4111 00009109 0FB70D[82DB0000]    <1> 	movzx	ecx, word [DestinationFile_DirEntryNumber] ; (<2048)
  4112 00009110 66C1E105            <1> 	shl	cx, 5 ; 32 * directory entry number
  4113 00009114 01CF                <1> 	add	edi, ecx
  4114                              <1> 	;mov	ecx, 8
  4115 00009116 66B90800            <1> 	mov	cx, 8
  4116 0000911A F3A5                <1> 	rep	movsd
  4117 0000911C 9D                  <1> 	popf
  4118 0000911D 730B                <1> 	jnc	short csftdf2_write_file_OK
  4119                              <1> 	 		
  4120                              <1> csftdf2_write_error:
  4121                              <1> 	; 18/03/2016
  4122 0000911F B01D                <1> 	mov	al, 1Dh ; write error
  4123 00009121 EB02                <1> 	jmp	short csftdf2_rw_error
  4124                              <1> 
  4125                              <1> 	; 16/03/2016
  4126                              <1> csftdf2_read_error:
  4127 00009123 B015                <1> 	mov	al, 15h ; ; Drive not ready or read error!
  4128                              <1> csftdf2_rw_error:
  4129 00009125 A2[B1DB0000]        <1> 	mov	[csftdf_rw_err], al 
  4130                              <1> 
  4131                              <1> csftdf2_write_file_OK:
  4132                              <1> 	; 18/03/2016
  4133 0000912A C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  4134 00009131 E8E7F0FFFF          <1> 	call	save_directory_buffer
  4135                              <1> 
  4136                              <1>  	; Update last modification date&time of destination
  4137                              <1> 	; file's (parent) directory
  4138 00009136 E87DF1FFFF          <1> 	call	update_parent_dir_lmdt
  4139                              <1> 	;
  4140 0000913B A1[B8DB0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  4141                              <1> 
  4142 00009140 21C0                <1> 	and	eax, eax
  4143 00009142 750E                <1> 	jnz	short csftdf2_dealloc_mblock
  4144                              <1> 
  4145 00009144 88C5                <1> 	mov	ch, al ; 0 (Cluster r/w, not full loading)
  4146                              <1> csftdf2_dealloc_retn:
  4147 00009146 8A0D[B1DB0000]      <1> 	mov	cl, [csftdf_rw_err]
  4148 0000914C A1[C4DB0000]        <1> 	mov	eax, [csftdf_df_cluster]
  4149 00009151 C3                  <1> 	retn
  4150                              <1> 
  4151                              <1> csftdf2_dealloc_mblock:
  4152 00009152 8B0D[BCDB0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  4153 00009158 E89FA9FFFF          <1> 	call	deallocate_memory_block
  4154 0000915D B5FF                <1>         mov     ch, 0FFh ; (File was full loaded at memory)
  4155 0000915F EBE5                <1> 	jmp	short csftdf2_dealloc_retn
  4156                              <1> 
  4157                              <1> csftdf2_save_fs_file:
  4158                              <1> 	; temporary - (21/03/2016)
  4159 00009161 B81D000000          <1> 	mov	eax, 1Dh ; write error
  4160 00009166 F9                  <1> 	stc
  4161 00009167 C3                  <1> 	retn
  4162                              <1> 
  4163                              <1> create_file:
  4164                              <1> 	; 31/03/2016
  4165                              <1> 	; 24/03/2016
  4166                              <1> 	; 23/03/2016
  4167                              <1> 	; 21/03/2016
  4168                              <1> 	; 20/03/2016
  4169                              <1> 	; 19/03/2016 (TRDOS 396 = TRDOS v2.0)
  4170                              <1> 	; 03/09/2011 (FILE.ASM, 'proc_create_file')
  4171                              <1> 	; 09/08/2010
  4172                              <1> 	;
  4173                              <1> 	; INPUT ->
  4174                              <1> 	; 	EAX = File Size
  4175                              <1> 	; 	ESI = ASCIIZ File Name
  4176                              <1> 	; 	CL = File Attributes 
  4177                              <1> 	;	EBX = FFFFFFFFh -> create empty file 
  4178                              <1> 	;			 (only for FAT fs) 
  4179                              <1> 	; OUTPUT ->
  4180                              <1> 	;     CF = 0 ->
  4181                              <1> 	;	EAX = New file's first cluster
  4182                              <1> 	; 	ESI = Logical Dos Drv Descr. Table Addr.
  4183                              <1> 	; 	EBX = offset CreateFile_Size
  4184                              <1> 	; 	ECX = Sectors per cluster (<256) 
  4185                              <1> 	; 	EDX = Directory entry index/number (<65536)
  4186                              <1> 	;     CF = 1 -> error code in AL
  4187                              <1> 
  4188                              <1> ;	test	cl, 18h (directory or volume name)
  4189                              <1> ;	jnz	short loc_createfile_access_denied
  4190 00009168 80E107              <1> 	and	cl, 07h ; S, H, R
  4191 0000916B 880D[00DC0000]      <1>         mov     [createfile_attrib], cl 
  4192                              <1> 
  4193 00009171 89D9                <1> 	mov	ecx, ebx
  4194 00009173 89F3                <1> 	mov	ebx, esi ; ASCIIZ File Name address
  4195 00009175 29D2                <1> 	sub	edx, edx
  4196 00009177 8A35[A2CF0000]      <1>         mov     dh, [Current_Drv]
  4197 0000917D BE00010900          <1>         mov     esi, Logical_DOSDisks
  4198 00009182 01D6                <1> 	add	esi, edx
  4199                              <1> 
  4200 00009184 8815[0BDC0000]      <1> 	mov	[createfile_UpdatePDir], dl ; 0 ; 31/03/2016 
  4201                              <1> 
  4202                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  4203 0000918A 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  4204 0000918E 730A                <1> 	jnb	short loc_createfile_check_file_sytem
  4205 00009190 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  4206 00009195 66BA0000            <1> 	mov	dx, 0
  4207                              <1> 	; err retn: EDX = 0, EBX = File name offset
  4208                              <1> 	; ESI -> Dos drive description table address	
  4209 00009199 C3                  <1> 	retn
  4210                              <1> 
  4211                              <1> ;loc_createfile_access_denied:
  4212                              <1> ;	mov	eax, 05h ; access denied (invalid attributes input)
  4213                              <1> ;	stc
  4214                              <1> ;	retn
  4215                              <1> 
  4216                              <1> loc_createfile_check_file_sytem:
  4217 0000919A 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  4218 0000919E 730A                <1> 	jnb	short loc_createfile_chk_empty_FAT_file_sign1
  4219                              <1> 
  4220 000091A0 A3[ECDB0000]        <1> 	mov	[createfile_size], eax
  4221                              <1> 	; ESI = Logical Dos Drive Description Table address
  4222                              <1> 	; EBX = ASCIIZ File Name address
  4223 000091A5 E9FE020000          <1> 	jmp	create_fs_file
  4224                              <1> 
  4225                              <1> loc_createfile_chk_empty_FAT_file_sign1:
  4226                              <1> 	; ECX = FFFFFFFFh -> create empty file if drive has FAT fs
  4227 000091AA 41                  <1> 	inc	ecx
  4228 000091AB 7506                <1> 	jnz	short loc_createfile_chk_empty_FAT_file_sign2
  4229 000091AD 890D[ECDB0000]      <1> 	mov	[createfile_size], ecx ; 0 ; empty file
  4230                              <1> 
  4231                              <1> loc_createfile_chk_empty_FAT_file_sign2:
  4232                              <1> 	; 23/03/2016
  4233 000091B3 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec]
  4234 000091B7 66890D[08DC0000]    <1> 	mov	[createfile_BytesPerSec], cx
  4235                              <1> 	
  4236                              <1> 	; EBX = ASCIIZ File Name address
  4237 000091BE 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  4238 000091C2 8815[01DC0000]      <1> 	mov	[createfile_SecPerClust], dl
  4239 000091C8 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  4240 000091CB 39D1                <1> 	cmp	ecx, edx ; byte [createfile_SecPerClust]
  4241 000091CD 7306                <1> 	jnb	short loc_create_fat_file
  4242                              <1> 	  
  4243                              <1> loc_createfile_insufficient_disk_space:
  4244 000091CF B827000000          <1> 	mov	eax, 27h
  4245                              <1> loc_createfile_gffc_retn:
  4246 000091D4 C3                  <1> 	retn
  4247                              <1> 
  4248                              <1> loc_create_fat_file:
  4249 000091D5 891D[E4DB0000]      <1> 	mov	[createfile_Name_Offset], ebx
  4250 000091DB 890D[E8DB0000]      <1> 	mov	[createfile_FreeSectors], ecx
  4251                              <1> 
  4252                              <1> loc_createfile_gffc_1:
  4253 000091E1 E821050000          <1> 	call	get_first_free_cluster
  4254 000091E6 72EC                <1> 	jc	short loc_createfile_gffc_retn
  4255                              <1> 
  4256 000091E8 A3[F0DB0000]        <1> 	mov	[createfile_FFCluster], eax
  4257                              <1> 
  4258                              <1> loc_createfile_locate_ffe_on_directory:
  4259                              <1> 	; Current directory fcluster <> Directory buffer cluster
  4260                              <1> 	; Current directory will be reloaded by
  4261                              <1> 	; 'locate_current_dir_file' procedure
  4262                              <1> 	;
  4263                              <1> 	; ESI = Logical Dos Drv Desc. Table Adress
  4264 000091ED 56                  <1> 	push	esi ; *
  4265 000091EE 31C0                <1> 	xor	eax, eax
  4266                              <1> 
  4267 000091F0 A3[C1D70000]        <1> 	mov	dword [FAT_ClusterCounter], eax ; 0
  4268                              <1> 	; 21/03/2016
  4269 000091F5 A2[0ADC0000]        <1> 	mov	byte [createfile_wfc], al ; 0 
  4270                              <1> 
  4271 000091FA 89C1                <1>  	mov	ecx, eax
  4272 000091FC 6649                <1> 	dec	cx ; FFFFh  
  4273                              <1> 	; CX = FFFFh -> find first deleted or free entry
  4274                              <1> 	; ESI would be ASCIIZ filename Address if the call
  4275                              <1> 	; would not be for first free or deleted dir entry  
  4276 000091FE E8F6E7FFFF          <1> 	call	locate_current_dir_file
  4277 00009203 0F83EE000000        <1> 	jnc	loc_createfile_set_ff_dir_entry
  4278 00009209 5E                  <1> 	pop	esi ; *
  4279                              <1> 	 ; ESI = Logical DOS Drv. Description Table Address 
  4280 0000920A 83F802              <1> 	cmp	eax, 2
  4281 0000920D 7402                <1> 	je	short loc_createfile_add_new_cluster
  4282                              <1> loc_createfile_locate_file_stc_retn:
  4283 0000920F F9                  <1> 	stc
  4284 00009210 C3                  <1> 	retn
  4285                              <1> 
  4286                              <1> loc_createfile_add_new_cluster:
  4287 00009211 803D[A1CF0000]02    <1> 	cmp	byte [Current_FATType], 2
  4288                              <1> 	;cmp	byte [esi+LD_FATType], 2
  4289 00009218 770C                <1> 	ja	short loc_createfile_add_new_cluster_check_fsc
  4290 0000921A 803D[A0CF0000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  4291                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  4292 00009221 7303                <1> 	jnb	short loc_createfile_add_new_cluster_check_fsc
  4293                              <1> 	
  4294                              <1> 	;mov	eax, 12
  4295 00009223 B00C                <1> 	mov	al, 12 ; No more files 
  4296                              <1> 
  4297                              <1> loc_createfile_anc_retn:
  4298 00009225 C3                  <1> 	retn
  4299                              <1> 
  4300                              <1> loc_createfile_add_new_cluster_check_fsc:
  4301 00009226 8B0D[E8DB0000]      <1> 	mov	ecx, [createfile_FreeSectors]
  4302 0000922C 0FB605[01DC0000]    <1> 	movzx	eax, byte [createfile_SecPerClust]
  4303 00009233 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  4304 00009236 39C1                <1> 	cmp	ecx, eax
  4305 00009238 7295                <1>         jb	short loc_createfile_insufficient_disk_space
  4306                              <1> 
  4307                              <1> loc_createfile_add_new_subdir_cluster:
  4308 0000923A 8B15[D1D70000]      <1> 	mov	edx, [DirBuff_Cluster]
  4309 00009240 8915[F4DB0000]      <1> 	mov	[createfile_LastDirCluster], edx	
  4310                              <1> 
  4311 00009246 A1[F0DB0000]        <1> 	mov	eax, [createfile_FFCluster]
  4312 0000924B E846040000          <1> 	call	load_FAT_sub_directory 
  4313 00009250 72D3                <1> 	jc	short loc_createfile_anc_retn
  4314                              <1> 
  4315                              <1> pass_createfile_add_new_subdir_cluster:
  4316                              <1> 	;movzx	eax, word [esi+LD_BPB+BytesPerSec]
  4317 00009252 0FB705[08DC0000]    <1> 	movzx	eax, word [createfile_BytesPerSec] ; 23/03/2016
  4318 00009259 F7E1                <1> 	mul	ecx ; ecx = directory buffer sector count
  4319 0000925B 89C1                <1> 	mov	ecx, eax
  4320 0000925D C1E902              <1> 	shr	ecx, 2 ; dword count
  4321 00009260 29C0                <1> 	sub	eax, eax ; 0
  4322 00009262 F3AB                <1> 	rep	stosd 
  4323                              <1> 	;
  4324 00009264 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4325 0000926B E8ADEFFFFF          <1> 	call	save_directory_buffer
  4326 00009270 72B3                <1> 	jc	short loc_createfile_anc_retn
  4327                              <1> 
  4328                              <1> loc_createfile_save_added_subdir_cluster:
  4329 00009272 A1[F4DB0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4330 00009277 8B0D[F0DB0000]      <1> 	mov	ecx, [createfile_FFCluster]
  4331 0000927D E858050000          <1> 	call	update_cluster
  4332 00009282 7304                <1> 	jnc	short loc_createfile_save_fat_buffer_0
  4333 00009284 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4334 00009286 751A                <1> 	jnz	short loc_createfile_save_fat_buffer_stc_retn
  4335                              <1> 
  4336                              <1> loc_createfile_save_fat_buffer_0:
  4337 00009288 A1[F0DB0000]        <1> 	mov	eax, [createfile_FFCluster]
  4338 0000928D A3[F4DB0000]        <1> 	mov	[createfile_LastDirCluster], eax
  4339 00009292 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh ; 28 bit
  4340 00009297 E83E050000          <1> 	call	update_cluster
  4341 0000929C 7306                <1> 	jnc	short loc_createfile_save_fat_buffer_1
  4342 0000929E 09C0                <1> 	or	eax, eax ; Was it free cluster
  4343 000092A0 7402                <1> 	jz	short loc_createfile_save_fat_buffer_1
  4344                              <1> 
  4345                              <1> loc_createfile_save_fat_buffer_stc_retn:
  4346 000092A2 F9                  <1> 	stc
  4347                              <1> loc_createfile_save_fat_buffer_retn:
  4348                              <1> loc_createfile_gffc_2_stc_retn:
  4349 000092A3 C3                  <1> 	retn
  4350                              <1> 
  4351                              <1> loc_createfile_save_fat_buffer_1:
  4352                              <1> 	; byte [FAT_BuffValidData] = 2 
  4353 000092A4 E8EE070000          <1> 	call	save_fat_buffer
  4354 000092A9 72F8                <1> 	jc	short loc_createfile_save_fat_buffer_retn
  4355                              <1> 
  4356 000092AB 803D[C1D70000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4357 000092B2 7222                <1> 	jb	short loc_createfile_save_fat_buffer_2
  4358                              <1> 
  4359                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4360 000092B4 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4361                              <1> 
  4362 000092B9 C605[C1D70000]00    <1> 	mov	byte [FAT_ClusterCounter], 0 ; 21/03/2016
  4363                              <1> 
  4364 000092C0 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4365 000092C4 E863080000          <1> 	call	calculate_fat_freespace
  4366                              <1> 
  4367                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4368                              <1> 	;jnz	short loc_createfile_save_fat_buffer_2
  4369                              <1> 
  4370                              <1> 	; ecx > 0 -> Recalculation is needed
  4371 000092C9 09C9                <1> 	or	ecx, ecx 
  4372 000092CB 7409                <1> 	jz	short loc_createfile_save_fat_buffer_2
  4373                              <1> 
  4374 000092CD 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4375 000092D1 E856080000          <1> 	call	calculate_fat_freespace
  4376                              <1> 
  4377                              <1> loc_createfile_save_fat_buffer_2:
  4378                              <1> 	;call	update_parent_dir_lmdt
  4379                              <1> 
  4380                              <1> loc_createfile_gffc_2:
  4381 000092D6 E82C040000          <1> 	call	get_first_free_cluster
  4382 000092DB 72C6                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4383                              <1> 
  4384 000092DD A3[F0DB0000]        <1> 	mov	[createfile_FFCluster], eax
  4385                              <1> 
  4386 000092E2 A1[F4DB0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4387                              <1> 	
  4388 000092E7 E8AA030000          <1> 	call	load_FAT_sub_directory 
  4389 000092EC 72B5                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4390                              <1> 
  4391 000092EE BF00000800          <1> 	mov	edi, Directory_Buffer
  4392                              <1> 
  4393 000092F3 6629DB              <1> 	sub	bx, bx ; directory entry index/number = 0
  4394                              <1> 
  4395 000092F6 56                  <1> 	push	esi ; * ; 23/03/2016
  4396                              <1> 
  4397                              <1> loc_createfile_set_ff_dir_entry:
  4398 000092F7 66891D[02DC0000]    <1> 	mov	[createfile_DirIndex], bx
  4399                              <1> 
  4400                              <1>         ; EDI = Directory entry address
  4401 000092FE 8B35[E4DB0000]      <1> 	mov	esi, [createfile_Name_Offset]
  4402 00009304 A1[F0DB0000]        <1> 	mov	eax, [createfile_FFCluster]
  4403 00009309 A3[F8DB0000]        <1> 	mov	[createfile_Cluster], eax ; 24/03/2016
  4404 0000930E B5FF                <1> 	mov	ch, 0FFh
  4405 00009310 8A0D[00DC0000]      <1>         mov	cl, [createfile_attrib] ; file attributes
  4406                              <1> 	; CH > 0 -> File size is in EBX
  4407 00009316 BB[ECDB0000]        <1> 	mov	ebx, createfile_size
  4408                              <1>   
  4409 0000931B E820EEFFFF          <1> 	call	make_directory_entry
  4410                              <1> 	
  4411 00009320 5E                  <1> 	pop	esi ; * ; ESI = Logical Dos Drv Desc. Table address
  4412                              <1> 
  4413 00009321 C605[CCD70000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4414 00009328 E8F0EEFFFF          <1> 	call	save_directory_buffer
  4415 0000932D 7221                <1> 	jc	short loc_createfile_set_ff_dir_entry_retn
  4416                              <1> 
  4417 0000932F C605[0BDC0000]01    <1> 	mov	byte [createfile_UpdatePDir], 1 ; 31/03/2016 
  4418                              <1> 
  4419                              <1> loc_createfile_get_set_write_file_cluster:
  4420 00009336 A1[ECDB0000]        <1> 	mov	eax, [createfile_size]
  4421 0000933B 09C0                <1> 	or	eax, eax
  4422 0000933D 7570                <1> 	jnz	short loc_createfile_get_set_wfc_cont
  4423 0000933F 40                  <1> 	inc	eax
  4424                              <1> 	; 23/03/2016
  4425 00009340 0FB61D[01DC0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4426                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512
  4427 00009347 0FB70D[08DC0000]    <1>         movzx   ecx, word [createfile_BytesPerSec] ; 512
  4428 0000934E EB7C                <1> 	jmp	loc_createfile_set_cluster_count 
  4429                              <1> 
  4430                              <1> loc_createfile_set_ff_dir_entry_retn:
  4431 00009350 C3                  <1> 	retn
  4432                              <1> 
  4433                              <1> loc_createfile_write_fcluster_to_disk:
  4434 00009351 034668              <1> 	add	eax, [esi+LD_DATABegin] ; convert to physical address
  4435 00009354 BB00000700          <1> 	mov	ebx, Cluster_Buffer
  4436                              <1> 	; ESI = Logical DOS Drv. Desc. Tbl. address
  4437                              <1> 	; EAX = Disk address
  4438                              <1> 	; EBX = Sector Buffer
  4439                              <1> 	; ECX = sectors per cluster
  4440 00009359 E81E270000          <1> 	call	disk_write
  4441 0000935E 7211                <1> 	jc	short loc_createfile_dsk_wr_err
  4442                              <1> 
  4443                              <1> loc_createfile_update_fat_cluster:
  4444                              <1> 	; 21/03/2016	
  4445 00009360 803D[0ADC0000]00    <1> 	cmp	byte [createfile_wfc], 0 
  4446 00009367 7712                <1> 	ja	short loc_createfile_update_fat_cluster_n1
  4447                              <1> 
  4448 00009369 FE05[0ADC0000]      <1> 	inc	byte [createfile_wfc] ; 1
  4449 0000936F EB24                <1> 	jmp	short loc_createfile_update_fat_cluster_n2
  4450                              <1> 
  4451                              <1> loc_createfile_dsk_wr_err:
  4452                              <1> 	; 23/03/2016
  4453 00009371 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  4454 00009376 E9BD000000          <1> 	jmp	loc_createfile_stc_retn
  4455                              <1> 
  4456                              <1> loc_createfile_update_fat_cluster_n1:
  4457 0000937B A1[FCDB0000]        <1> 	mov	eax, [createfile_PCluster]
  4458 00009380 8B0D[F8DB0000]      <1> 	mov	ecx, [createfile_Cluster]
  4459 00009386 E84F040000          <1> 	call	update_cluster
  4460 0000938B 7308                <1> 	jnc	short loc_createfile_update_fat_cluster_n2
  4461 0000938D 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4462 0000938F 0F85A3000000        <1> 	jnz	loc_createfile_stc_retn
  4463                              <1> 
  4464                              <1> loc_createfile_update_fat_cluster_n2:
  4465 00009395 A1[F8DB0000]        <1>         mov	eax, [createfile_Cluster]
  4466 0000939A B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4467 0000939F E836040000          <1> 	call	update_cluster
  4468 000093A4 734E                <1> 	jnc	short loc_createfile_save_fat_buffer_3
  4469 000093A6 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4470 000093A8 744A                <1> 	jz	short loc_createfile_save_fat_buffer_3
  4471                              <1> 
  4472                              <1> loc_createfile_upd_fat_fcluster_stc_retn:
  4473 000093AA E989000000          <1> 	jmp	loc_createfile_stc_retn
  4474                              <1> 
  4475                              <1> loc_createfile_get_set_wfc_cont:
  4476                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512	
  4477 000093AF 0FB70D[08DC0000]    <1> 	movzx	ecx, word [createfile_BytesPerSec] ; 512
  4478 000093B6 01C8                <1> 	add	eax, ecx
  4479 000093B8 48                  <1> 	dec	eax  ; add eax, 511
  4480 000093B9 29D2                <1> 	sub	edx, edx
  4481 000093BB F7F1                <1> 	div	ecx
  4482 000093BD 0FB61D[01DC0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4483 000093C4 01D8                <1> 	add	eax, ebx
  4484 000093C6 48                  <1> 	dec	eax  ; add eax, SecPerClust - 1
  4485 000093C7 6631D2              <1> 	xor	dx, dx
  4486 000093CA F7F3                <1> 	div	ebx
  4487                              <1> 
  4488                              <1> loc_createfile_set_cluster_count:
  4489 000093CC A3[04DC0000]        <1> 	mov 	[createfile_CCount], eax
  4490                              <1> 	
  4491 000093D1 BF00000700          <1> 	mov	edi, Cluster_Buffer
  4492 000093D6 89C8                <1> 	mov	eax, ecx ; Bytes per Sector
  4493 000093D8 F7E3                <1> 	mul	ebx ; Sectors per Cluster 
  4494                              <1> 	; EAX = Bytes per Cluster
  4495 000093DA 89C1                <1> 	mov	ecx, eax
  4496 000093DC C1E902              <1> 	shr	ecx, 2 ; dword count
  4497 000093DF 31C0                <1> 	xor	eax, eax
  4498 000093E1 F3AB                <1> 	rep	stosd ; clear cluster buffer
  4499                              <1> 
  4500 000093E3 A1[F8DB0000]        <1> 	mov	eax, [createfile_Cluster] ; 24/03/2016
  4501                              <1> 
  4502 000093E8 89D9                <1> 	mov	ecx, ebx
  4503                              <1> 
  4504                              <1> loc_createfile_get_set_wf_fclust_cont:
  4505 000093EA 83E802              <1> 	sub	eax, 2
  4506 000093ED F7E1                <1> 	mul	ecx
  4507                              <1> 	; EAX = Logical DOS disk address (offset)
  4508 000093EF E95DFFFFFF          <1>         jmp     loc_createfile_write_fcluster_to_disk
  4509                              <1> 
  4510                              <1> loc_createfile_save_fat_buffer_3:
  4511                              <1> 	; byte [FAT_BuffValidData] = 2
  4512 000093F4 E89E060000          <1> 	call	save_fat_buffer
  4513 000093F9 723D                <1> 	jc	loc_createfile_stc_retn
  4514                              <1> 
  4515                              <1> 	; 21/03/2016
  4516 000093FB 803D[C1D70000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4517 00009402 721B                <1> 	jb	short loc_createfile_save_fat_buffer_4
  4518                              <1> 
  4519                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4520 00009404 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4521 00009409 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4522 0000940D E81A070000          <1> 	call	calculate_fat_freespace
  4523                              <1> 
  4524                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4525                              <1> 	;jnz	short loc_createfile_save_fat_buffer_4
  4526                              <1> 
  4527                              <1> 	; ecx > 0 -> Recalculation is needed
  4528 00009412 09C9                <1> 	or	ecx, ecx 
  4529 00009414 7409                <1> 	jz	short loc_createfile_save_fat_buffer_4
  4530                              <1> 
  4531 00009416 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4532 0000941A E80D070000          <1> 	call	calculate_fat_freespace
  4533                              <1> 
  4534                              <1> loc_createfile_save_fat_buffer_4:
  4535 0000941F FF0D[04DC0000]      <1> 	dec	dword [createfile_CCount]
  4536                              <1> 	;jz	short loc_createfile_upd_dir_modif_date_time
  4537 00009425 743F                <1> 	jz	short loc_createfile_stc_retn_cc ; 31/03/2016
  4538                              <1> 
  4539                              <1> loc_createfile_get_set_write_next_cluster:
  4540 00009427 E8DB020000          <1> 	call	get_first_free_cluster
  4541 0000942C 720A                <1> 	jc	short loc_createfile_stc_retn
  4542                              <1> 
  4543                              <1> loc_createfile_get_set_write_next_cluster_1:
  4544 0000942E 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  4545 00009431 7213                <1> 	jb	short loc_createfile_get_set_write_next_cluster_2
  4546                              <1> 
  4547                              <1> loc_createfile_wnc_insufficient_disk_space:	
  4548 00009433 B827000000          <1> 	mov	eax, 27h ; Insufficient disk space
  4549                              <1> 
  4550                              <1> loc_createfile_stc_retn:
  4551 00009438 803D[0ADC0000]01    <1> 	cmp	byte [createfile_wfc], 1
  4552 0000943F 7324                <1> 	jnb	short loc_createfile_err_retn
  4553 00009441 C3                  <1> 	retn
  4554                              <1> 
  4555                              <1> loc_createfile_wnc_inv_format_retn:
  4556                              <1> 	;mov	eax, 0Bh
  4557 00009442 B00B                <1> 	mov	al, 0Bh ; Invalid format
  4558 00009444 EBF2                <1> 	jmp	short loc_createfile_stc_retn
  4559                              <1> 	         
  4560                              <1> loc_createfile_get_set_write_next_cluster_2:
  4561 00009446 83F802              <1> 	cmp	eax, 2
  4562 00009449 72F7                <1> 	jb	short loc_createfile_wnc_inv_format_retn
  4563                              <1> 
  4564                              <1> loc_createfile_get_set_write_next_cluster_3:
  4565 0000944B 8B0D[F8DB0000]      <1> 	mov	ecx, [createfile_Cluster]
  4566 00009451 A3[F8DB0000]        <1> 	mov	[createfile_Cluster], eax
  4567 00009456 890D[FCDB0000]      <1> 	mov	[createfile_PCluster], ecx
  4568 0000945C 0FB60D[01DC0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust]
  4569 00009463 EB85                <1> 	jmp	short loc_createfile_get_set_wf_fclust_cont
  4570                              <1> 
  4571                              <1> loc_createfile_err_retn:
  4572 00009465 F9                  <1> 	stc
  4573                              <1> 
  4574                              <1> ;loc_createfile_upd_dir_modif_date_time:
  4575                              <1> loc_createfile_stc_retn_cc: ; 31/03/2016
  4576 00009466 9C                  <1> 	pushf	; cpu is here for an error return or completion 
  4577 00009467 50                  <1> 	push	eax ; error code if cf = 1
  4578                              <1> 
  4579                              <1> 	;call	update_parent_dir_lmdt
  4580                              <1> 
  4581                              <1> ;loc_createfile_stc_retn_cc:
  4582 00009468 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4583 0000946D 09C0                <1> 	or	eax, eax
  4584 0000946F 741A                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4585 00009471 8A3D[A2CF0000]      <1> 	mov	bh, [Current_Drv]
  4586 00009477 B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  4587                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  4588                              <1> 	; (If EAX value is negative, Free Cluster Count will be decreased)
  4589 00009479 E8AE060000          <1>   	call	calculate_fat_freespace
  4590                              <1>         ; ESI = Logical DOS Drive Description Table Address 
  4591                              <1>         ;jc	short loc_createfile_stc_retn_pop_eax_cf
  4592 0000947E 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  4593 00009480 7409                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4594                              <1> 
  4595                              <1> loc_createfile_stc_retn_recalc_FAT_freespace:
  4596 00009482 66BB00FF            <1> 	mov	bx, 0FF00h ; bh = 0FFh -> 
  4597                              <1> 	; ESI = Logical DOS Drv DT Addr
  4598                              <1> 	; BL = 0 -> Recalculate 
  4599 00009486 E8A1060000          <1> 	call	calculate_fat_freespace
  4600                              <1> 
  4601                              <1> loc_createfile_stc_retn_pop_eax:
  4602 0000948B 58                  <1> 	pop	eax
  4603 0000948C 9D                  <1> 	popf
  4604 0000948D 7218                <1> 	jc	short loc_createfile_retn
  4605                              <1> 
  4606                              <1> loc_createfile_retn_fcluster:
  4607 0000948F A1[F0DB0000]        <1> 	mov	eax, [createfile_FFCluster]
  4608 00009494 BB[ECDB0000]        <1> 	mov	ebx, createfile_size
  4609                              <1> 	;movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  4610 00009499 0FB60D[01DC0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust] ; 23/03/2016
  4611 000094A0 0FB715[02DC0000]    <1> 	movzx	edx, word [createfile_DirIndex]
  4612                              <1> 
  4613                              <1> loc_createfile_retn:
  4614 000094A7 C3                  <1> 	retn
  4615                              <1> 
  4616                              <1> create_fs_file:
  4617                              <1> 	; temporary (21/03/2016)
  4618 000094A8 C3                  <1> 	retn
  4619                              <1> 
  4620                              <1> delete_fs_file:
  4621                              <1> 	; temporary (28/02/2016)
  4622 000094A9 C3                  <1> 	retn
  4623                              <1> 
  4624                              <1> rename_fs_file_or_directory:
  4625 000094AA C3                  <1> 	retn
  4626                              <1> 
  4627                              <1> make_fs_directory:
  4628                              <1> 	; temporary (21/02/2016)
  4629 000094AB C3                  <1> 	retn
  4630                              <1> 
  4631                              <1> add_new_fs_section:
  4632                              <1> 	; temporary (11/03/2016)
  4633 000094AC C3                  <1> 	retn
  4634                              <1> 
  4635                              <1> delete_fs_directory_entry:
  4636                              <1> 	; temporary (11/03/2016)
  4637 000094AD C3                  <1> 	retn
  4638                              <1> 
  4639                              <1> csftdf2_read_fs_file_sectors:
  4640                              <1> 	; temporary (19/03/2016)
  4641 000094AE C3                  <1> 	retn
  4642                              <1> 
  4643                              <1> csftdf2_write_fs_file_sectors:
  4644                              <1> 	; temporary (19/03/2016)
  4645 000094AF C3                  <1> 	retn
  1928                                  %include 'trdosk5.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - File System Procedures : trdosk5s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; DRV_FAT.ASM (21/08/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DRV_FAT.ASM (c) 2005-2011 Erdogan TAN [ 07/07/2009 ] Last Update: 21/08/2011
    14                              <1> 
    15                              <1> get_next_cluster:
    16                              <1> 	; 23/03/2016
    17                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
    18                              <1> 	; 05/07/2011
    19                              <1> 	; 07/07/2009
    20                              <1> 	; 2005
    21                              <1> 	; INPUT ->
    22                              <1> 	;	EAX = Cluster Number (32 bit)
    23                              <1> 	;	ESI = Logical DOS Drive Parameters Table
    24                              <1> 	; OUTPUT ->
    25                              <1> 	;	cf = 0 -> No Error, EAX valid
    26                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
    27                              <1> 	;	cf = 1 & EAX > 0 -> Error
    28                              <1> 	;	ECX = Current/Previous cluster (if CF = 0)
    29                              <1> 	;	EAX = Next Cluster Number (32 bit)
    30                              <1> 	;
    31                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
    32                              <1> 
    33 000094B0 A3[B5D70000]        <1> 	mov	[FAT_CurrentCluster], eax
    34                              <1> check_next_cluster_fat_type:
    35 000094B5 29D2                <1> 	sub	edx, edx ; 0
    36 000094B7 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    37 000094BB 7250                <1> 	jb	short get_FAT12_next_cluster
    38 000094BD 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    39                              <1> get_FAT16_next_cluster:
    40 000094C3 BB00030000          <1> 	mov	ebx, 300h ;768
    41 000094C8 F7F3                <1> 	div	ebx
    42                              <1> 	; EAX = Count of 3 FAT sectors
    43                              <1> 	; EDX = Cluster Offset (< 768)
    44 000094CA 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    45 000094CD 89D3                <1> 	mov	ebx, edx ; Byte Offset
    46 000094CF 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    47 000094D5 66BA0300            <1> 	mov	dx, 3
    48 000094D9 F7E2                <1> 	mul	edx  
    49                              <1> 	; EAX = FAT Sector (<= 256)
    50                              <1> 	; EDX = 0
    51 000094DB 8A0E                <1> 	mov	cl, [esi+LD_Name]
    52 000094DD 803D[B9D70000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    53 000094E4 0F86CC000000        <1>         jna     load_FAT_sectors0
    54 000094EA 3A0D[BAD70000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    55 000094F0 0F85C0000000        <1>         jne     load_FAT_sectors0
    56 000094F6 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
    57 000094FC 0F85BA000000        <1>         jne     load_FAT_sectors1
    58                              <1> 	;movzx	eax, word [ebx]
    59 00009502 668B03              <1> 	mov	ax, [ebx]
    60                              <1> 	; 01/02/2016
    61                              <1> 	; DRV_FAT.ASM (21/08/2011) had a FATal bug here !
    62                              <1> 	; (cmp ah, 0Fh) ! (ax >= FF7h)
    63                              <1> 	; (how can i do a such mistake!?)
    64                              <1> 	;cmp	al, 0F7h
    65                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    66                              <1> 	;cmp	ah, 0FFh
    67                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    68 00009505 6683F8F7            <1> 	cmp	ax, 0FFF7h
    69 00009509 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    70                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    71 0000950B EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    72                              <1> 
    73                              <1> get_FAT12_next_cluster:
    74 0000950D BB00040000          <1> 	mov	ebx, 400h ;1024
    75 00009512 F7F3                <1> 	div	ebx
    76                              <1> 	; EAX = Count of 3 FAT sectors
    77                              <1> 	; EDX = Cluster Offset (< 1024)
    78 00009514 6650                <1> 	push	ax
    79 00009516 66B80300            <1> 	mov	ax, 3	
    80 0000951A 66F7E2              <1> 	mul	dx    	; Multiply by 3
    81 0000951D 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    82 00009520 6689C3              <1>         mov	bx, ax 	; Byte Offset
    83 00009523 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    84 00009529 6658                <1> 	pop	ax
    85 0000952B 66BA0300            <1> 	mov	dx, 3
    86 0000952F F7E2                <1> 	mul	edx 
    87                              <1> 	; EAX = FAT Sector (<= 12)
    88                              <1> 	; EDX = 0
    89 00009531 8A0E                <1> 	mov	cl, [esi+LD_Name]
    90 00009533 803D[B9D70000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    91 0000953A 767A                <1> 	jna	short load_FAT_sectors0
    92 0000953C 3A0D[BAD70000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    93 00009542 7572                <1> 	jne	short load_FAT_sectors0
    94 00009544 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
    95 0000954A 7570                <1> 	jne	short load_FAT_sectors1
    96 0000954C A1[B5D70000]        <1> 	mov	eax, [FAT_CurrentCluster]
    97 00009551 66D1E8              <1> 	shr	ax, 1
    98                              <1> 	;movzx	eax, word [ebx]
    99 00009554 668B03              <1> 	mov	ax, [ebx]
   100 00009557 7314                <1> 	jnc	short get_FAT12_nc_even
   101 00009559 66C1E804            <1> 	shr	ax, 4
   102                              <1> loc_gnc_fat12_eoc_check:
   103                              <1> 	;cmp	al, 0F7h
   104                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   105                              <1> 	;cmp	ah, 0Fh
   106                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   107 0000955D 663DF70F            <1> 	cmp	ax, 0FF7h
   108 00009561 7202                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
   109                              <1> 	; ax >= FF7h (cluster 0002h to FF6h is valid, in use)
   110                              <1> 
   111                              <1> loc_pass_gnc_FAT16_eoc_check_xor_eax:
   112 00009563 31C0                <1> 	xor	eax, eax ; 0
   113                              <1> loc_pass_gnc_FAT16_eoc_check:
   114                              <1> loc_pass_gnc_FAT32_eoc_check:
   115 00009565 8B0D[B5D70000]      <1> 	mov	ecx, [FAT_CurrentCluster]
   116 0000956B F5                  <1> 	cmc
   117 0000956C C3                  <1> 	retn
   118                              <1> 
   119                              <1> get_FAT12_nc_even:
   120 0000956D 80E40F              <1> 	and	ah, 0Fh
   121 00009570 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   122                              <1> 
   123                              <1> get_FAT32_next_cluster:
   124 00009572 BB80010000          <1> 	mov	ebx, 180h ;384
   125 00009577 F7F3                <1> 	div	ebx
   126                              <1> 	; EAX = Count of 3 FAT sectors
   127                              <1> 	; EDX = Cluster Offset (< 384)
   128 00009579 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   129 0000957D 89D3                <1> 	mov	ebx, edx ; Byte Offset
   130 0000957F 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   131 00009585 66BA0300            <1> 	mov	dx, 3
   132 00009589 F7E2                <1> 	mul	edx	
   133                              <1>         ; EAX = FAT Sector (<= 2097152) ; (FFFFFF7h * 4) / 512
   134                              <1> 	; 	for 32KB cluster size:
   135                              <1> 	;	EAX <= 1024 = (4GB / 32KB) * 4) / 512 	
   136                              <1> 	; EDX = 0
   137 0000958B 8A0E                <1> 	mov	cl, [esi+LD_Name]
   138 0000958D 803D[B9D70000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   139 00009594 7620                <1> 	jna	short load_FAT_sectors0
   140 00009596 3A0D[BAD70000]      <1> 	cmp	cl, [FAT_BuffDrvName]
   141 0000959C 7518                <1> 	jne	short load_FAT_sectors0
   142 0000959E 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   143 000095A4 7516                <1> 	jne	short load_FAT_sectors1
   144 000095A6 8B03                <1> 	mov	eax, [ebx]
   145 000095A8 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   146 000095AD 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   147 000095B2 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   148                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   149 000095B4 EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   150                              <1> 
   151                              <1> load_FAT_sectors0:
   152 000095B6 880D[BAD70000]      <1> 	mov	[FAT_BuffDrvName], cl
   153                              <1> load_FAT_sectors1:
   154 000095BC A3[BDD70000]        <1> 	mov	[FAT_BuffSector], eax
   155 000095C1 89C3                <1> 	mov	ebx, eax
   156 000095C3 034660              <1>         add     eax, [esi+LD_FATBegin]
   157 000095C6 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   158 000095CA 7706                <1>         ja      short load_FAT_sectors3
   159 000095CC 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   160 000095D0 EB03                <1> 	jmp	short load_FAT_sectors4
   161                              <1> load_FAT_sectors3:
   162 000095D2 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   163                              <1> load_FAT_sectors4:
   164 000095D5 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   165 000095D7 83F903              <1>         cmp     ecx, 3
   166 000095DA 7605                <1>         jna     short load_FAT_sectors5
   167 000095DC B903000000          <1> 	mov	ecx, 3
   168                              <1> load_FAT_sectors5:
   169 000095E1 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   170 000095E6 E8A0240000          <1> 	call	disk_read
   171 000095EB 730D                <1> 	jnc	short load_FAT_sectors_ok
   172                              <1> 	; 23/03/2016
   173 000095ED B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   174 000095F2 C605[B9D70000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   175 000095F9 C3                  <1> 	retn
   176                              <1> load_FAT_sectors_ok:
   177 000095FA C605[B9D70000]01    <1> 	mov	byte [FAT_BuffValidData], 1
   178 00009601 A1[B5D70000]        <1> 	mov	eax, [FAT_CurrentCluster]
   179 00009606 E9AAFEFFFF          <1>         jmp     check_next_cluster_fat_type
   180                              <1> 
   181                              <1> load_FAT_root_directory:
   182                              <1> 	; 07/02/2016
   183                              <1> 	; 02/02/2016
   184                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   185                              <1> 	; 21/05/2011
   186                              <1> 	; 22/08/2009
   187                              <1> 	;
   188                              <1> 	; INPUT ->
   189                              <1> 	;	ESI = Logical DOS Drive Description Table
   190                              <1> 	; OUTPUT ->
   191                              <1> 	;	cf = 1 -> Root directory could not be loaded
   192                              <1> 	;	    EAX > 0 -> Error number
   193                              <1> 	;	cf = 0 -> EAX = 0
   194                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   195                              <1> 	;	EBX = Directory buffer address
   196                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   197                              <1> 	;
   198                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   199                              <1> 
   200                              <1> 	; NOTE: Only for FAT12 and FAT16 file systems !
   201                              <1> 	; (FAT32 fs root dir must be loaded as sub directory)
   202                              <1> 
   203 0000960B 8A1E                <1> 	mov	bl, [esi+LD_Name]
   204 0000960D 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   205                              <1> 
   206                              <1> 	;mov	[DirBuff_DRV], bl
   207                              <1> 	;mov	[DirBuff_FATType], bh
   208 00009610 66891D[CAD70000]    <1> 	mov	[DirBuff_DRV], bx
   209                              <1> 	
   210                              <1> 	;cmp	bh, 2
   211                              <1> 	;ja	short load_FAT32_root_dir0 ; FAT32 root dir
   212                              <1> 
   213 00009617 0FB75617            <1> 	movzx	edx, word [esi+LD_BPB+RootDirEnts]
   214                              <1> 
   215                              <1> 	;or	dx, dx ; 0 for FAT32 file systems
   216                              <1> 	;jz	short load_FAT32_root_dir0 ; FAT32 root dir
   217                              <1> 
   218 0000961B 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   219 00009620 7414                <1> 	je	short lrd_mov_ecx_32
   220 00009622 89D0                <1> 	mov	eax, edx
   221 00009624 6683C00F            <1> 	add	ax, 15 ; round up 
   222 00009628 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
   223 0000962C 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
   224 0000962E 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
   225 00009632 664A                <1> 	dec	dx    ; Last entry number of root dir
   226                              <1> 	; cx = Dir Buffer sector count             
   227 00009634 EB0B                <1> 	jmp	short lrd_check_dir_buffer
   228                              <1> 
   229                              <1> lrd_mov_ecx_32:
   230 00009636 B920000000          <1> 	mov	ecx, 32
   231 0000963B 664A                <1> 	dec	dx ; 511
   232 0000963D 66B80040            <1> 	mov	ax, 32*512 
   233                              <1>  
   234                              <1> lrd_check_dir_buffer:
   235 00009641 29DB                <1> 	sub	ebx, ebx ; 0
   236 00009643 881D[CCD70000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   237 00009649 668915[CFD70000]    <1> 	mov	[DirBuff_LastEntry], dx
   238 00009650 891D[D1D70000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   239 00009656 66A3[D5D70000]      <1> 	mov	[DirBuffer_Size], ax
   240                              <1> 
   241 0000965C 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   242                              <1> read_directory:
   243 0000965F BB00000800          <1> 	mov	ebx, Directory_Buffer
   244 00009664 51                  <1> 	push	ecx ; Directory buffer sector count
   245 00009665 53                  <1> 	push	ebx
   246 00009666 E820240000          <1> 	call	disk_read
   247 0000966B 5B                  <1> 	pop	ebx
   248 0000966C 720B                <1> 	jc	short load_DirBuff_error
   249                              <1> 
   250                              <1> validate_DirBuff_and_return:
   251 0000966E 59                  <1> 	pop	ecx ; Number of loaded sectors
   252 0000966F C605[CCD70000]01    <1> 	mov	byte [DirBuff_ValidData], 1
   253 00009676 31C0                <1> 	xor	eax, eax ; 0 = no error
   254 00009678 C3                  <1> 	retn
   255                              <1> 
   256                              <1> load_DirBuff_error:
   257 00009679 89C8                <1> 	mov	eax, ecx ; remaining sectors
   258 0000967B 59                  <1> 	pop	ecx ; sector count
   259 0000967C 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   260 0000967E B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
   261 00009683 F9                  <1> 	stc
   262 00009684 C3                  <1>         retn
   263                              <1> 
   264                              <1> load_FAT32_root_directory:
   265                              <1> 	; 02/02/2016 (TRDOS 386 =  TRDOS v2.0)
   266                              <1> 	;
   267                              <1> 	; INPUT ->
   268                              <1> 	;	ESI = Logical DOS Drive Description Table
   269                              <1> 	; OUTPUT ->
   270                              <1> 	;	cf = 1 -> Root directory could not be loaded
   271                              <1> 	;	    EAX > 0 -> Error number
   272                              <1> 	;	cf = 0 -> EAX = 0
   273                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   274                              <1> 	;	EBX = Directory buffer address
   275                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   276                              <1> 	;
   277                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   278                              <1> 
   279                              <1> 
   280 00009685 8A1E                <1> 	mov	bl, [esi+LD_Name]
   281 00009687 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   282                              <1> 
   283                              <1> 	;mov	[DirBuff_DRV], bl
   284                              <1> 	;mov	[DirBuff_FATType], bh
   285 0000968A 66891D[CAD70000]    <1> 	mov	[DirBuff_DRV], bx
   286                              <1> 
   287                              <1> load_FAT32_root_dir0:
   288 00009691 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   289 00009694 EB0C                <1> 	jmp	short load_FAT_sub_dir0
   290                              <1> 	
   291                              <1> load_FAT_sub_directory:
   292                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   293                              <1> 	; 05/07/2011
   294                              <1> 	; 23/08/2009
   295                              <1> 	;
   296                              <1> 	; INPUT ->
   297                              <1> 	;	ESI = Logical DOS Drive Description Table
   298                              <1> 	;	EAX = Cluster Number
   299                              <1> 	; OUTPUT ->
   300                              <1> 	;	cf = 1 -> Sub directory could not be loaded
   301                              <1> 	;	    EAX > 0 -> Error number
   302                              <1> 	;	cf = 0 -> EAX = 0
   303                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   304                              <1> 	;	EBX = Directory buffer address
   305                              <1> 	;
   306                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   307                              <1> 	;
   308                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   309                              <1> 
   310 00009696 8A1E                <1> 	mov	bl, [esi+LD_Name]
   311 00009698 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   312                              <1> 
   313                              <1> 	;mov	[DirBuff_DRV], bl
   314                              <1> 	;mov	[DirBuff_FATType], bh
   315 0000969B 66891D[CAD70000]    <1> 	mov	[DirBuff_DRV], bx
   316                              <1> 
   317                              <1> load_FAT_sub_dir0:
   318 000096A2 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   319                              <1> 
   320 000096A6 882D[CCD70000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   321 000096AC A3[D1D70000]        <1> 	mov	[DirBuff_Cluster], eax
   322                              <1> 
   323 000096B1 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   324 000096B5 F7E1                <1> 	mul	ecx
   325 000096B7 C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   326 000096BA 6648                <1> 	dec	ax ; last entry
   327 000096BC 66A3[CFD70000]      <1> 	mov	[DirBuff_LastEntry], ax
   328                              <1> 
   329 000096C2 A1[D1D70000]        <1> 	mov	eax, [DirBuff_Cluster]
   330 000096C7 83E802              <1> 	sub	eax, 2
   331 000096CA F7E1                <1> 	mul	ecx
   332 000096CC 034668              <1> 	add	eax, [esi+LD_DATABegin]
   333                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   334 000096CF EB8E                <1> 	jmp	short read_directory
   335                              <1> 
   336                              <1> ; DRV_FS.ASM
   337                              <1> 
   338                              <1> load_current_FS_directory:
   339 000096D1 C3                  <1> 	retn
   340                              <1> load_FS_root_directory:
   341 000096D2 C3                  <1> 	retn
   342                              <1> load_FS_sub_directory:
   343 000096D3 C3                  <1> 	retn
   344                              <1> 
   345                              <1> read_cluster:
   346                              <1> 	; 18/03/2016
   347                              <1> 	; 16/03/2016
   348                              <1> 	; 17/02/2016
   349                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   350                              <1> 	;
   351                              <1> 	; INPUT ->
   352                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
   353                              <1> 	;	ESI = Logical DOS Drive Description Table address
   354                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
   355                              <1> 	;	Only for SINGLIX FS:
   356                              <1> 	;	EDX = File Number (The 1st FDT address) 
   357                              <1> 	; OUTPUT ->
   358                              <1> 	;	cf = 1 -> Cluster can not be loaded at the buffer
   359                              <1> 	;	    EAX > 0 -> Error number
   360                              <1> 	;	cf = 0 -> Cluster has been loaded at the buffer
   361                              <1> 	;
   362                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   363                              <1> 	
   364 000096D4 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
   365                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
   366                              <1> 
   367                              <1> read_file_sectors: ; 16/03/2016
   368 000096D8 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   369 000096DC 761C                <1> 	jna	short read_fs_cluster
   370                              <1> 
   371                              <1> read_fat_file_sectors: ; 18/03/2016
   372 000096DE 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   373 000096E1 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
   374 000096E5 F7E2                <1> 	mul	edx
   375 000096E7 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
   376                              <1> 
   377                              <1> 	; EAX = Disk sector address
   378                              <1> 	; ECX = Sector count
   379                              <1> 	; EBX = Buffer address
   380                              <1> 	; (EDX = 0)
   381                              <1> 	; ESI = Logical DOS drive description table address	
   382                              <1> 
   383 000096EA E89C230000          <1> 	call	disk_read
   384 000096EF 7306                <1> 	jnc	short rclust_retn
   385                              <1> 	
   386 000096F1 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
   387 000096F6 C3                  <1> 	retn
   388                              <1> 
   389                              <1> rclust_retn:
   390 000096F7 29C0                <1> 	sub	eax, eax ; 0
   391 000096F9 C3                  <1> 	retn
   392                              <1> 
   393                              <1> read_fs_cluster:
   394                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   395                              <1> 	; Singlix FS
   396                              <1> 	
   397                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
   398                              <1> 	
   399                              <1> 	; EDX = File number is the first File Descriptor Table address 
   400                              <1> 	;	of the file. (Absolute address of the FDT).
   401                              <1> 	
   402                              <1> 	; eax = sector index (0 for the first sector)
   403                              <1> 	; edx = FDT0 address
   404                              <1> 		; 64 KB buffer = 128 sectors (limit) 
   405 000096FA B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   406 000096FF E801000000          <1> 	call	read_fs_sectors
   407 00009704 C3                  <1> 	retn
   408                              <1> 
   409                              <1> read_fs_sectors:
   410                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   411 00009705 F9                  <1> 	stc
   412 00009706 C3                  <1> 	retn
   413                              <1> 
   414                              <1> get_first_free_cluster:
   415                              <1> 	; 02/03/2016
   416                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   417                              <1> 	; 26/10/2010 (DRV_FAT.ASM, 'proc_get_first_free_cluster')
   418                              <1> 	; 10/07/2010
   419                              <1> 	; INPUT ->
   420                              <1> 	;	ESI = Logical DOS Drive Description Table address
   421                              <1> 	; OUTPUT ->
   422                              <1> 	;	cf = 1 -> Error code in AL (EAX)
   423                              <1> 	;	cf = 0 -> 
   424                              <1> 	;	  EAX = Cluster number 
   425                              <1> 	;	  If EAX = FFFFFFFFh -> no free space
   426                              <1> 	;	If the drive has FAT32 fs:
   427                              <1> 	;	  EBX = FAT32 FSI sector buffer address (if > 0)
   428                              <1> 
   429 00009707 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   430 0000970A 40                  <1> 	inc	eax ; add eax, 1
   431 0000970B A3[54DA0000]        <1> 	mov	[gffc_last_free_cluster], eax
   432                              <1> 
   433 00009710 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   434                              <1> 
   435 00009712 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   436 00009716 760E                <1> 	jna	short loc_gffc_get_first_fat_free_cluster0
   437                              <1> 
   438                              <1> loc_gffc_get_first_fat32_free_cluster:
   439                              <1> 	; 02/03/2016
   440 00009718 E834060000          <1> 	call	get_fat32_fsinfo_sector_parms
   441 0000971D 7207                <1> 	jc	short loc_gffc_get_first_fat_free_cluster0 
   442                              <1> 
   443                              <1> loc_gffc_check_fsinfo_parms:
   444                              <1> 	;;mov	ebx, DOSBootSectorBuff
   445                              <1> 	;cmp	dword [ebx], 41615252h
   446                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   447                              <1> 	;cmp	dword [ebx+484], 61417272h
   448                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   449                              <1> 	;mov	eax, [ebx+492] ; FSI_Next_Free
   450                              <1> 	;EAX = First free cluster 
   451                              <1> 	;(from FAT32 FSInfo sector)
   452 0000971F 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   453 00009721 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   454 00009724 7205                <1> 	jb	short loc_gffc_get_first_fat_free_cluster1
   455                              <1> 
   456                              <1> 	; Start from the 1st cluster of the FAT(32) file system
   457                              <1> loc_gffc_get_first_fat_free_cluster0:
   458 00009726 B802000000          <1> 	mov	eax, 2
   459                              <1> 	;xor	edx, edx
   460                              <1> 
   461                              <1> loc_gffc_get_first_fat_free_cluster1:
   462 0000972B 53                  <1> 	push	ebx ; 02/03/2016 
   463                              <1> 
   464                              <1> loc_gffc_get_first_fat_free_cluster2:   
   465 0000972C A3[50DA0000]        <1> 	mov	[gffc_first_free_cluster], eax
   466 00009731 A3[4CDA0000]        <1> 	mov	[gffc_next_free_cluster], eax
   467                              <1> 
   468                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   469                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   470                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   471                              <1> 
   472                              <1> loc_gffc_get_first_fat_free_cluster3:
   473 00009736 E875FDFFFF          <1> 	call	get_next_cluster
   474 0000973B 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   475 0000973D 09C0                <1> 	or	eax, eax
   476 0000973F 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   477 00009741 5B                  <1> 	pop	ebx ; 02/03/2016
   478 00009742 F5                  <1> 	cmc 	; stc
   479 00009743 C3                  <1> 	retn
   480                              <1> 
   481                              <1> loc_gffc_get_first_fat_free_cluster4:
   482 00009744 21C0                <1> 	and	eax, eax ; next cluster value
   483 00009746 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   484 00009748 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   485 0000974A EB22                <1> 	jmp	short loc_gffc_check_for_set
   486                              <1>  
   487                              <1> loc_gffc_first_free_fat_cluster_next:
   488 0000974C A1[4CDA0000]        <1> 	mov	eax, [gffc_next_free_cluster]
   489 00009751 3B05[54DA0000]      <1> 	cmp	eax, [gffc_last_free_cluster]
   490 00009757 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   491                              <1> pass_gffc_last_cluster_eax_check:
   492 00009759 40                  <1> 	inc	eax ; add eax, 1
   493 0000975A A3[4CDA0000]        <1> 	mov	[gffc_next_free_cluster], eax
   494 0000975F EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   495                              <1> 
   496                              <1> retn_stc_from_get_first_free_cluster:
   497 00009761 A1[50DA0000]        <1> 	mov	eax, [gffc_first_free_cluster]
   498 00009766 83F802              <1> 	cmp	eax, 2
   499 00009769 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   500 0000976B 29C0                <1> 	sub	eax, eax
   501 0000976D 48                  <1> 	dec	eax ; FFFFFFFFh
   502                              <1> 
   503                              <1> loc_gffc_check_for_set:
   504                              <1> 	; 02/03/2016
   505 0000976E 5B                  <1> 	pop	ebx
   506                              <1> 
   507                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   508                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   509                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   510                              <1> 
   511 0000976F 09DB                <1> 	or	ebx, ebx
   512 00009771 750E                <1> 	jnz	short loc_gffc_set_ffree_fat32_cluster
   513                              <1> 
   514                              <1> 	;cmp	byte [esi+LD_FATType], 3
   515                              <1> 	;jnb	short loc_gffc_set_ffree_fat32_cluster
   516                              <1> 
   517                              <1> 	;xor	ebx, ebx ; 0
   518                              <1> 
   519                              <1> loc_gffc_retn:
   520 00009773 C3                  <1> 	retn
   521                              <1> 
   522                              <1> loc_gffc_check_previous_clusters:
   523 00009774 48                  <1> 	dec	eax ; sub eax, 1
   524 00009775 A3[54DA0000]        <1> 	mov	[gffc_last_free_cluster], eax 
   525 0000977A B802000000          <1> 	mov	eax, 2
   526                              <1> 	;xor	edx, edx
   527 0000977F EBAB                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster2
   528                              <1> 
   529                              <1> loc_gffc_set_ffree_fat32_cluster:
   530                              <1> 	;call	set_first_free_cluster
   531                              <1> 	;retn
   532                              <1> 	;jmp	short set_first_free_cluster	
   533                              <1> 
   534                              <1> set_first_free_cluster:
   535                              <1> 	; 23/03/2016
   536                              <1> 	; 02/03/2016
   537                              <1> 	; 29/02/2016
   538                              <1> 	; 26/02/2016
   539                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   540                              <1> 	; 21/08/2011 (DRV_FAT.ASM, 'proc_set_first_free_cluster')
   541                              <1> 	; 11/07/2010
   542                              <1> 	; INPUT -> 
   543                              <1> 	;	ESI = Logical DOS Drive Description Table address
   544                              <1> 	;	EAX = First free cluster
   545                              <1> 	;	EBX = FSINFO sector buffer address
   546                              <1> 	;  	;;If EBX > 0, it is FSINFO sector buffer address
   547                              <1> 	;	;;EBX = 0, if FSINFO sector is not loaded
   548                              <1> 	; OUTPUT->
   549                              <1> 	;	ESI = Logical DOS Drive Description Table address
   550                              <1> 	;  	If EBX > 0, it is FSINFO sector buffer address
   551                              <1> 	;	EBX = 0, if FSINFO sector could not be loaded
   552                              <1> 	; 	CF = 1 -> Error code in AL (EAX)
   553                              <1> 	;	CF = 0 -> first free cluster is successfully updated 
   554                              <1> 
   555                              <1> 	;cmp	byte [esi+LD_FATType], 3
   556                              <1> 	;jb	short loc_sffc_invalid_drive
   557                              <1> 
   558                              <1> 	; Save First Free Cluster value for 'update_cluster'
   559 00009781 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First free Cluster	
   560                              <1> 
   561                              <1> 	;or	ebx, ebx
   562                              <1> 	;jnz	short loc_sffc_read_fsinfo_sector
   563                              <1> 
   564 00009784 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   565 0000978A 7540                <1> 	jne	short loc_sffc_read_fsinfo_sector
   566 0000978C 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   566 00009795 61                  <1>
   567 00009796 7534                <1> 	jne	short loc_sffc_read_fsinfo_sector
   568                              <1> 
   569 00009798 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   570 0000979E 741F                <1> 	je	short loc_sffc_retn
   571                              <1> 
   572                              <1> loc_sffc_write_fsinfo_sector:
   573                              <1> 	; EBX = FSINFO sector buffer
   574                              <1> 	; [CFS_FAT32FSINFOSEC] is set in 'get_fat32_fsinfo_sector_parms'
   575 000097A0 8983EC010000        <1> 	mov	[ebx+492], eax
   576 000097A6 A1[64DA0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   577 000097AB B901000000          <1> 	mov	ecx, 1
   578 000097B0 53                  <1> 	push	ebx
   579 000097B1 E8C6220000          <1> 	call	disk_write
   580 000097B6 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   581 000097B8 5B                  <1> 	pop	ebx
   582                              <1> 
   583 000097B9 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   584                              <1> 
   585                              <1> loc_sffc_retn:
   586 000097BF C3                  <1> 	retn
   587                              <1> 
   588                              <1> ;loc_sffc_invalid_drive:
   589                              <1> ;	mov	eax, 0Fh ; MSDOS Error : Invalid drive
   590                              <1> ;	push	edx
   591                              <1> 
   592                              <1> loc_sffc_read_fsinfo_sector_err1:
   593 000097C0 BB00000000          <1> 	mov	ebx, 0
   594                              <1> 	; 23/03/2016
   595 000097C5 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
   596                              <1> 
   597                              <1> loc_sffc_read_fsinfo_sector_err2:
   598 000097CA 5A                  <1> 	pop	edx
   599 000097CB C3                  <1> 	retn
   600                              <1> 	
   601                              <1> loc_sffc_read_fsinfo_sector:
   602 000097CC 50                  <1> 	push	eax
   603                              <1> 
   604 000097CD E87F050000          <1> 	call	get_fat32_fsinfo_sector_parms
   605 000097D2 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   606                              <1> 
   607 000097D4 58                  <1> 	pop	eax
   608                              <1> 	; EDX = First (Next) Free Cluster value from FSINFO sector
   609                              <1> 	; EAX = First Free Cluster value from 'get_next_cluster'
   610                              <1> 	; (edx = old value)
   611 000097D5 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   612 000097D7 75C7                <1> 	jne	short loc_sffc_write_fsinfo_sector
   613                              <1> 
   614 000097D9 C3                  <1> 	retn	
   615                              <1> 
   616                              <1> update_cluster:
   617                              <1> 	; 02/03/2016
   618                              <1> 	; 01/03/2016
   619                              <1> 	; 29/02/2016
   620                              <1> 	; 27/02/2016
   621                              <1> 	; 26/02/2016
   622                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   623                              <1> 	; 11/08/2011  
   624                              <1> 	; 09/02/2005
   625                              <1> 	; INPUT ->
   626                              <1> 	;	EAX = Cluster Number
   627                              <1> 	;	ECX = New Cluster Value
   628                              <1> 	;	ESI = Logical Dos Drive Parameters Table
   629                              <1> 	;
   630                              <1> 	;	/// dword [FAT_ClusterCounter] ///
   631                              <1> 	;
   632                              <1> 	; OUTPUT ->
   633                              <1> 	;	cf = 0 -> No Error, EAX is valid
   634                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
   635                              <1> 	; 	cf = 1 & EAX > 0 -> Error
   636                              <1> 	;		(ECX -> any value)
   637                              <1> 	; 	EAX = Next Cluster
   638                              <1> 	;	ECX = New Cluster Value
   639                              <1> 	;
   640                              <1> 	;	/// [FAT_ClusterCounter] is updated,
   641                              <1> 	;	/// decreased when a free cluster is assigned,
   642                              <1> 	;	/// increased if an assigned cluster is freed.	
   643                              <1> 	;		
   644                              <1> 	;
   645                              <1> 	; (Modified registers: EAX, EBX, -ECX-, EDX)
   646                              <1> 	
   647 000097DA A3[B5D70000]        <1> 	mov	[FAT_CurrentCluster], eax
   648 000097DF 890D[58DA0000]      <1> 	mov	[ClusterValue], ecx
   649                              <1> 
   650                              <1> loc_update_cluster_check_fat_buffer:
   651 000097E5 8A1E                <1> 	mov	bl, [esi+LD_Name]
   652 000097E7 381D[BAD70000]      <1> 	cmp	[FAT_BuffDrvName], bl
   653 000097ED 741A                <1> 	je	short loc_update_cluster_check_fat_type
   654 000097EF 803D[B9D70000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   655 000097F6 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   656                              <1> 
   657                              <1> loc_uc_reset_fat_buffer_validation:
   658 000097FC C605[B9D70000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   659                              <1> 
   660                              <1> loc_uc_check_fat_type_reset_drvname:
   661 00009803 881D[BAD70000]      <1> 	mov	[FAT_BuffDrvName], bl
   662                              <1> 
   663                              <1> loc_update_cluster_check_fat_type:
   664 00009809 29D2                <1> 	sub	edx, edx ; 26/02/2016
   665 0000980B 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   666 0000980E 83F802              <1> 	cmp	eax, 2
   667 00009811 0F82BE000000        <1>         jb      update_cluster_inv_data
   668 00009817 80FB02              <1> 	cmp	bl, 2 
   669 0000981A 0F877A010000        <1>         ja      update_fat32_cluster
   670                              <1> 	;cmp	bl, 1
   671                              <1> 	;jb	short update_cluster_inv_data
   672 00009820 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   673 00009823 41                  <1> 	inc	ecx  
   674 00009824 890D[C5D70000]      <1> 	mov	[LastCluster], ecx
   675 0000982A 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   676 0000982C 0F87A6000000        <1>         ja      return_uc_fat_stc
   677                              <1> 	; TRDOS v1 has a FATal bug here ! 
   678                              <1> 		; or bl, bl ; cmp bl, 0
   679                              <1> 		; jz short update_fat12_cluster
   680                              <1> 	; !! It would destroy FAT12 floppy disk fs here !!
   681                              <1> 	; ('A:' disks of TRDOS v1 operating system project
   682                              <1> 	; had 'singlix fs', so, I could not differ this mistake
   683                              <1> 	; on a drive 'A:')
   684 00009832 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   685 00009835 0F86A2000000        <1>         jna     update_fat12_cluster 
   686                              <1> 
   687                              <1> update_fat16_cluster:
   688                              <1> pass_uc_fat16_errc:
   689                              <1> 	;sub	edx, edx
   690 0000983B BB00030000          <1> 	mov	ebx, 300h ;768
   691 00009840 F7F3                <1> 	div	ebx
   692                              <1> 	; EAX = Count of 3 FAT sectors
   693                              <1> 	; DX = Cluster offset in FAT buffer
   694 00009842 6689D3              <1> 	mov	bx, dx  
   695 00009845 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   696 00009848 66BA0300            <1> 	mov	dx, 3
   697 0000984C F7E2                <1> 	mul	edx  
   698                              <1> 	; EAX = FAT Sector
   699                              <1> 	; EDX = 0
   700                              <1> 	; EBX = Byte offset in FAT buffer
   701 0000984E 8A0D[B9D70000]      <1> 	mov	cl, [FAT_BuffValidData]
   702 00009854 80F902              <1> 	cmp	cl, 2
   703 00009857 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   704                              <1> 
   705                              <1> loc_uc_check_fat16_buff_sector_save:
   706 00009859 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   707 0000985F 755D                <1> 	jne	short loc_uc_save_fat_buffer
   708 00009861 EB15                <1> 	jmp	short loc_update_fat16_cell
   709                              <1> 
   710                              <1> loc_uc_check_fat16_buff_sector_load:
   711 00009863 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   712 00009866 0F85FB010000        <1>         jne     loc_uc_load_fat_sectors
   713 0000986C 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   714 00009872 0F85EF010000        <1>         jne     loc_uc_load_fat_sectors
   715                              <1> 
   716                              <1> loc_update_fat16_cell:
   717                              <1> loc_update_fat16_buffer:
   718 00009878 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   719                              <1> 	;movzx	eax, word [ebx]
   720 0000987E 668B03              <1> 	mov	ax, [ebx]
   721                              <1> 	; 01/03/2016
   722 00009881 89C2                <1> 	mov	edx, eax ; old value of the cluster
   723 00009883 A3[B5D70000]        <1> 	mov	[FAT_CurrentCluster], eax
   724 00009888 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   725 0000988E 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   726                              <1> 
   727 00009891 C605[B9D70000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   728                              <1> 	
   729 00009898 6683F802            <1> 	cmp	ax, 2
   730 0000989C 723A                <1> 	jb	short return_uc_fat_stc
   731 0000989E 3B05[C5D70000]      <1> 	cmp	eax, [LastCluster]
   732 000098A4 7732                <1> 	ja	short return_uc_fat_stc
   733                              <1> 
   734                              <1> loc_fat_buffer_updated:
   735                              <1> 	; 01/03/2016
   736 000098A6 F8                  <1> 	clc
   737                              <1> loc_fat_buffer_stc_1:
   738 000098A7 9C                  <1> 	pushf
   739 000098A8 21C9                <1> 	and	ecx, ecx
   740 000098AA 7506                <1> 	jnz	short loc_fat_buffer_updated_1
   741                              <1> 
   742                              <1> 	; 01/03/2016 
   743                              <1> 	; new value of the cluster = 0 (free)
   744                              <1> 	; increase free(d) cluster count
   745 000098AC FF05[C1D70000]      <1> 	inc	dword [FAT_ClusterCounter]
   746                              <1> 
   747                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   748 000098B2 09D2                <1> 	or	edx, edx ; 02/03/2016
   749 000098B4 7506                <1> 	jnz	short loc_fat_buffer_updated_2
   750                              <1> 	; old value of the cluster = 0 (it was free cluster)
   751                              <1> 	; decrease free(d) cluster count
   752 000098B6 FF0D[C1D70000]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   753                              <1> 
   754                              <1> loc_fat_buffer_updated_2:
   755 000098BC 9D                  <1> 	popf
   756 000098BD C3                  <1> 	retn
   757                              <1> 
   758                              <1> loc_uc_save_fat_buffer:
   759                              <1> 	; byte [FAT_BuffValidData] = 2 
   760 000098BE E8D4010000          <1> 	call	save_fat_buffer
   761 000098C3 0F8297010000        <1>         jc      loc_fat_sectors_rw_error2
   762                              <1> 	;mov	byte [FAT_BuffValidData], 1
   763 000098C9 A1[B5D70000]        <1> 	mov	eax, [FAT_CurrentCluster]
   764                              <1> 	;mov	ecx, [ClusterValue]
   765                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   766 000098CE 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   767 000098D0 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   768                              <1> 
   769                              <1> update_cluster_inv_data:
   770                              <1> 	;mov	eax, 0Dh
   771 000098D5 B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   772 000098D7 C3                  <1> 	retn 
   773                              <1> 
   774                              <1> return_uc_fat_stc:
   775                              <1> 	; 01/03/2016
   776 000098D8 31C0                <1> 	xor	eax, eax
   777 000098DA F9                  <1> 	stc
   778 000098DB EBCA                <1> 	jmp	short loc_fat_buffer_stc_1
   779                              <1> 
   780                              <1> update_fat12_cluster:
   781                              <1> pass_uc_fat12_errc:
   782                              <1> 	;sub	edx, edx
   783 000098DD BB00040000          <1> 	mov	ebx, 400h ;1024
   784 000098E2 F7F3                <1> 	div	ebx
   785                              <1> 	; EAX = Count of 3 FAT sectors
   786                              <1> 	; DX = Cluster offset in FAT buffer
   787 000098E4 66B90300            <1> 	mov	cx, 3
   788 000098E8 6689C3              <1> 	mov	bx, ax
   789 000098EB 6689C8              <1> 	mov	ax, cx ; 3
   790 000098EE 66F7E2              <1> 	mul	dx     ; Multiply by 3
   791 000098F1 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   792 000098F4 6693                <1> 	xchg	bx, ax
   793                              <1> 	; EAX = Count of 3 FAT sectors
   794                              <1> 	; EBX = Byte Offset in FAT buffer   
   795 000098F6 66F7E1              <1> 	mul	cx  ; 3 * AX
   796                              <1> 	; EAX = FAT Beginning Sector
   797                              <1> 	; EDX = 0
   798 000098F9 8A0D[B9D70000]      <1> 	mov	cl, [FAT_BuffValidData]
   799                              <1> 	; TRDOS v1 has a FATal bug here ! 
   800                              <1> 	; (it does not have 'cmp cl, 2' instruction here !
   801                              <1> 	;  while 'jne' is existing !)
   802 000098FF 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   803 00009902 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   804                              <1> 
   805                              <1> loc_uc_check_fat12_buff_sector_save:
   806 00009904 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   807 0000990A 75B2                <1>         jne     short loc_uc_save_fat_buffer
   808 0000990C EB15                <1> 	jmp	short loc_update_fat12_cell
   809                              <1> 
   810                              <1> loc_uc_check_fat12_buff_sector_load:
   811 0000990E 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   812 00009911 0F8550010000        <1>         jne     loc_uc_load_fat_sectors
   813 00009917 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   814 0000991D 0F8544010000        <1>         jne     loc_uc_load_fat_sectors
   815                              <1> 
   816                              <1> loc_update_fat12_cell:
   817 00009923 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   818 00009929 668B0D[B5D70000]    <1> 	mov	cx, [FAT_CurrentCluster]
   819 00009930 66D1E9              <1> 	shr	cx, 1
   820 00009933 668B03              <1> 	mov	ax, [ebx]
   821 00009936 6689C2              <1> 	mov	dx, ax
   822 00009939 7344                <1> 	jnc	short uc_fat12_nc_even
   823                              <1> 
   824 0000993B 6683E00F            <1> 	and	ax, 0Fh
   825 0000993F 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   826 00009945 66C1E104            <1> 	shl	cx, 4
   827 00009949 6609C1              <1> 	or	cx, ax
   828 0000994C 6689D0              <1> 	mov	ax, dx
   829 0000994F 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   830 00009952 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   831                              <1> 
   832                              <1> update_fat12_buffer:
   833 00009956 A3[B5D70000]        <1> 	mov	[FAT_CurrentCluster], eax
   834 0000995B 89C2                <1> 	mov	edx, eax ; 01/03/2016
   835 0000995D C605[B9D70000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   836 00009964 6683F802            <1> 	cmp	ax, 2
   837 00009968 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   838 0000996E 3B05[C5D70000]      <1> 	cmp	eax, [LastCluster]
   839 00009974 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   840 0000997A E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   841                              <1> 
   842                              <1> uc_fat12_nc_even:
   843 0000997F 662500F0            <1> 	and	ax, 0F000h
   844 00009983 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   845 00009989 80E50F              <1> 	and	ch, 0Fh
   846 0000998C 6609C1              <1> 	or	cx, ax
   847 0000998F 6689D0              <1> 	mov	ax, dx
   848 00009992 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   849 00009995 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   850 00009998 EBBC                <1> 	jmp	short update_fat12_buffer
   851                              <1> 
   852                              <1> update_fat32_cluster:
   853 0000999A 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   854 0000999D 41                  <1> 	inc	ecx
   855 0000999E 890D[C5D70000]      <1> 	mov	[LastCluster], ecx
   856                              <1> 
   857 000099A4 39C8                <1> 	cmp	eax, ecx
   858 000099A6 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   859                              <1> 
   860                              <1> pass_uc_fat32_errc:
   861                              <1> 	;sub	edx, edx
   862 000099AC BB80010000          <1> 	mov	ebx, 180h ;384
   863 000099B1 F7F3                <1> 	div	ebx
   864                              <1> 	; EAX = Count of 3 FAT sectors
   865                              <1> 	; DX = Cluster offset in FAT buffer
   866 000099B3 89D3                <1> 	mov	ebx, edx
   867 000099B5 C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   868 000099B8 BA03000000          <1> 	mov	edx, 3	
   869 000099BD F7E2                <1> 	mul	edx
   870                              <1> 	; EBX = Cluster Offset in FAT buffer
   871                              <1> 	; EAX = FAT Sector
   872                              <1> 	; EDX = 0
   873 000099BF 8A0D[B9D70000]      <1> 	mov	cl, [FAT_BuffValidData]
   874 000099C5 80F902              <1> 	cmp	cl, 2
   875 000099C8 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   876                              <1> 
   877                              <1> loc_uc_check_fat32_buff_sector_save:
   878 000099CA 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   879 000099D0 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   880 000099D6 EB11                <1> 	jmp	short loc_update_fat32_cell
   881                              <1> 
   882                              <1> loc_uc_check_fat32_buff_sector_load:
   883 000099D8 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   884 000099DB 0F8586000000        <1>         jne     loc_uc_load_fat_sectors
   885 000099E1 3B05[BDD70000]      <1> 	cmp	eax, [FAT_BuffSector]
   886 000099E7 757E                <1>         jne     loc_uc_load_fat_sectors
   887                              <1> 
   888                              <1> loc_update_fat32_cell:
   889                              <1> loc_update_fat32_buffer:
   890 000099E9 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   891 000099EF 8B03                <1> 	mov	eax, [ebx]
   892 000099F1 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   893                              <1> 	
   894 000099F6 8B15[B5D70000]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   895                              <1> 
   896 000099FC A3[B5D70000]        <1> 	mov 	[FAT_CurrentCluster], eax
   897 00009A01 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue]
   898 00009A07 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   899                              <1> 
   900 00009A09 C605[B9D70000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   901                              <1> 
   902                              <1> 	; 01/03/2016
   903 00009A10 21C0                <1> 	and	eax, eax ; was it free cluster ?
   904 00009A12 7514                <1> 	jnz	short loc_upd_fat32_c0
   905                              <1> 
   906                              <1> 	;or	ecx, ecx ; it will be left free ?!
   907                              <1> 	;jz	short loc_upd_fat32_c3
   908                              <1> 
   909 00009A14 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   910 00009A17 7520                <1> 	jne	short loc_upd_fat32_c3
   911                              <1> 
   912 00009A19 3B15[C5D70000]      <1> 	cmp	edx, [LastCluster]
   913 00009A1F 7207                <1> 	jb	short loc_upd_fat32_c0
   914                              <1> 
   915 00009A21 BA02000000          <1> 	mov	edx, 2 ; rewind !
   916 00009A26 EB0E                <1> 	jmp	short loc_upd_fat32_c2
   917                              <1> 
   918                              <1> loc_upd_fat32_c0:
   919 00009A28 FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   920 00009A2B EB0C                <1> 	jmp	short loc_upd_fat32_c3
   921                              <1> 
   922                              <1> loc_upd_fat32_c1:
   923 00009A2D 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   924 00009A2F 7508                <1> 	jnz	short loc_upd_fat32_c3
   925                              <1> 
   926 00009A31 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   927 00009A34 7303                <1> 	jnb	short loc_upd_fat32_c3
   928                              <1> 
   929                              <1> loc_upd_fat32_c2:	
   930 00009A36 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   931                              <1> 
   932                              <1> loc_upd_fat32_c3:
   933 00009A39 89C2                <1> 	mov	edx, eax
   934                              <1> 
   935                              <1> loc_upd_fat32_c4:
   936 00009A3B 83F802              <1> 	cmp	eax, 2
   937 00009A3E 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   938                              <1> 
   939                              <1> pass_uc_fat32_c_zero_check_2:
   940 00009A44 3B05[C5D70000]      <1> 	cmp	eax, [LastCluster]
   941 00009A4A 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   942                              <1> 	
   943 00009A50 E951FEFFFF          <1> 	jmp     loc_fat_buffer_updated
   944                              <1> 
   945                              <1> loc_fat_sectors_rw_error1:
   946                              <1> 	;mov	byte [FAT_BuffValidData], 0
   947                              <1> 	; 23/03/2016
   948 00009A55 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   949 00009A5A 8825[B9D70000]      <1> 	mov	[FAT_BuffValidData], ah ; 0
   950                              <1> 
   951                              <1> loc_fat_sectors_rw_error2:
   952                              <1> 	;mov	eax, error code
   953                              <1> 	;mov	edx, 0
   954 00009A60 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue]
   955 00009A66 C3                  <1> 	retn
   956                              <1> 
   957                              <1> loc_uc_load_fat_sectors:
   958 00009A67 A3[BDD70000]        <1> 	mov	[FAT_BuffSector], eax
   959                              <1> 
   960                              <1> load_uc_fat_sectors_zero:
   961 00009A6C 034660              <1> 	add	eax, [esi+LD_FATBegin]
   962 00009A6F BB001C0900          <1> 	mov	ebx, FAT_Buffer
   963 00009A74 B903000000          <1> 	mov	ecx, 3
   964 00009A79 E80D200000          <1> 	call	disk_read
   965 00009A7E 72D5                <1> 	jc	short loc_fat_sectors_rw_error1
   966                              <1> 
   967 00009A80 C605[B9D70000]01    <1>         mov     byte [FAT_BuffValidData], 1
   968 00009A87 A1[B5D70000]        <1> 	mov 	eax, [FAT_CurrentCluster]
   969 00009A8C 8B0D[58DA0000]      <1> 	mov	ecx, [ClusterValue]
   970 00009A92 E972FDFFFF          <1>         jmp     loc_update_cluster_check_fat_type
   971                              <1> 
   972                              <1> save_fat_buffer:
   973                              <1> 	; 01/03/2016
   974                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   975                              <1> 	; 11/08/2011
   976                              <1> 	; 09/02/2005 
   977                              <1> 	; INPUT ->
   978                              <1> 	;	None
   979                              <1> 	; OUTPUT ->
   980                              <1> 	;	cf = 0 -> OK.
   981                              <1> 	;	cf = 1 -> error code in AL (EAX)
   982                              <1> 	;
   983                              <1> 	;	EBX = FAT_Buffer address
   984                              <1> 	;
   985                              <1> 	; (EAX, EDX, ECX will be modified)
   986                              <1> 
   987                              <1> 	;cmp	byte [FAT_BuffValidData], 2 
   988                              <1> 	;je	short loc_save_fat_buff
   989                              <1> 
   990                              <1> ;loc_save_fat_buffer_retn:
   991                              <1> ;	xor	eax, eax
   992                              <1> ;	retn
   993                              <1> 
   994                              <1> loc_save_fat_buff:
   995 00009A97 31D2                <1> 	xor	edx, edx
   996 00009A99 8A35[BAD70000]      <1> 	mov	dh, [FAT_BuffDrvName]
   997 00009A9F 80FE41              <1> 	cmp	dh, 'A'
   998 00009AA2 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
   999 00009AA4 80EE41              <1> 	sub	dh, 'A'
  1000 00009AA7 56                  <1> 	push	esi ; *
  1001 00009AA8 BE00010900          <1>         mov     esi, Logical_DOSDisks
  1002 00009AAD 01D6                <1> 	add	esi, edx
  1003                              <1> 	
  1004 00009AAF 8A5603              <1> 	mov	dl, [esi+LD_FATType]
  1005 00009AB2 20D2                <1> 	and	dl, dl
  1006 00009AB4 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
  1007                              <1> 
  1008 00009AB6 A1[BDD70000]        <1> 	mov	eax, [FAT_BuffSector]
  1009 00009ABB 80FA02              <1> 	cmp	dl, 2
  1010 00009ABE 770A                <1> 	ja	short loc_save_fat32_buff
  1011                              <1> 
  1012                              <1> loc_save_fat_12_16_buff:
  1013                              <1> 	; 01/03/2016
  1014                              <1> 	; TRDOS v1 has a FATal bug here!
  1015                              <1> 	; Correct code: mov dx, word ptr [FAT_BuffSector]+2
  1016                              <1> 	; (DX:AX in TRDOS v1 -> EAX in TRDOS v2)
  1017                              <1> 	;
  1018 00009AC0 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
  1019 00009AC4 29C1                <1> 	sub	ecx, eax
  1020                              <1> 	; TRDOS v1 has a bug here... ('pop esi' was forgotten!)
  1021                              <1> 	;jna	short loc_save_fat_buffer_inv_data_retn ; wrong addr!
  1022 00009AC6 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1023 00009AC8 EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1024                              <1> 
  1025                              <1> loc_save_fat32_buff:
  1026 00009ACA 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1027 00009ACD 29C1                <1> 	sub	ecx, eax
  1028 00009ACF 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1029                              <1> 
  1030                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1031 00009AD1 5E                  <1> 	pop	esi ; *
  1032                              <1> loc_save_fat_buffer_inv_data_retn:
  1033 00009AD2 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1034 00009AD7 C3                  <1> 	retn
  1035                              <1> 
  1036                              <1> loc_save_fat_buff_remain_sectors_3:
  1037 00009AD8 B903000000          <1> 	mov	ecx, 3
  1038 00009ADD EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1039                              <1> 
  1040                              <1> loc_save_fat_buffer_check_rs3:
  1041 00009ADF 83F903              <1> 	cmp	ecx, 3
  1042 00009AE2 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1043                              <1> 
  1044                              <1> loc_save_fat_buff_continue:
  1045 00009AE4 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1046 00009AE9 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1047 00009AEC 51                  <1> 	push	ecx
  1048 00009AED E88A1F0000          <1> 	call	disk_write
  1049 00009AF2 59                  <1> 	pop	ecx
  1050 00009AF3 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1051                              <1> 	
  1052 00009AF5 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1053 00009AF9 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1054                              <1> 
  1055                              <1> loc_calc_2nd_fat32_addr:
  1056 00009AFB 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1057 00009AFE EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1058                              <1> 
  1059                              <1> loc_calc_2nd_fat12_16_addr:
  1060 00009B00 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1061                              <1> 
  1062                              <1> loc_calc_2nd_fat_addr:
  1063 00009B04 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1064 00009B07 0305[BDD70000]      <1> 	add	eax, [FAT_BuffSector]
  1065 00009B0D BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1066                              <1> 	; ecx = 1 to 3
  1067 00009B12 E8651F0000          <1> 	call	disk_write
  1068 00009B17 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1069                              <1>  	; Valid  buffer (1 = valid but do not save)
  1070 00009B19 C605[B9D70000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1071                              <1> 
  1072                              <1> loc_save_FAT_buff_write_err:
  1073 00009B20 5E                  <1> 	pop	esi ; *
  1074 00009B21 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1075                              <1> 	; 23/03/2016
  1076 00009B26 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
  1077 00009B2B C3                  <1> 	retn
  1078                              <1> 
  1079                              <1> calculate_fat_freespace:
  1080                              <1> 	; 23/03/2016
  1081                              <1> 	; 02/03/2016
  1082                              <1> 	; 01/03/2016
  1083                              <1> 	; 29/02/2016
  1084                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1085                              <1> 	; 30/04/2011
  1086                              <1> 	; 03/04/2010
  1087                              <1> 	; 2005
  1088                              <1> 	; INPUT ->
  1089                              <1> 	;	EAX = Cluster count to be added or subtracted
  1090                              <1> 	; 	If BH = FFh, ESI = TR-DOS Logical Drive Description Table
  1091                              <1> 	; 	If BH < FFh, BH = TR-DOS Logical Drive Number
  1092                              <1> 	; 	BL: 
  1093                              <1> 	;	0 = Calculate, 1 = Add, 2 = Subtract, 3 = Get (Not Set/Calc)
  1094                              <1> 	; OUTPUT ->
  1095                              <1> 	;	EAX = Free Space in sectors
  1096                              <1> 	;	ESI = Logical Dos Drive Description Table address
  1097                              <1> 	;	BH = Logical Dos Drive Number (same with input value of BH)
  1098                              <1> 	;	BL = Type of operation (same with input value of BL)
  1099                              <1> 	;	ECX = 0 -> valid
  1100                              <1> 	;	ECX > 0 -> error or invalid
  1101                              <1> 	;	If EAX = FFFFFFFFh, it is 're-calculation needed'
  1102                              <1> 	;			          sign due to r/w error   
  1103                              <1> 
  1104 00009B2C 66891D[5EDA0000]    <1> 	mov	[CFS_OPType], bx
  1105 00009B33 A3[60DA0000]        <1> 	mov	[CFS_CC], eax
  1106                              <1> 	
  1107 00009B38 80FFFF              <1> 	cmp	bh, 0FFh
  1108 00009B3B 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1109                              <1> 
  1110                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1111 00009B3D 31C0                <1> 	xor	eax, eax
  1112 00009B3F 88FC                <1>         mov     ah, bh
  1113 00009B41 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1114 00009B46 01C6                <1>         add     esi, eax
  1115                              <1> 
  1116                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1117 00009B48 08DB                <1> 	or	bl, bl
  1118 00009B4A 7435                <1> 	jz	short loc_reset_fcc
  1119                              <1> 	
  1120                              <1> loc_get_free_sectors:
  1121 00009B4C 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1122                              <1> 
  1123                              <1> 	;xor	ecx, ecx
  1124                              <1> 	;dec	ecx ; 0FFFFFFFFh
  1125                              <1> 	;cmp	eax, ecx ; 29/02/2016
  1126                              <1> 	;je	short loc_get_free_sectors_retn ; recalculation is needed!
  1127                              <1> 	
  1128                              <1> 	; 23/03/2016
  1129 00009B4F 8B4E70              <1> 	mov	ecx, [esi+LD_TotalSectors]
  1130 00009B52 39C1                <1> 	cmp	ecx, eax ; Total sectors must be greater than Free sectors !
  1131 00009B54 7707                <1> 	ja	short loc_get_free_sectors_check_optype
  1132                              <1> 	
  1133 00009B56 31C0                <1> 	xor	eax, eax
  1134 00009B58 48                  <1> 	dec	eax ; 0FFFFFFFFh  ; recalculation is needed!
  1135 00009B59 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; reset (for recalculation)
  1136                              <1> 		
  1137                              <1> loc_get_free_sectors_retn:
  1138 00009B5C C3                  <1> 	retn
  1139                              <1> 	
  1140                              <1> loc_get_free_sectors_check_optype:
  1141 00009B5D 80FB03              <1> 	cmp	bl, 3
  1142 00009B60 7203                <1> 	jb	short loc_set_fcc
  1143                              <1> 
  1144 00009B62 29C9                <1> 	sub	ecx, ecx ; 0
  1145                              <1> 
  1146 00009B64 C3                  <1> 	retn	
  1147                              <1> 
  1148                              <1> loc_set_fcc:
  1149 00009B65 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1150 00009B69 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1151                              <1> 
  1152                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1153 00009B6F 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1154 00009B73 29D2                <1> 	sub	edx, edx
  1155 00009B75 F7F1                <1> 	div	ecx
  1156                              <1> 	;or	dx, dx 
  1157                              <1> 	;	; DX -> Remain sectors < SecPerClust
  1158                              <1> 	;	; DX > 0 -> invalid free sector count
  1159                              <1> 	;jnz	short loc_reset_fcc 
  1160                              <1> 
  1161                              <1> ;pass_set_fcc_div32:
  1162 00009B77 A3[D7D70000]        <1> 	mov	[FreeClusterCount], eax
  1163 00009B7C E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1164                              <1> 
  1165                              <1> loc_reset_fcc:
  1166 00009B81 31C0                <1> 	xor	eax, eax
  1167 00009B83 A3[D7D70000]        <1> 	mov	[FreeClusterCount], eax ; 0
  1168 00009B88 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1169 00009B8B 42                  <1> 	inc	edx
  1170 00009B8C 8915[C5D70000]      <1> 	mov	[LastCluster], edx
  1171                              <1> 
  1172 00009B92 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1173 00009B96 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1174                              <1> 
  1175 00009B98 48                  <1> 	dec	eax ; FFFFFFFFh
  1176 00009B99 A3[68DA0000]        <1> 	mov	[CFS_FAT32FC], eax
  1177                              <1> 
  1178                              <1> 	; 29/02/2016
  1179 00009B9E 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1180 00009BA1 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1181                              <1> 	
  1182 00009BA4 B802000000          <1> 	mov 	eax, 2
  1183                              <1> 
  1184                              <1> loc_count_fc_next_cluster_0:
  1185 00009BA9 50                  <1> 	push	eax
  1186 00009BAA E801F9FFFF          <1> 	call	get_next_cluster
  1187 00009BAF 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1188 00009BB1 09C0                <1> 	or	eax, eax
  1189 00009BB3 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1190                              <1> 
  1191                              <1> loc_put_fcc_unknown_sign:
  1192 00009BB5 58                  <1> 	pop	eax
  1193                              <1> 	; "Free count is Unknown" sign
  1194                              <1> 	;mov	dword [FreeClusterCount], 0FFFFFFFFh
  1195                              <1> 
  1196                              <1> 	; 29/02/2016
  1197                              <1> 	; Save Free Cluster Count value in FAT32 'BPB_Reserved' area
  1198                              <1> 	;mov	[esi+LD_BPB+BPB_Reserved], 0FFFFFFFFh ; unknown!
  1199 00009BB6 8B15[68DA0000]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1200                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1201 00009BBC 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1202                              <1> 	
  1203 00009BBF EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1204                              <1> 
  1205                              <1> loc_check_fat32_ff_cluster:
  1206 00009BC1 09C0                <1> 	or	eax, eax
  1207 00009BC3 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1208 00009BC5 58                  <1> 	pop	eax
  1209 00009BC6 A3[68DA0000]        <1> 	mov	[CFS_FAT32FC], eax
  1210                              <1> 	;mov	dword [FreeClusterCount], 1
  1211 00009BCB FF05[D7D70000]      <1> 	inc	dword [FreeClusterCount]
  1212 00009BD1 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1213                              <1> 
  1214                              <1> pass_inc_cfs_fcc_0:
  1215 00009BD3 58                  <1> 	pop	eax
  1216                              <1> 
  1217                              <1> pass_inc_cfs_fcc_0c:
  1218 00009BD4 40                  <1> 	inc	eax ; add eax, 1
  1219 00009BD5 3B05[C5D70000]      <1> 	cmp	eax, [LastCluster]
  1220 00009BDB 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1221 00009BDD EB6F                <1> 	jmp	short loc_update_FAT32_fs_info_fcc
  1222                              <1> 
  1223                              <1> loc_count_free_fat_clusters_0:
  1224                              <1> 	;mov	eax, 2
  1225 00009BDF B002                <1> 	mov	al, 2
  1226                              <1> 
  1227                              <1> loc_count_fc_next_cluster:
  1228 00009BE1 50                  <1> 	push	eax
  1229 00009BE2 E8C9F8FFFF          <1> 	call	get_next_cluster
  1230 00009BE7 720C                <1> 	jc	short loc_count_fcc_stc
  1231                              <1> 
  1232                              <1> loc_count_free_clusters_1:
  1233 00009BE9 21C0                <1> 	and	eax, eax
  1234 00009BEB 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1235                              <1> 
  1236 00009BED FF05[D7D70000]      <1> 	inc	dword [FreeClusterCount]
  1237 00009BF3 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1238                              <1> 
  1239                              <1> loc_count_fcc_stc:
  1240 00009BF5 09C0                <1> 	or	eax, eax
  1241 00009BF7 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1242                              <1> 
  1243                              <1> pass_inc_cfs_fcc:
  1244 00009BF9 58                  <1> 	pop	eax
  1245                              <1> 
  1246                              <1> pass_inc_cfs_fcc_1:
  1247 00009BFA 40                  <1> 	inc	eax ; add eax, 1
  1248 00009BFB 3B05[C5D70000]      <1> 	cmp	eax, [LastCluster]
  1249 00009C01 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1250                              <1> 
  1251                              <1> loc_set_free_sectors:
  1252 00009C03 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1253 00009C07 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1254                              <1> 
  1255                              <1> loc_set_free_sectors_FAT12_FAT16:
  1256 00009C09 803D[5EDA0000]00    <1> 	cmp	byte [CFS_OPType], 0
  1257 00009C10 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1258 00009C12 A1[60DA0000]        <1> 	mov	eax, [CFS_CC]
  1259 00009C17 803D[5EDA0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1260 00009C1E 7708                <1> 	ja	short pass_FAT_add_fcc
  1261 00009C20 0105[D7D70000]      <1> 	add 	[FreeClusterCount], eax
  1262 00009C26 EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1263                              <1> 
  1264                              <1> pass_FAT_add_fcc:
  1265 00009C28 2905[D7D70000]      <1> 	sub	[FreeClusterCount], eax
  1266                              <1> 
  1267                              <1> pass_FAT_add_sub_fcc:
  1268 00009C2E 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1269 00009C32 8B15[D7D70000]      <1> 	mov	edx, [FreeClusterCount]
  1270 00009C38 F7E2                <1> 	mul	edx
  1271                              <1> 
  1272 00009C3A 31C9                <1> 	xor	ecx, ecx 
  1273 00009C3C EB05                <1> 	jmp	short loc_cfs_retn_params
  1274                              <1> 
  1275                              <1> loc_put_fcc_invalid_sign:
  1276 00009C3E 29C0                <1>        	sub	eax, eax ; 0
  1277 00009C40 48                  <1> 	dec	eax ; FFFFFFFFh
  1278                              <1> loc_fat32_ffc_recalc_needed:
  1279 00009C41 89C1                <1> 	mov	ecx, eax
  1280                              <1> 
  1281                              <1> loc_cfs_retn_params:
  1282 00009C43 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1283 00009C46 0FB71D[5EDA0000]    <1> 	movzx	ebx, word [CFS_OPType]
  1284 00009C4D C3                  <1> 	retn
  1285                              <1> 
  1286                              <1> loc_update_FAT32_fs_info_fcc:
  1287                              <1> loc_check_fcc_FSINFO_op:
  1288                              <1> 	; 29/02/2016
  1289                              <1> 	; EAX = Free cluster count (before this update) ; value from disk
  1290                              <1> 	; EDX = First Free Cluster (before this update) ; value from disk
  1291 00009C4E 803D[5EDA0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1292 00009C55 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1293 00009C57 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1294                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1295 00009C59 F71D[60DA0000]      <1> 	neg	dword [CFS_CC] ; prepare to subtract ; 2 = sub (add negative)
  1296                              <1> loc_check_fcc_FSINFO_op1:
  1297                              <1> 	; 01/03/2016
  1298 00009C5F 31D2                <1> 	xor	edx, edx ; 0
  1299 00009C61 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1300 00009C62 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1301 00009C65 39D0                <1> 	cmp	eax, edx
  1302 00009C67 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1303 00009C69 0305[60DA0000]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1304 00009C6F 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1305                              <1> 	
  1306 00009C71 A3[D7D70000]        <1> 	mov	[FreeClusterCount], eax
  1307 00009C76 EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1308                              <1> 
  1309                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1310 00009C78 8B15[68DA0000]      <1> 	mov	edx, [CFS_FAT32FC]
  1311 00009C7E A1[D7D70000]        <1> 	mov	eax, [FreeClusterCount]
  1312 00009C83 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1313                              <1> loc_cfs_write_FSINFO_sector:
  1314 00009C86 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1315                              <1> 	; 01/03/2016
  1316 00009C89 E89A000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1317 00009C8E 72AE                <1>         jc      short loc_put_fcc_invalid_sign
  1318                              <1> 
  1319                              <1> loc_set_FAT32_free_sectors:
  1320                              <1> 	; 29/02/2016
  1321                              <1> 	;mov	eax, [FreeClusterCount]
  1322                              <1> 	;mov	ecx, eax
  1323                              <1> 	;cmp	eax, 0FFFFFFFFh ; Invalid !
  1324                              <1> 	;je	short loc_cfs_retn_params
  1325                              <1> 	;
  1326 00009C90 8B0D[D7D70000]      <1> 	mov	ecx, [FreeClusterCount]
  1327 00009C96 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1328 00009C9A F7E1                <1> 	mul	ecx
  1329                              <1> 	; 29/02/2016
  1330 00009C9C 31C9                <1> 	xor	ecx, ecx ; 0
  1331 00009C9E 09D2                <1> 	or	edx, edx ; 0 ?
  1332 00009CA0 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1333 00009CA2 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1334 00009CA5 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1335                              <1> 	;
  1336                              <1> loc_set_FAT32_free_sectors_ok:
  1337 00009CA7 31D2                <1> 	xor	edx, edx ; 0
  1338 00009CA9 EB98                <1>         jmp     short loc_cfs_retn_params 
  1339                              <1> 	;
  1340                              <1> 
  1341                              <1> get_last_cluster:
  1342                              <1> 	; 27/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1343                              <1> 	; 12/06/2010 (DRV_FAT.ASM, 'proc_get_last_custer')
  1344                              <1> 	; 06/06/2010
  1345                              <1> 	; INPUT ->
  1346                              <1> 	;	EAX = First Cluster Number
  1347                              <1> 	; 	ESI = Logical Dos Drive Parameters Table
  1348                              <1> 	; OUTPUT ->
  1349                              <1> 	;	cf = 0 -> No Error, EAX is valid
  1350                              <1> 	;	cf = 1 -> EAX > 0 -> Error
  1351                              <1> 	;	EAX = Last Cluster Number
  1352                              <1> 	;       ECX = Previous Cluster -just before the last cluster-
  1353                              <1> 	;
  1354                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1355                              <1> 
  1356 00009CAB 89C1                <1> 	mov	ecx, eax	
  1357                              <1> 
  1358                              <1> loc_glc_get_next_cluster_1:
  1359 00009CAD 890D[6CDA0000]      <1> 	mov	[glc_prevcluster], ecx
  1360                              <1> 
  1361                              <1> loc_glc_get_next_cluster_2:
  1362 00009CB3 E8F8F7FFFF          <1> 	call	get_next_cluster
  1363                              <1> 	; ecx = current/previous cluster 
  1364                              <1> 	; eax = next/last cluster
  1365 00009CB8 73F3                <1> 	jnc	short loc_glc_get_next_cluster_1
  1366                              <1> 
  1367 00009CBA 09C0                <1> 	or	eax, eax
  1368 00009CBC 7509                <1> 	jnz	short loc_glc_stc_retn
  1369                              <1> 
  1370                              <1> 	; ecx = previous cluster
  1371 00009CBE 89C8                <1>         mov	eax, ecx
  1372                              <1> 
  1373                              <1> 	; previous cluster becomes last cluster (ecx -> eax)
  1374                              <1> 	; previous of previous cluster becomes previous cluster (ecx)
  1375                              <1> 
  1376                              <1> loc_glc_prev_cluster_retn:
  1377 00009CC0 8B0D[6CDA0000]      <1> 	mov	ecx, [glc_prevcluster] 
  1378 00009CC6 C3                  <1> 	retn
  1379                              <1> 
  1380                              <1> loc_glc_stc_retn:
  1381 00009CC7 F5                  <1> 	cmc	;stc
  1382 00009CC8 EBF6                <1>         jmp	short loc_glc_prev_cluster_retn
  1383                              <1> 
  1384                              <1> truncate_cluster_chain:
  1385                              <1> 	; 01/03/2016
  1386                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1387                              <1> 	; 22/01/2011 (DRV_FAT.ASM, 'proc_truncate_cluster_chain')
  1388                              <1> 	; 11/09/2010
  1389                              <1> 	; INPUT ->
  1390                              <1> 	;	ESI = Logical dos drive description table address
  1391                              <1> 	;	EAX = First cluster to be truncated/unlinked 
  1392                              <1> 	; OUTPUT ->
  1393                              <1> 	;	ESI = Logical dos drive description table address
  1394                              <1> 	; 	ECX = Count of truncated/removed clusters
  1395                              <1> 	; 	CF = 0 -> EAX = Free sectors
  1396                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1397                              <1> 
  1398                              <1> 	; NOTE: This procedure does not update lm date&time ! 
  1399                              <1> 
  1400                              <1> loc_truncate_cc:	
  1401 00009CCA 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1402                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1403 00009CCC 890D[C1D70000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1404                              <1> 
  1405                              <1> loc_tcc_unlink_clusters:
  1406 00009CD2 E803FBFFFF          <1> 	call	update_cluster
  1407                              <1> 	; EAX = Next Cluster
  1408                              <1> 	; ECX = Cluster Value
  1409                              <1> 	; Note:
  1410                              <1> 	; Returns count of unlinked clusters in
  1411                              <1> 	; dword ptr FAT_ClusterCounter
  1412 00009CD7 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1413                              <1> 
  1414                              <1> pass_tcc_unlink_clusters:
  1415 00009CD9 A2[73DA0000]        <1> 	mov	byte [TCC_FATErr], al
  1416 00009CDE 803D[B9D70000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1417 00009CE5 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1418 00009CE7 E8ABFDFFFF          <1> 	call	save_fat_buffer
  1419 00009CEC 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1420 00009CEE A2[73DA0000]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1421                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1422                              <1> 
  1423                              <1> 	; 01/03/2016
  1424 00009CF3 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1425                              <1> 
  1426                              <1> loc_tcc_calculate_FAT_freespace:
  1427 00009CF5 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1428 00009CFA 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1429                              <1> 			   ; BL = 1 -> add cluster
  1430 00009CFE E829FEFFFF          <1> 	call	calculate_fat_freespace
  1431 00009D03 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1432 00009D05 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1433                              <1> 
  1434                              <1> loc_tcc_recalculate_FAT_freespace:
  1435 00009D07 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1436 00009D0B E81CFEFFFF          <1> 	call	calculate_fat_freespace
  1437                              <1>               
  1438                              <1> loc_tcc_calculate_FAT_freespace_err:
  1439                              <1> pass_truncate_cc_recalc_FAT_freespace:
  1440 00009D10 8B0D[C1D70000]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1441                              <1> 
  1442 00009D16 803D[73DA0000]00    <1> 	cmp	byte [TCC_FATErr], 0
  1443 00009D1D 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1444                              <1> 
  1445                              <1> loc_tcc_unlink_clusters_error:
  1446 00009D1F 0FB605[73DA0000]    <1> 	movzx	eax, byte [TCC_FATErr]
  1447 00009D26 F9                  <1> 	stc
  1448                              <1> loc_tcc_unlink_clusters_retn:
  1449 00009D27 C3                  <1> 	retn
  1450                              <1> 
  1451                              <1> set_fat32_fsinfo_sector_parms:
  1452                              <1> 	; 23/03/2016
  1453                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1454                              <1> 	; INPUT ->
  1455                              <1> 	;	ESI = Logical dos drive description table address
  1456                              <1> 	;	[esi+LD_BPB+BPB_Reserved] = Free Cluster Count
  1457                              <1> 	;	[esi+LD_BPB+BPB_Reserved+4] = First Free Cluster 
  1458                              <1> 	; OUTPUT ->
  1459                              <1> 	;	ESI = Logical dos drive description table address
  1460                              <1> 	; 	CF = 0 -> OK..
  1461                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1462                              <1> 	;
  1463                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1464                              <1> 
  1465 00009D28 E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1466 00009D2D 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1467                              <1> 
  1468 00009D2F 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1469 00009D32 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1470                              <1> 
  1471                              <1>         ;mov	ebx, DOSBootSectorBuff
  1472 00009D35 8983E8010000        <1> 	mov	[ebx+488], eax
  1473 00009D3B 8993EC010000        <1> 	mov	[ebx+492], edx	
  1474                              <1> 
  1475 00009D41 A1[64DA0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1476 00009D46 B901000000          <1> 	mov	ecx, 1
  1477 00009D4B E82C1D0000          <1> 	call	disk_write
  1478                              <1> 	;jnc     short update_fat32_fsinfo_sector_retn
  1479                              <1> 
  1480                              <1> 	; 23/03/2016
  1481                              <1> 	;mov	eax, 1Dh ; Drive not ready or write error
  1482                              <1> 
  1483                              <1> update_fat32_fsinfo_sector_retn:
  1484 00009D50 C3                  <1> 	retn
  1485                              <1> 
  1486                              <1> get_fat32_fsinfo_sector_parms:
  1487                              <1> 	; 23/03/2016
  1488                              <1> 	; 01/03/2016
  1489                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1490                              <1> 	; INPUT ->
  1491                              <1> 	;	ESI = Logical dos drive description table address
  1492                              <1> 	; OUTPUT ->
  1493                              <1> 	;	ESI = Logical dos drive description table address
  1494                              <1> 	;	EBX = FSINFO sector buffer address (DOSBootSectorBuff)	
  1495                              <1> 	;	CF = 0 -> OK..
  1496                              <1> 	;	   EAX = FsInfo sector address
  1497                              <1> 	;	   ECX = Free cluster count
  1498                              <1> 	;	   EDX = First free cluster 	
  1499                              <1> 	;	CF = 1 -> Error code in AL (EAX)
  1500                              <1> 	;	   EBX = 0
  1501                              <1> 	;	
  1502                              <1> 	;	[CFS_FAT32FSINFOSEC] = FAT32 FSINFO sector address
  1503                              <1>         ;
  1504                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1505                              <1> 
  1506 00009D51 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1507 00009D55 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1508 00009D58 A3[64DA0000]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1509                              <1> 	
  1510 00009D5D BB[B5D50000]        <1>         mov     ebx, DOSBootSectorBuff
  1511 00009D62 B901000000          <1> 	mov	ecx, 1
  1512 00009D67 E81F1D0000          <1> 	call	disk_read
  1513 00009D6C 7232                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1514                              <1> 
  1515 00009D6E BB[B5D50000]        <1> 	mov	ebx, DOSBootSectorBuff
  1516                              <1> 
  1517 00009D73 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1518 00009D79 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1519                              <1> 
  1520 00009D7B 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1520 00009D84 61                  <1>
  1521 00009D85 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1522                              <1> 
  1523 00009D87 A1[64DA0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1524 00009D8C 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1525 00009D92 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1526                              <1> 
  1527 00009D98 C3                  <1> 	retn
  1528                              <1> 
  1529                              <1> loc_read_FAT32_fsinfo_sec_stc:
  1530 00009D99 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format!
  1531 00009D9E EB05                <1> 	jmp	short loc_read_FAT32_fsinfo_sec_stc_retn
  1532                              <1> 
  1533                              <1> loc_read_FAT32_fsinfo_sec_err:
  1534                              <1> 	; 23/03/2016
  1535 00009DA0 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
  1536                              <1> 
  1537                              <1> loc_read_FAT32_fsinfo_sec_stc_retn:
  1538 00009DA5 29DB                <1> 	sub	ebx, ebx ; 0
  1539 00009DA7 F9                  <1> 	stc
  1540 00009DA8 C3                  <1> 	retn
  1541                              <1> 
  1542                              <1> add_new_cluster:
  1543                              <1> 	; 24/03/2016
  1544                              <1> 	; 18/03/2016
  1545                              <1> 	; 11/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1546                              <1> 	; 30/07/2011 (DRV_FAT.ASM)
  1547                              <1> 	; 11/09/2010
  1548                              <1> 	; INPUT ->
  1549                              <1> 	;	ESI = Logical dos drv desc. table address
  1550                              <1> 	;	EAX = Last cluster
  1551                              <1> 	; OUTPUT ->
  1552                              <1> 	;	ESI = Logical dos drv desc. table address
  1553                              <1> 	;	EAX = New Last cluster (next cluster)
  1554                              <1> 	;	cf = 1 -> error code in EAX (AL)
  1555                              <1> 	;	cf = 1 -> DX = sectors per cluster
  1556                              <1> 	;	ECX = Free sectors
  1557                              <1> 	; NOTE:
  1558                              <1> 	; This procedure does not update lm date&time !
  1559                              <1> 	;
  1560                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, EDI)
  1561                              <1> 	;
  1562                              <1> 
  1563 00009DA9 A3[90DB0000]        <1> 	mov	[FAT_anc_LCluster], eax
  1564                              <1> 	
  1565 00009DAE E854F9FFFF          <1> 	call	get_first_free_cluster
  1566 00009DB3 720B                <1> 	jc	short loc_add_new_cluster_retn
  1567                              <1> 	; EAX >= 2 and EAX < FFFFFFFFh is valid
  1568                              <1> 
  1569 00009DB5 89C2                <1> 	mov	edx, eax
  1570                              <1> 
  1571 00009DB7 42                  <1> 	inc	edx
  1572                              <1> 	;jnz	short loc_add_new_cluster_check_ffc_eax
  1573 00009DB8 7516                <1> 	jnz	short loc_add_new_cluster_save_fcc
  1574                              <1> 
  1575                              <1> loc_add_new_cluster_no_disk_space_retn:
  1576 00009DBA B827000000          <1> 	mov	eax, 27h ; MSDOS err => insufficient disk space
  1577                              <1> loc_add_new_cluster_stc_retn:
  1578 00009DBF F9                  <1> 	stc
  1579                              <1> loc_add_new_cluster_retn:
  1580 00009DC0 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1581 00009DC4 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1582                              <1> 	;xor	edx, edx
  1583                              <1> 	;stc
  1584 00009DC7 C3                  <1> 	retn
  1585                              <1> 
  1586                              <1> loc_anc_invalid_format_stc_retn:
  1587 00009DC8 F9                  <1> 	stc
  1588                              <1> loc_add_new_cluster_invalid_format_retn:
  1589 00009DC9 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  1590 00009DCE EBF0                <1> 	jmp	short loc_add_new_cluster_retn 
  1591                              <1> 
  1592                              <1> ;loc_add_new_cluster_check_ffc_eax:
  1593                              <1> ;	cmp	eax, 2
  1594                              <1> ;	jb	short loc_add_new_cluster_invalid_format_retn
  1595                              <1> 
  1596                              <1> loc_add_new_cluster_save_fcc:  
  1597 00009DD0 A3[94DB0000]        <1> 	mov	[FAT_anc_FFCluster], eax
  1598                              <1> 
  1599 00009DD5 83E802              <1> 	sub	eax, 2
  1600 00009DD8 0FB65E13            <1>         movzx   ebx, byte [esi+LD_BPB+SecPerClust]
  1601 00009DDC F7E3                <1> 	mul	ebx
  1602 00009DDE 09D2                <1> 	or	edx, edx
  1603 00009DE0 75E6                <1> 	jnz	short loc_anc_invalid_format_stc_retn
  1604                              <1> 
  1605                              <1> loc_add_new_cluster_allocate_cluster:
  1606                              <1> 	; 18/03/2016
  1607 00009DE2 92                  <1> 	xchg	edx, eax ; eax = 0
  1608 00009DE3 3805[C9D70000]      <1> 	cmp	[ClusterBuffer_Valid], al ; 0
  1609 00009DE9 7607                <1> 	jna	short loc_anc_clear_cluster_buffer
  1610                              <1> 	; 'copy' command, 
  1611                              <1> 	; writing destination file clust after reading source file clust
  1612 00009DEB A2[C9D70000]        <1> 	mov	[ClusterBuffer_Valid], al ; 0 ; reset
  1613 00009DF0 EB0C                <1> 	jmp	short loc_add_new_cluster_write_nc_to_disk
  1614                              <1> 
  1615                              <1> loc_anc_clear_cluster_buffer:
  1616                              <1> 	; 11/03/2016
  1617                              <1> 	; Clear buffer
  1618 00009DF2 BF00000700          <1> 	mov	edi, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  1619 00009DF7 89D9                <1> 	mov	ecx, ebx ; sector count
  1620 00009DF9 C1E107              <1> 	shl	ecx, 7 ; 1 sector = 512 bytes -> 128 double words
  1621                              <1> 	;xor	eax, eax ; 0
  1622 00009DFC F3AB                <1> 	rep	stosd
  1623                              <1> 
  1624                              <1> loc_add_new_cluster_write_nc_to_disk:
  1625                              <1> 	; 11/03/2016
  1626                              <1> 	;xchg	eax, edx ; edx = 0, eax = sector offset
  1627 00009DFE 89D0                <1> 	mov	eax, edx
  1628 00009E00 034668              <1>         add     eax, [esi+LD_DATABegin]
  1629 00009E03 72C4                <1> 	jc	short loc_add_new_cluster_invalid_format_retn 
  1630                              <1> 		
  1631 00009E05 89D9                <1> 	mov	ecx, ebx ; ECX = sectors per cluster (<256)
  1632 00009E07 BB00000700          <1> 	mov	ebx, Cluster_Buffer
  1633 00009E0C E86B1C0000          <1> 	call	disk_write
  1634 00009E11 7307                <1> 	jnc	short loc_add_new_cluster_update_fat_nlc
  1635                              <1> 	
  1636 00009E13 B81D000000          <1> 	mov	eax, 1Dh ; Write Error
  1637 00009E18 EBA5                <1> 	jmp	short loc_add_new_cluster_stc_retn
  1638                              <1> 
  1639                              <1> loc_add_new_cluster_update_fat_nlc:
  1640 00009E1A A1[94DB0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1641 00009E1F 31C9                <1> 	xor	ecx, ecx
  1642 00009E21 890D[C1D70000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1643 00009E27 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1644 00009E28 E8ADF9FFFF          <1> 	call	update_cluster
  1645 00009E2D 7304                <1> 	jnc	short loc_add_new_cluster_update_fat_plc
  1646 00009E2F 09C0                <1> 	or	eax, eax ;EAX = 0 -> cluster value is 0 or eocc
  1647 00009E31 758C                <1> 	jnz	short loc_add_new_cluster_stc_retn
  1648                              <1> 
  1649                              <1> loc_add_new_cluster_update_fat_plc:
  1650 00009E33 A1[90DB0000]        <1> 	mov	eax, [FAT_anc_LCluster]
  1651 00009E38 8B0D[94DB0000]      <1> 	mov	ecx, [FAT_anc_FFCluster]
  1652 00009E3E E897F9FFFF          <1> 	call	update_cluster
  1653 00009E43 7314                <1> 	jnc	short loc_add_new_cluster_save_fat_buffer
  1654 00009E45 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1655 00009E47 7410                <1> 	jz	short loc_add_new_cluster_save_fat_buffer
  1656                              <1> 
  1657                              <1> loc_anc_save_fat_buffer_err_retn:
  1658                              <1> 	;cmp	byte [FAT_ClusterCounter], 1
  1659                              <1> 	;jb	short loc_add_new_cluster_retn
  1660                              <1> 
  1661 00009E49 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 00009E4D 50                  <1> 	push	eax
  1664 00009E4E E8D9FCFFFF          <1> 	call	calculate_fat_freespace
  1665 00009E53 58                  <1> 	pop	eax
  1666 00009E54 E966FFFFFF          <1>         jmp     loc_add_new_cluster_stc_retn
  1667                              <1> 
  1668                              <1> loc_add_new_cluster_save_fat_buffer:
  1669                              <1> 	;cmp	byte [FAT_BuffValidData], 2
  1670                              <1> 	;jne	short loc_add_new_cluster_calc_FAT_freespace 
  1671                              <1> 	;Byte [FAT_BuffValidData] =  2 
  1672 00009E59 E839FCFFFF          <1> 	call	save_fat_buffer
  1673 00009E5E 72E9                <1> 	jc	short loc_anc_save_fat_buffer_err_retn
  1674                              <1> 
  1675                              <1> loc_add_new_cluster_calc_FAT_freespace:
  1676                              <1> 	;mov	eax, 1 ; Only one Cluster
  1677 00009E60 A1[C1D70000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1678 00009E65 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI -> Dos drv desc. table
  1679                              <1> 		; BL = 1 -> add cluster
  1680 00009E69 B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  1681                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  1682                              <1> 	; (Free Cluster Count is decreased when EAX value is negative)
  1683 00009E6B E8BCFCFFFF          <1>         call    calculate_fat_freespace
  1684                              <1> 	;ECX = 0 -> no error, ECX > 0 -> error or invalid return
  1685 00009E70 21C9                <1> 	and	ecx, ecx ; ECX = 0 -> valid free sector count
  1686 00009E72 7409                <1> 	jz	short loc_add_new_cluster_return_cluster_number
  1687                              <1> 
  1688                              <1> loc_add_new_cluster_recalc_FAT_freespace:
  1689 00009E74 66BB00FF            <1> 	mov	bx, 0FF00h  ; recalculate free space
  1690 00009E78 E8AFFCFFFF          <1>         call    calculate_fat_freespace
  1691                              <1> 	; cf = 0
  1692                              <1> loc_add_new_cluster_return_cluster_number:
  1693 00009E7D 89C1                <1> 	mov	ecx, eax ; Free sector count
  1694 00009E7F A1[94DB0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1695 00009E84 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1696                              <1> 	;mov	edi, Cluster_Buffer
  1697 00009E88 31D2                <1> 	xor	edx, edx
  1698 00009E8A C3                  <1>         retn
  1699                              <1> 
  1700                              <1> write_cluster:
  1701                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1702                              <1> 	;
  1703                              <1> 	; INPUT ->
  1704                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
  1705                              <1> 	;	ESI = Logical DOS Drive Description Table address
  1706                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
  1707                              <1> 	;	Only for SINGLIX FS:
  1708                              <1> 	;	EDX = File Number (The 1st FDT address) 
  1709                              <1> 	; OUTPUT ->
  1710                              <1> 	;	cf = 1 -> Cluster can not be written onto disk
  1711                              <1> 	;	    EAX > 0 -> Error number
  1712                              <1> 	;	cf = 0 -> Cluster has been written successfully
  1713                              <1> 	;
  1714                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1715                              <1> 	
  1716 00009E8B 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
  1717                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  1718                              <1> 
  1719                              <1> write_file_sectors: ; 16/03/2016
  1720 00009E8F 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  1721 00009E93 761C                <1> 	jna	short write_fs_cluster
  1722                              <1> 
  1723                              <1> write_fat_file_sectors: 
  1724 00009E95 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
  1725 00009E98 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
  1726 00009E9C F7E2                <1> 	mul	edx
  1727 00009E9E 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
  1728                              <1> 
  1729                              <1> 	; EAX = Disk sector address
  1730                              <1> 	; ECX = Sector count
  1731                              <1> 	; EBX = Buffer address
  1732                              <1> 	; (EDX = 0)
  1733                              <1> 	; ESI = Logical DOS drive description table address	
  1734                              <1> 
  1735 00009EA1 E8D61B0000          <1> 	call	disk_write
  1736 00009EA6 7306                <1> 	jnc	short wclust_retn
  1737                              <1> 	
  1738 00009EA8 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  1739 00009EAD C3                  <1> 	retn
  1740                              <1> 
  1741                              <1> wclust_retn:
  1742 00009EAE 29C0                <1> 	sub	eax, eax ; 0
  1743 00009EB0 C3                  <1> 	retn
  1744                              <1> 
  1745                              <1> write_fs_cluster:
  1746                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1747                              <1> 	; Singlix FS
  1748                              <1> 	
  1749                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
  1750                              <1> 	
  1751                              <1> 	; EDX = File number is the first File Descriptor Table address 
  1752                              <1> 	;	of the file. (Absolute address of the FDT).
  1753                              <1> 	
  1754                              <1> 	; eax = sector index (0 for the first sector)
  1755                              <1> 	; edx = FDT0 address
  1756                              <1> 		; 64 KB buffer = 128 sectors (limit) 
  1757 00009EB1 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
  1758 00009EB6 E801000000          <1> 	call	write_fs_sectors
  1759 00009EBB C3                  <1> 	retn
  1760                              <1> 
  1761                              <1> write_fs_sectors:
  1762                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1763 00009EBC F9                  <1> 	stc
  1764 00009EBD C3                  <1> 	retn
  1765                              <1> 
  1766                              <1> get_cluster_by_index:
  1767                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1768                              <1> 	; INPUT ->
  1769                              <1> 	; 	EAX = Beginning cluster
  1770                              <1> 	; 	EDX = Sector index in disk/file section
  1771                              <1> 	;	      (Only for SINGLIX file system!)
  1772                              <1> 	; 	ECX = Cluster sequence number after the beginning cluster
  1773                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1774                              <1> 	; OUTPUT ->
  1775                              <1> 	;	EAX = Cluster number 
  1776                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1777                              <1> 	;
  1778                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1779                              <1> 	;	
  1780 00009EBE 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1781 00009EC2 721E                <1>         jb      get_fs_section_by_index 
  1782                              <1> 
  1783 00009EC4 3B4E78              <1> 	cmp	ecx, [esi+LD_Clusters]
  1784 00009EC7 7207                <1> 	jb	short gcbi_1
  1785                              <1> gcbi_0:
  1786 00009EC9 F9                  <1> 	stc
  1787 00009ECA B823000000          <1> 	mov	eax, 23h ; Cluster not available ! 
  1788                              <1> 			 ; MSDOS error code: FCB unavailable
  1789 00009ECF C3                  <1> 	retn
  1790                              <1> gcbi_1:
  1791 00009ED0 51                  <1> 	push	ecx
  1792 00009ED1 E8DAF5FFFF          <1> 	call	get_next_cluster
  1793 00009ED6 59                  <1> 	pop	ecx
  1794 00009ED7 7203                <1> 	jc	short gcbi_3
  1795 00009ED9 E2F5                <1> 	loop	gcbi_1
  1796                              <1> gcbi_2:
  1797 00009EDB C3                  <1> 	retn
  1798                              <1> gcbi_3:
  1799 00009EDC 09C0                <1> 	or	eax, eax
  1800 00009EDE 74E9                <1> 	jz	short gcbi_0
  1801 00009EE0 F5                  <1> 	cmc 	; stc
  1802 00009EE1 C3                  <1> 	retn
  1803                              <1> 
  1804                              <1> get_fs_section_by_index:
  1805                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1806                              <1> 	; INPUT ->
  1807                              <1> 	; 	EAX = Beginning FDT number/address
  1808                              <1> 	; 	EDX = Sector index in disk/file section
  1809                              <1> 	; 	ECX = Sector sequence number after the beginning FDT
  1810                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1811                              <1> 	; OUTPUT ->
  1812                              <1> 	; 	EAX = FDT number/address
  1813                              <1> 	; 	EDX = Sector index from FDT sector (0,1,2,3,4...)
  1814                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1815                              <1> 	;
  1816                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1817                              <1> 	;
  1818 00009EE2 B8FFFFFFFF          <1> 	mov	eax, 0FFFFFFFFh
  1819 00009EE7 C3                  <1> 	retn
  1929                                  %include 'trdosk6.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk6.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 06/05/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    11                              <1> ; u1.s (27/17/2015), u2.s (03/01/2016)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> sysent: ; < enter to system call >
    15                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
    16                              <1> 	; 16/04/2015 - 19/10/2015 (Retro UNIX 386 v1)
    17                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
    18                              <1> 	;
    19                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
    20                              <1> 	; The trap type is determined and an indirect jump is made to 
    21                              <1> 	; the appropriate system call handler. If there is a trap inside
    22                              <1> 	; the system a jump to panic is made. All user registers are saved 
    23                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
    24                              <1> 	; instructor is decoded to get the the system code part (see
    25                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
    26                              <1> 	; the indirect jump address is calculated. If a bad system call is
    27                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
    28                              <1> 	; is called. If the call is legitimate control passes to the
    29                              <1> 	; appropriate system routine.
    30                              <1> 	;
    31                              <1> 	; Calling sequence:
    32                              <1> 	;	Through a trap caused by any sys call outside the system.
    33                              <1> 	; Arguments:
    34                              <1> 	;	Arguments of particular system call.	
    35                              <1> 	; ...............................................................
    36                              <1> 	;	
    37                              <1> 	; Retro UNIX 8086 v1 modification: 
    38                              <1> 	;       System call number is in EAX register.
    39                              <1> 	;
    40                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
    41                              <1> 	;	registers depending of function details.
    42                              <1>   	;
    43                              <1> 	; 16/04/2015
    44 00009EE8 368925[78DF0000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    45                              <1> 	; save user registers
    46 00009EEF 1E                  <1> 	push	ds
    47 00009EF0 06                  <1> 	push	es
    48 00009EF1 0FA0                <1> 	push	fs
    49 00009EF3 0FA8                <1> 	push	gs
    50 00009EF5 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
    51                              <1> 	;
    52                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
    53                              <1> 	; 	(ESPACE is size of space in kernel stack 
    54                              <1> 	;	for saving/restoring user registers.)
    55                              <1> 	;
    56 00009EF6 50                  <1> 	push	eax ; 01/07/2015
    57 00009EF7 66B81000            <1> 	mov     ax, KDATA
    58 00009EFB 8ED8                <1>         mov     ds, ax
    59 00009EFD 8EC0                <1>         mov     es, ax
    60 00009EFF 8EE0                <1>         mov     fs, ax
    61 00009F01 8EE8                <1>         mov     gs, ax
    62 00009F03 A1[D8CE0000]        <1> 	mov	eax, [k_page_dir]
    63 00009F08 0F22D8              <1> 	mov	cr3, eax
    64 00009F0B 58                  <1> 	pop	eax ; 01/07/2015
    65                              <1> 	; 19/10/2015
    66 00009F0C FC                  <1> 	cld
    67                              <1> 	;
    68 00009F0D FE05[77DF0000]      <1> 	inc	byte [sysflg]
    69                              <1> 		; incb sysflg / indicate a system routine is in progress
    70 00009F13 FB                  <1>         sti 	; 18/01/2014
    71 00009F14 0F8558A0FFFF        <1> 	jnz     panic ; 24/05/2013
    72                              <1> 		; beq 1f
    73                              <1> 		; jmp panic ; / called if trap inside system
    74                              <1> ;1:
    75                              <1> 	; 16/04/2015
    76 00009F1A A3[80DF0000]        <1> 	mov	[u.r0], eax
    77 00009F1F 8925[7CDF0000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
    78                              <1> 	;
    79                              <1> 		; mov $s.syst+2,clockp
    80                              <1> 		; mov r0,-(sp) / save user registers 
    81                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
    82                              <1> 			   ; / in u.r0
    83                              <1> 		; mov r1,-(sp)
    84                              <1> 		; mov r2,-(sp)
    85                              <1> 		; mov r3,-(sp)
    86                              <1> 		; mov r4,-(sp)
    87                              <1> 		; mov r5,-(sp)
    88                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
    89                              <1> 		             ; / arithmetic unit
    90                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
    91                              <1> 		             ; / extended arithmetic unit
    92                              <1> 		; mov sc,-(sp) / "step count" register for the extended
    93                              <1> 		             ; / arithmetic unit
    94                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
    95                              <1> 		; mov 18.(sp),r0 / store pc in r0
    96                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
    97                              <1> 		; sub $sys,r0 / get xxx code
    98 00009F25 C1E002              <1> 	shl	eax, 2
    99                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   100 00009F28 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
   101                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
   102                              <1> 	;jnb	short badsys
   103                              <1> 		; bhis badsys / yes, bad system call
   104 00009F2D F5                  <1> 	cmc
   105 00009F2E 9C                  <1> 	pushf	
   106 00009F2F 50                  <1> 	push	eax
   107 00009F30 8B2D[78DF0000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   108 00009F36 B0FE                <1> 	mov	al, 0FEh ; 11111110b
   109 00009F38 1400                <1> 	adc	al, 0 ; al = al + cf
   110 00009F3A 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
   111                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
   112                              <1> 				 ; / and clear carry bit
   113 00009F3D 5D                  <1> 	pop	ebp ; eax
   114 00009F3E 9D                  <1> 	popf
   115 00009F3F 0F8248010000        <1>         jc      badsys
   116 00009F45 A1[80DF0000]        <1> 	mov	eax, [u.r0]
   117                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   118 00009F4A FFA5[509F0000]      <1> 	jmp	dword [ebp+syscalls]
   119                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
   120                              <1> 		            ; / to proper system routine.
   121                              <1> syscalls: ; 1:
   122                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   123                              <1> 	; 21/09/2015
   124                              <1> 	; 01/07/2015
   125                              <1> 	; 16/04/2015 (32 bit address modification) 
   126                              <1> 	;dd sysrele	; / 0
   127 00009F50 [F8B90000]          <1> 	dd sysver	; / 0 ; Get TRDOS 386 version number (v2.0)	
   128 00009F54 [EDA00000]          <1> 	dd sysexit 	; / 1
   129 00009F58 [12A20000]          <1> 	dd sysfork 	; / 2
   130 00009F5C [25A30000]          <1> 	dd sysread 	; / 3
   131 00009F60 [40A30000]          <1> 	dd syswrite 	; / 4
   132 00009F64 [AAA30000]          <1> 	dd sysopen 	; / 5
   133 00009F68 [E4A40000]          <1> 	dd sysclose 	; / 6
   134 00009F6C [94A10000]          <1> 	dd syswait 	; / 7
   135 00009F70 [5AA40000]          <1> 	dd syscreat 	; / 8
   136 00009F74 [0BA80000]          <1> 	dd syslink 	; / 9
   137 00009F78 [CDA80000]          <1> 	dd sysunlink 	; / 10
   138 00009F7C [A0A90000]          <1> 	dd sysexec 	; / 11
   139 00009F80 [FAAD0000]          <1> 	dd syschdir 	; / 12
   140 00009F84 [DEAE0000]          <1> 	dd systime 	; / 13
   141 00009F88 [9BA40000]          <1> 	dd sysmkdir 	; / 14
   142 00009F8C [4CAE0000]          <1> 	dd syschmod 	; / 15
   143 00009F90 [AEAE0000]          <1> 	dd syschown 	; / 16
   144 00009F94 [11AF0000]          <1> 	dd sysbreak 	; / 17
   145 00009F98 [6BAB0000]          <1> 	dd sysstat 	; / 18
   146 00009F9C [D6AF0000]          <1> 	dd sysseek 	; / 19
   147 00009FA0 [E8AF0000]          <1> 	dd systell 	; / 20
   148 00009FA4 [E9B00000]          <1> 	dd sysmount 	; / 21
   149 00009FA8 [9BB10000]          <1> 	dd sysumount 	; / 22
   150 00009FAC [66B00000]          <1> 	dd syssetuid 	; / 23
   151 00009FB0 [97B00000]          <1> 	dd sysgetuid 	; / 24
   152 00009FB4 [EDAE0000]          <1> 	dd sysstime 	; / 25
   153 00009FB8 [5AB00000]          <1> 	dd sysquit 	; / 26
   154 00009FBC [4EB00000]          <1> 	dd sysintr 	; / 27
   155 00009FC0 [47AB0000]          <1> 	dd sysfstat 	; / 28
   156 00009FC4 [00A50000]          <1> 	dd sysemt 	; / 29
   157 00009FC8 [2EA50000]          <1> 	dd sysmdate 	; / 30
   158 00009FCC [79A50000]          <1> 	dd sysstty 	; / 31
   159 00009FD0 [F8A60000]          <1> 	dd sysgtty 	; / 32
   160 00009FD4 [29A50000]          <1> 	dd sysilgins 	; / 33
   161 00009FD8 [F6B10000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   162                              <1> 			     ; 11/06/2014
   163 00009FDC [25B20000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   164                              <1> 			     ; 01/07/2015
   165 00009FE0 [FCB20000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   166                              <1> 			     ; 21/09/2015 - get last error number
   167                              <1> end_of_syscalls:
   168                              <1> 
   169                              <1> error:
   170                              <1> 	; 17/09/2015
   171                              <1> 	; 03/09/2015
   172                              <1> 	; 01/09/2015
   173                              <1> 	; 09/06/2015
   174                              <1> 	; 13/05/2015
   175                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   176                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
   177                              <1> 	;
   178                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
   179                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
   180                              <1> 	;
   181                              <1> 	; INPUTS -> none
   182                              <1> 	; OUTPUTS ->
   183                              <1> 	;	processor status - carry (c) bit is set (means error)
   184                              <1> 	;
   185                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
   186                              <1> 	; 	      Because, jumps to error procedure
   187                              <1> 	;	      disrupts push-pop nesting balance)
   188                              <1> 	;
   189 00009FE4 8B2D[78DF0000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   190 00009FEA 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
   191                              <1> 				 ; (system call will return with cf = 1)
   192                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
   193                              <1> 		               ; / users stack
   194                              <1> 	; 17/09/2015
   195 00009FEE 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
   196                              <1> 				 ; for saving/restoring user registers	
   197                              <1> 	;cmp	ebp, [u.usp]
   198                              <1> 	;je	short err0	
   199 00009FF1 892D[7CDF0000]      <1> 	mov	[u.usp], ebp
   200                              <1> ;err0:
   201                              <1> 	; 01/09/2015
   202 00009FF7 8B25[7CDF0000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
   203                              <1> 				    ; 10/04/2013
   204                              <1> 				    ; (If an I/O error occurs during disk I/O,
   205                              <1> 				    ; related procedures will jump to 'error'
   206                              <1> 				    ; procedure directly without returning to 
   207                              <1> 				    ; the caller procedure. So, stack pointer
   208                              <1>                                     ; must be restored here.)
   209                              <1> 	; 13/05/2015
   210                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
   211                              <1> 	;	'get last error' system call later. 	
   212                              <1> 
   213                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
   214 00009FFD C605[E7DF0000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
   215                              <1> 
   216                              <1> sysret: ; < return from system call>
   217                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   218                              <1> 	; 16/04/2015 - 10/09/2015 (Retro UNIX 386 v1)
   219                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
   220                              <1> 	;
   221                              <1> 	; 'sysret' first checks to see if process is about to be 
   222                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
   223                              <1> 	; If not, following happens:	 
   224                              <1> 	; 	1) The user's stack pointer is restored.
   225                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
   226                              <1> 	;	   i-node has been modified. If it has, it is written out
   227                              <1> 	;	   via 'ppoke'.
   228                              <1> 	;	3) If the super block has been modified, it is written out
   229                              <1> 	;	   via 'ppoke'.				
   230                              <1> 	;	4) If the dismountable file system's super block has been
   231                              <1> 	;	   modified, it is written out to the specified device
   232                              <1> 	;	   via 'ppoke'.
   233                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
   234                              <1> 	;	   during his execution. If so, 'tswap' is called to give
   235                              <1> 	;	   another user a chance to run.
   236                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
   237                              <1> 	;	    (See 'sysrele' for conclusion.)		
   238                              <1> 	;
   239                              <1> 	; Calling sequence:
   240                              <1> 	;	jump table or 'br sysret'
   241                              <1> 	; Arguments: 
   242                              <1> 	;	-	
   243                              <1> 	; ...............................................................
   244                              <1> 	;	
   245                              <1> 	; ((AX=r1 for 'iget' input))
   246                              <1> 	;	
   247 0000A004 6631C0              <1> 	xor	ax, ax ; 04/05/2013
   248                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   249 0000A007 FEC0                <1> 	inc	al ; 04/05/2013
   250 0000A009 3805[CEDF0000]      <1> 	cmp	[u.bsys], al ; 1
   251                              <1> 		; tstb u.bsys / is a process about to be terminated because
   252 0000A00F 0F83D8000000        <1>         jnb     sysexit ; 04/05/2013
   253                              <1> 		; bne sysexit / of an error? yes, go to sysexit
   254                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
   255                              <1> 		; mov u.sp,sp / no point stack to users stack
   256 0000A015 FEC8                <1> 	dec 	al ; mov ax, 0
   257                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   258 0000A017 E84B1A0000          <1> 	call	iget
   259                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   260                              <1> 		            ; / it is written out
   261 0000A01C 6631C0              <1> 	xor 	ax, ax ; 0
   262 0000A01F 3805[75DF0000]      <1> 	cmp	[smod], al ; 0
   263                              <1> 		; tstb	smod / has the super block been modified
   264 0000A025 7614                <1> 	jna	short sysret1
   265                              <1> 		; beq	1f / no, 1f
   266 0000A027 A2[75DF0000]        <1> 	mov	[smod], al ; 0
   267                              <1> 		; clrb smod / yes, clear smod
   268 0000A02C BB[2DE80000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
   269 0000A031 66810B0002          <1>    	or	word [ebx], 200h ;;
   270                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
   271                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
   272                              <1> 		      	      ; / output
   273                              <1> 	; AX = 0
   274 0000A036 E82D1A0000          <1> 	call 	poke ; 07/08/2013
   275                              <1> 	; call	ppoke
   276                              <1> 	; AX = 0
   277                              <1> 		; jsr r0,ppoke / write out modified super block to disk
   278                              <1> sysret1: ;1:
   279 0000A03B 3805[76DF0000]      <1> 	cmp	[mmod], al ; 0
   280                              <1> 		; tstb	mmod / has the super block for the dismountable file
   281                              <1> 		           ; / system
   282 0000A041 7614                <1> 	jna	short sysrel0
   283                              <1> 		; beq 1f / been modified?  no, 1f
   284 0000A043 A2[76DF0000]        <1> 	mov	[mmod], al ; 0	
   285                              <1> 		; clrb	mmod / yes, clear mmod
   286                              <1>         ;mov    ax, [mntd]
   287                              <1>         ;;mov   al, [mdev] ; 26/04/2013
   288 0000A048 BB[35EA0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
   289                              <1>         ;;mov	[ebx], al
   290                              <1> 	;mov    [sb1], al
   291                              <1> 		; movb	mntd,sb1 / set the I/O queue
   292 0000A04D 66810B0002          <1> 	or	word [ebx], 200h
   293                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
   294                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
   295 0000A052 E8111A0000          <1> 	call	poke ; 07/08/2013
   296                              <1> 	;call	ppoke 
   297                              <1> 		; jsr r0,ppoke / write it out to its device
   298                              <1>         ;xor    al, al ; 26/04/2013       
   299                              <1> ;1:
   300                              <1> 		; tstb uquant / is the time quantum 0?
   301                              <1> 		; bne 1f / no, don't swap it out
   302                              <1> 
   303                              <1> sysrele: ; < release >
   304                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   305                              <1> 	; 16/04/2015 - 14/10/2015 (Retro UNIX 386 v1)
   306                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
   307                              <1> 	;
   308                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
   309                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
   310                              <1> 	; turns off the system flag. It then checked to see if there is
   311                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
   312                              <1> 	; the output gets flashed (see isintr) and interrupt action is
   313                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
   314                              <1> 	; the user, a rti is made.
   315                              <1> 	;
   316                              <1> 	; Calling sequence:
   317                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
   318                              <1> 	; Arguments:
   319                              <1> 	;	-	
   320                              <1> 	; ...............................................................
   321                              <1> 	;	
   322                              <1> 	; 23/02/2014 (swapret)
   323                              <1> 	; 22/09/2013
   324                              <1> sysrel0: ;1:
   325 0000A057 803D[C2DF0000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   326                              <1> 		; tstb uquant / is the time quantum 0?
   327 0000A05E 7705                <1>         ja      short swapret
   328                              <1> 		; bne 1f / no, don't swap it out
   329                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
   330 0000A060 E8041A0000          <1> 	call	tswap
   331                              <1> 		; jsr r0,tswap / yes, swap it out
   332                              <1> ;
   333                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
   334                              <1> swapret: ;1:
   335                              <1> 	; 10/09/2015
   336                              <1> 	; 01/09/2015
   337                              <1> 	; 14/05/2015
   338                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
   339                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
   340                              <1> 	; cli
   341                              <1> 	; 24/07/2015
   342                              <1> 	;
   343                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
   344                              <1> 	;; mov	esp, [u.usp]
   345                              <1> 
   346                              <1> 	; 22/09/2013
   347 0000A065 E8001A0000          <1> 	call	isintr
   348                              <1> 	; 20/10/2013
   349 0000A06A 7405                <1> 	jz	short sysrel1
   350 0000A06C E865000000          <1> 	call	intract
   351                              <1> 		; jsr r0,isintr / is there an interrupt from the user
   352                              <1> 		;     br intract / yes, output gets flushed, take interrupt
   353                              <1> 		               ; / action
   354                              <1> sysrel1:
   355 0000A071 FA                  <1> 	cli ; 14/10/2015
   356 0000A072 FE0D[77DF0000]      <1> 	dec	byte [sysflg]
   357                              <1> 		; decb sysflg / turn system flag off
   358 0000A078 A1[D9DF0000]        <1> 	mov     eax, [u.pgdir]
   359 0000A07D 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
   360                              <1> 			  ; (others are different than kernel page tables) 
   361                              <1> 	; 10/09/2015
   362 0000A080 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   363                              <1> 		; mov (sp)+,sc / restore user registers
   364                              <1> 		; mov (sp)+,mq
   365                              <1> 		; mov (sp)+,ac
   366                              <1> 		; mov (sp)+,r5
   367                              <1> 		; mov (sp)+,r4
   368                              <1> 		; mov (sp)+,r3
   369                              <1> 		; mov (sp)+,r2
   370                              <1> 	;
   371 0000A081 A1[80DF0000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   372 0000A086 0FA9                <1> 	pop	gs
   373 0000A088 0FA1                <1> 	pop	fs
   374 0000A08A 07                  <1> 	pop	es
   375 0000A08B 1F                  <1> 	pop	ds
   376 0000A08C CF                  <1> 	iretd	
   377                              <1> 		; rti / no, return from interrupt
   378                              <1> 
   379                              <1> badsys:
   380                              <1> 	; 18/04/2016 (TRDOS 386 = TRDOS v2.0)
   381                              <1> 	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
   382                              <1> 	; 03/02/2011 ('trdos_ifc_routine')
   383                              <1> 	;
   384                              <1> 	; 16/04/2015 (Retro UNIX 386 v1, 'badsys')
   385                              <1> 	; (EIP, EAX values will be shown on screen with error message)
   386                              <1> 	; (EIP = 'CD 40h' instruction address -INT 40h-)
   387                              <1> 	; (EAX = Function number)  
   388                              <1> 	;
   389 0000A08D FE05[CEDF0000]      <1> 	inc	byte [u.bsys]
   390                              <1> 	;
   391 0000A093 8B1D[78DF0000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   392 0000A099 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   393 0000A09B 83E802              <1> 	sub	eax, 2 ; CDh, ##h
   394 0000A09E E84C79FFFF          <1> 	call	dwordtohex
   395 0000A0A3 8915[D9C40000]      <1> 	mov	[eip_str], edx
   396 0000A0A9 A3[DDC40000]        <1> 	mov	[eip_str+4], eax
   397 0000A0AE A1[80DF0000]        <1> 	mov	eax, [u.r0]
   398 0000A0B3 E83779FFFF          <1> 	call	dwordtohex
   399 0000A0B8 8915[C8C40000]      <1> 	mov	[eax_str], edx
   400 0000A0BE A3[CCC40000]        <1> 	mov	[eax_str+4], eax
   401                              <1> 
   402 0000A0C3 C605[BDC40000]40    <1> 	mov	byte [int_num_str], 40h
   403                              <1> 
   404 0000A0CA BE[8FC40000]        <1> 	mov	esi, ifc_msg ; "invalid funtion call !" msg (trdosk9.s)
   405 0000A0CF E84B9EFFFF          <1> 	call	print_msg
   406                              <1> 
   407 0000A0D4 EB17                <1> 	jmp	sysexit
   408                              <1> 
   409                              <1> intract: ; / interrupt action
   410                              <1> 	; 14/10/2015
   411                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   412                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
   413                              <1> 	;
   414                              <1> 	; Retro UNIX 8086 v1 modification !
   415                              <1> 	; (Process/task switching and quit routine by using
   416                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
   417                              <1> 	;
   418                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
   419                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
   420                              <1> 	;		'intract' will jump to 'sysexit'.
   421                              <1> 	;	    Intract will return to the caller 
   422                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
   423                              <1> 	; 14/10/2015
   424 0000A0D6 FB                  <1> 	sti
   425                              <1> 	; 07/12/2013	
   426 0000A0D7 66FF05[C6DF0000]    <1> 	inc 	word [u.quit]
   427 0000A0DE 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   428 0000A0E0 66FF0D[C6DF0000]    <1> 	dec	word [u.quit]
   429                              <1> 	; 16/04/2015
   430 0000A0E7 C3                  <1> 	retn
   431                              <1> intrct0:	
   432 0000A0E8 58                  <1> 	pop	eax ; call intract -> retn
   433                              <1> 	;
   434 0000A0E9 31C0                <1> 	xor 	eax, eax
   435 0000A0EB FEC0                <1> 	inc	al  ; mov ax, 1
   436                              <1> ;;;
   437                              <1> 	; UNIX v1 original 'intract' routine... 
   438                              <1> 	; / interrupt action
   439                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
   440                              <1> 		; bne 1f / no, 1f
   441                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
   442                              <1> 	; 1: / now in user area
   443                              <1> 		; mov r1,-(sp) / save r1
   444                              <1> 		; mov u.ttyp,r1 
   445                              <1> 			; / pointer to tty buffer in control-to r1
   446                              <1> 		; cmpb 6(r1),$177
   447                              <1> 			; / is the interrupt char equal to "del"
   448                              <1> 		; beq 1f / yes, 1f
   449                              <1> 		; clrb 6(r1) 
   450                              <1> 		        ; / no, clear the byte 
   451                              <1> 			; / (must be a quit character)
   452                              <1> 		; mov (sp)+,r1 / restore r1
   453                              <1> 		; clr u.quit / clear quit flag
   454                              <1> 		; bis $20,2(sp) 
   455                              <1> 		    	; / set trace for quit (sets t bit of 
   456                              <1> 			; / ps-trace trap)
   457                              <1> 		; rti   ;  / return from interrupt
   458                              <1> 	; 1: / interrupt char = del
   459                              <1> 		; clrb 6(r1) / clear the interrupt byte 
   460                              <1> 			   ; / in the buffer
   461                              <1> 		; mov (sp)+,r1 / restore r1
   462                              <1> 		; cmp u.intr,$core / should control be 
   463                              <1> 				; / transferred to loc core?
   464                              <1> 		; blo 1f
   465                              <1> 		; jmp *u.intr / user to do rti yes, 
   466                              <1> 				; / transfer to loc core
   467                              <1> 	; 1:
   468                              <1> 		; sys 1 / exit
   469                              <1> 
   470                              <1> sysexit: ; <terminate process>
   471                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   472                              <1> 	; 16/04/2015 - 01/09/2015 (Retro UNIX 386 v1)
   473                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   474                              <1> 	;
   475                              <1> 	; 'sysexit' terminates a process. First each file that
   476                              <1> 	; the process has opened is closed by 'flose'. The process
   477                              <1> 	; status is then set to unused. The 'p.pid' table is then
   478                              <1> 	; searched to find children of the dying process. If any of
   479                              <1> 	; children are zombies (died by not waited for), they are
   480                              <1> 	; set free. The 'p.pid' table is then searched to find the
   481                              <1> 	; dying process's parent. When the parent is found, it is
   482                              <1> 	; checked to see if it is free or it is a zombie. If it is
   483                              <1> 	; one of these, the dying process just dies. If it is waiting
   484                              <1> 	; for a child process to die, it notified that it doesn't 
   485                              <1> 	; have to wait anymore by setting it's status from 2 to 1
   486                              <1> 	; (waiting to active). It is awakened and put on runq by
   487                              <1> 	; 'putlu'. The dying process enters a zombie state in which
   488                              <1> 	; it will never be run again but stays around until a 'wait'
   489                              <1> 	; is completed by it's parent process. If the parent is not
   490                              <1> 	; found, process just dies. This means 'swap' is called with
   491                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
   492                              <1> 	; to write out the process and 'rswap' reads the new process
   493                              <1> 	; over the one that dies..i.e., the dying process is 
   494                              <1> 	; overwritten and destroyed.	
   495                              <1>  	;
   496                              <1> 	; Calling sequence:
   497                              <1> 	;	sysexit or conditional branch.
   498                              <1> 	; Arguments:
   499                              <1> 	;	-	
   500                              <1> 	; ...............................................................
   501                              <1> 	;	
   502                              <1> 	; Retro UNIX 8086 v1 modification: 
   503                              <1> 	;       System call number (=1) is in EAX register.
   504                              <1> 	;
   505                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
   506                              <1> 	;       registers depending of function details.
   507                              <1> 	;
   508                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
   509                              <1> 	;
   510                              <1> ; / terminate process
   511                              <1> 	; AX = 1
   512 0000A0ED 6648                <1> 	dec 	ax ; 0
   513 0000A0EF 66A3[C4DF0000]      <1> 	mov	[u.intr], ax ; 0
   514                              <1> 		; clr u.intr / clear interrupt control word
   515                              <1> 		; clr r1 / clear r1
   516                              <1> 	; AX = 0
   517                              <1> sysexit_1: ; 1:
   518                              <1> 	; AX = File descriptor
   519                              <1> 		; / r1 has file descriptor (index to u.fp list)
   520                              <1> 		; / Search the whole list
   521 0000A0F5 E8070B0000          <1> 	call	fclose
   522                              <1> 		; jsr r0,fclose / close all files the process opened
   523                              <1> 	;; ignore error return
   524                              <1> 		; br .+2 / ignore error return
   525                              <1> 	;inc	ax
   526 0000A0FA FEC0                <1> 	inc	al
   527                              <1> 		; inc r1 / increment file descriptor
   528                              <1> 	;cmp	ax, 10
   529 0000A0FC 3C0A                <1> 	cmp	al, 10
   530                              <1> 		; cmp r1,$10. / end of u.fp list?
   531 0000A0FE 72F5                <1> 	jb	short sysexit_1
   532                              <1> 		; blt 1b / no, go back
   533 0000A100 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno]
   534                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   535 0000A107 88A3[07DD0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   536                              <1> 		; clrb p.stat-1(r1) / free the process
   537                              <1> 	;shl	bx, 1
   538 0000A10D D0E3                <1> 	shl	bl, 1
   539                              <1> 		; asl r1 / use r1 for index into the below tables
   540 0000A10F 668B8B[76DC0000]    <1> 	mov	cx, [ebx+p.pid-2]
   541                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   542 0000A116 668B93[96DC0000]    <1> 	mov	dx, [ebx+p.ppid-2]
   543                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
   544                              <1> 	; xor 	bx, bx ; 0
   545 0000A11D 30DB                <1> 	xor	bl, bl ; 0
   546                              <1> 		; clr r2
   547 0000A11F 31F6                <1> 	xor	esi, esi ; 0
   548                              <1> 		; clr r5 / initialize reg
   549                              <1> sysexit_2: ; 1:
   550                              <1> 	        ; / find children of this dying process, 
   551                              <1> 		; / if they are zombies, free them
   552                              <1> 	;add	bx, 2
   553 0000A121 80C302              <1> 	add	bl, 2
   554                              <1> 		; add $2,r2 / search parent process table 
   555                              <1> 		          ; / for dying process's name
   556 0000A124 66398B[96DC0000]    <1> 	cmp	[ebx+p.ppid-2], cx
   557                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   558 0000A12B 7513                <1> 	jne	short sysexit_4
   559                              <1> 		; bne 3f / no
   560                              <1> 	;shr	bx, 1
   561 0000A12D D0EB                <1> 	shr	bl, 1
   562                              <1> 		; asr r2 / yes, it is a parent
   563 0000A12F 80BB[07DD0000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB
   564                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
   565                              <1> 				     ; / dying process a zombie
   566 0000A136 7506                <1> 	jne	short sysexit_3 
   567                              <1> 		; bne 2f / no
   568 0000A138 88A3[07DD0000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   569                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
   570                              <1> sysexit_3: ; 2:
   571                              <1> 	;shr	bx, 1
   572 0000A13E D0E3                <1> 	shl	bl, 1
   573                              <1> 		; asl r2
   574                              <1> sysexit_4: ; 3:
   575                              <1> 		; / search the process name table 
   576                              <1> 		; / for the dying process's parent
   577 0000A140 663993[76DC0000]    <1> 	cmp	[ebx+p.pid-2], dx
   578                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   579 0000A147 7502                <1> 	jne	short sysexit_5
   580                              <1> 		; bne 3f / no
   581 0000A149 89DE                <1> 	mov	esi, ebx
   582                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
   583                              <1> 		          ; / process # x2) in r5
   584                              <1> sysexit_5: ; 3:
   585                              <1> 	;cmp	bx, nproc + nproc
   586 0000A14B 80FB20              <1> 	cmp	bl, nproc + nproc
   587                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   588 0000A14E 72D1                <1> 	jb	short sysexit_2
   589                              <1> 		; blt 1b / no, go back
   590                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
   591 0000A150 21F6                <1> 	and	esi, esi ; r5=r1
   592 0000A152 7431                <1> 	jz	short sysexit_6
   593                              <1> 		; beq 2f / no parent has been found. 
   594                              <1> 		       ; / The process just dies
   595 0000A154 66D1EE              <1> 	shr	si, 1
   596                              <1> 		; asr r1 / set up index to p.stat
   597 0000A157 8A86[07DD0000]      <1> 	mov	al, [esi+p.stat-1]
   598                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   599 0000A15D 20C0                <1> 	and	al, al
   600 0000A15F 7424                <1> 	jz	short sysexit_6
   601                              <1> 		; beq 2f / if its been freed, 2f
   602 0000A161 3C03                <1> 	cmp	al, 3
   603                              <1> 		; cmp r2,$3 / is parent a zombie?
   604 0000A163 7420                <1> 	je	short sysexit_6
   605                              <1> 		; beq 2f / yes, 2f
   606                              <1> 	; BH = 0
   607 0000A165 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno]
   608                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   609 0000A16B C683[07DD0000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB
   610                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   611 0000A172 3C01                <1> 	cmp	al, 1 ; SRUN
   612 0000A174 740F                <1> 	je	short sysexit_6
   613                              <1> 	;cmp	al, 2
   614                              <1> 		; cmp r2,$2 / is the parent waiting for 
   615                              <1> 			  ; / this child to die
   616                              <1> 	;jne	short sysexit_6	
   617                              <1> 		; bne 2f / yes, notify parent not to wait any more
   618                              <1> 	; p.stat = 2 --> waiting
   619                              <1> 	; p.stat = 4 --> sleeping
   620 0000A176 C686[07DD0000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN
   621                              <1> 	;dec	byte [esi+p.stat-1]
   622                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
   623 0000A17D 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
   624                              <1> 	; 
   625                              <1> 	;mov	ebx, runq + 4
   626                              <1> 		; mov $runq+4,r2 / on the runq
   627 0000A180 E84E180000          <1> 	call	putlu
   628                              <1> 		; jsr r0, putlu
   629                              <1> sysexit_6: ; 2:
   630                              <1> 		; / the process dies
   631 0000A185 C605[CFDF0000]00    <1> 	mov	byte [u.uno], 0
   632                              <1> 		; clrb u.uno / put zero as the process number, 
   633                              <1> 	           ; / so "swap" will
   634 0000A18C E874170000          <1> 	call	swap
   635                              <1> 		; jsr r0,swap / overwrite process with another process
   636                              <1> hlt_sys:
   637                              <1> 	;sti
   638                              <1> hlts0:
   639 0000A191 F4                  <1> 	hlt
   640 0000A192 EBFD                <1> 	jmp	short hlts0
   641                              <1> 		; 0 / and thereby kill it; halt?
   642                              <1> 
   643                              <1> 
   644                              <1> syswait: ; < wait for a processs to die >
   645                              <1> 	; 17/09/2015
   646                              <1> 	; 02/09/2015
   647                              <1> 	; 01/09/2015
   648                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   649                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
   650                              <1> 	;
   651                              <1> 	; 'syswait' waits for a process die. 
   652                              <1> 	; It works in following way:
   653                              <1> 	;    1) From the parent process number, the parent's 
   654                              <1> 	; 	process name is found. The p.ppid table of parent
   655                              <1> 	;	names is then searched for this process name.
   656                              <1> 	;	If a match occurs, r2 contains child's process
   657                              <1> 	;	number. The child status is checked to see if it is
   658                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
   659                              <1> 	;	If it is, the child process is freed and it's name
   660                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
   661                              <1> 	;	If the child is not a zombie, nothing happens and
   662                              <1> 	;	the search goes on through the p.ppid table until
   663                              <1> 	;	all processes are checked or a zombie is found.
   664                              <1> 	;    2) If no zombies are found, a check is made to see if
   665                              <1> 	;	there are any children at all. If there are none,
   666                              <1> 	;	an error return is made. If there are, the parent's
   667                              <1> 	;	status is set to 2 (waiting for child to die),
   668                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
   669                              <1> 	;	is made to wait on the next process.
   670                              <1> 	;
   671                              <1> 	; Calling sequence:
   672                              <1> 	;	?
   673                              <1> 	; Arguments:
   674                              <1> 	;	-
   675                              <1> 	; Inputs: - 
   676                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
   677                              <1> 	; ...............................................................
   678                              <1> 	;				
   679                              <1> 	
   680                              <1> ; / wait for a process to die
   681                              <1> 
   682                              <1> syswait_0:
   683 0000A194 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   684                              <1> 		; movb u.uno,r1 / put parents process number in r1
   685 0000A19B D0E3                <1> 	shl	bl, 1
   686                              <1> 	;shl	bx, 1
   687                              <1> 		; asl r1 / x2 to get index into p.pid table
   688 0000A19D 668B83[76DC0000]    <1> 	mov	ax, [ebx+p.pid-2]
   689                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   690 0000A1A4 31F6                <1> 	xor	esi, esi
   691                              <1> 		; clr r2
   692 0000A1A6 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
   693                              <1> 	;xor 	cl, cl
   694                              <1> 		; clr r3 / initialize reg 3
   695                              <1> syswait_1: ; 1:
   696 0000A1A8 6683C602            <1> 	add	si, 2
   697                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
   698                              <1> 			  ; / search table of parent processes 
   699                              <1> 			  ; / for this process name
   700 0000A1AC 663B86[96DC0000]    <1> 	cmp	ax, [esi+p.ppid-2]
   701                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
   702                              <1> 			            ; / process number
   703 0000A1B3 7535                <1> 	jne	short syswait_3
   704                              <1> 		;bne 3f / branch if no match of parent process name
   705                              <1> 	;inc	cx
   706 0000A1B5 FEC1                <1> 	inc	cl
   707                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   708 0000A1B7 66D1EE              <1> 	shr	si, 1
   709                              <1> 		; asr r2 / r2/2 to get index to p.stat table
   710                              <1> 	; The possible states ('p.stat' values) of a process are:
   711                              <1> 	;	0 = free or unused
   712                              <1> 	;	1 = active
   713                              <1> 	;	2 = waiting for a child process to die
   714                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
   715 0000A1BA 80BE[07DD0000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
   716                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
   717 0000A1C1 7524                <1> 	jne	short syswait_2
   718                              <1> 		; bne 2f / no, skip it
   719 0000A1C3 88BE[07DD0000]      <1> 	mov	[esi+p.stat-1], bh ; 0
   720                              <1> 		; clrb p.stat-1(r2) / yes, free it
   721 0000A1C9 66D1E6              <1> 	shl	si, 1
   722                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   723 0000A1CC 0FB786[76DC0000]    <1> 	movzx	eax, word [esi+p.pid-2]
   724 0000A1D3 A3[80DF0000]        <1> 	mov	[u.r0], eax
   725                              <1> 		; mov p.pid-2(r2),*u.r0 
   726                              <1> 			      ; / put childs process name in (u.r0)
   727                              <1> 	;
   728                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
   729                              <1> 	;
   730                              <1> 	; Parent process ID -p.ppid- field (of the child process)
   731                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
   732                              <1> 	; system call loop from the application/program if it calls
   733                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
   734                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
   735                              <1> 	;
   736                              <1> 	; Note: syswait will return with error if there is not a
   737                              <1> 	;       zombie or running process to wait.	
   738                              <1> 	;
   739 0000A1D8 6629C0              <1> 	sub	ax, ax
   740 0000A1DB 668986[96DC0000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   741 0000A1E2 E920FEFFFF          <1> 	jmp	sysret0 ; ax = 0
   742                              <1> 	;
   743                              <1> 	;jmp	sysret
   744                              <1> 		; br sysret1 / return cause child is dead
   745                              <1> syswait_2: ; 2:
   746 0000A1E7 66D1E6              <1> 	shl	si, 1
   747                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   748                              <1> syswait_3: ; 3:
   749 0000A1EA 6683FE20            <1> 	cmp	si, nproc+nproc
   750                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   751 0000A1EE 72B8                <1> 	jb	short syswait_1
   752                              <1> 		; blt 1b / no, continue search
   753                              <1> 	;and	cx, cx
   754 0000A1F0 20C9                <1> 	and	cl, cl
   755                              <1> 		; tst r3 / one gets here if there are no children 
   756                              <1> 		       ; / or children that are still active
   757                              <1> 	; 30/10/2013
   758 0000A1F2 750B                <1> 	jnz	short syswait_4
   759                              <1> 	;jz	error
   760                              <1> 		; beq error1 / there are no children, error
   761 0000A1F4 890D[80DF0000]      <1> 	mov	[u.r0], ecx ; 0
   762 0000A1FA E9E5FDFFFF          <1> 	jmp	error
   763                              <1> syswait_4:
   764 0000A1FF 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno]
   765                              <1> 		; movb u.uno,r1 / there are children so put 
   766                              <1> 			      ; / parent process number in r1
   767 0000A205 FE83[07DD0000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
   768                              <1> 		; incb p.stat-1(r1) / it is waiting for 
   769                              <1> 				  ; / other children to die
   770                              <1> 	; 04/11/2013
   771 0000A20B E8F5160000          <1> 	call	swap
   772                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   773 0000A210 EB82                <1> 	jmp	syswait_0
   774                              <1> 		; br syswait / wait on next process
   775                              <1> 
   776                              <1> sysfork: ; < create a new process >
   777                              <1> 	; 18/09/2015
   778                              <1> 	; 04/09/2015
   779                              <1> 	; 02/09/2015
   780                              <1> 	; 01/09/2015
   781                              <1> 	; 28/08/2015
   782                              <1> 	; 14/05/2015
   783                              <1> 	; 10/05/2015
   784                              <1> 	; 09/05/2015
   785                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
   786                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   787                              <1> 	;
   788                              <1> 	; 'sysfork' creates a new process. This process is referred
   789                              <1> 	; to as the child process. This new process core image is
   790                              <1> 	; a copy of that of the caller of 'sysfork'. The only
   791                              <1> 	; distinction is the return location and the fact that (u.r0)
   792                              <1> 	; in the old process (parent) contains the process id (p.pid)
   793                              <1> 	; of the new process (child). This id is used by 'syswait'.
   794                              <1> 	; 'sysfork' works in the following manner: 	
   795                              <1> 	;    1) The process status table (p.stat) is searched to find
   796                              <1> 	;	a process number that is unused. If none are found
   797                              <1> 	;	an error occurs.
   798                              <1> 	;    2) when one is found, it becomes the child process number
   799                              <1> 	;	and it's status (p.stat) is set to active.
   800                              <1> 	;    3) If the parent had a control tty, the interrupt 
   801                              <1> 	;	character in that tty buffer is cleared.
   802                              <1> 	;    4) The child process is put on the lowest priority run 
   803                              <1> 	;	queue via 'putlu'.
   804                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
   805                              <1> 	;	it is a unique number) and is put in the child's unique
   806                              <1> 	;	identifier; process id (p.pid).
   807                              <1> 	;    6) The process name of the parent is then obtained and
   808                              <1> 	;	placed in the unique identifier of the parent process
   809                              <1> 	;	name is then put in 'u.r0'.	
   810                              <1> 	;    7) The child process is then written out on disk by
   811                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
   812                              <1> 	;	and the child is born. (The child process is written 
   813                              <1> 	;	out on disk/drum with 'u.uno' being the child process
   814                              <1> 	;	number.)
   815                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
   816                              <1> 	;    9) The child process name is put in 'u.r0'.
   817                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
   818                              <1> 	;	create the return address for the parent process.
   819                              <1> 	;   11) The 'u.fp' list as then searched to see what files
   820                              <1> 	;	the parent has opened. For each file the parent has
   821                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
   822                              <1> 	;	to indicate that the child process also has opened
   823                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
   824                              <1> 	;
   825                              <1> 	; Calling sequence:
   826                              <1> 	;	from shell ?
   827                              <1> 	; Arguments:
   828                              <1> 	;	-
   829                              <1> 	; Inputs: -
   830                              <1> 	; Outputs: *u.r0 - child process name
   831                              <1> 	; ...............................................................
   832                              <1> 	;	
   833                              <1> 	; Retro UNIX 8086 v1 modification: 
   834                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
   835                              <1> 	;	= process id of child a parent process returns
   836                              <1> 	;	= process id of parent when a child process returns
   837                              <1> 	;
   838                              <1> 	;       In original UNIX v1, sysfork is called and returns as
   839                              <1> 	;	in following manner: (with an example: c library, fork)
   840                              <1> 	;	
   841                              <1> 	;	1:
   842                              <1> 	;		sys	fork
   843                              <1> 	;			br 1f  / child process returns here
   844                              <1> 	;		bes	2f     / parent process returns here
   845                              <1> 	;		/ pid of new process in r0
   846                              <1> 	;		rts	pc
   847                              <1> 	;	2: / parent process condionally branches here
   848                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
   849                              <1> 	;		rts	pc
   850                              <1> 	;
   851                              <1> 	;	1: / child process brances here
   852                              <1> 	;		clr	r0   / pid = 0 in child process
   853                              <1> 	;		rts	pc
   854                              <1> 	;
   855                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
   856                              <1> 	;		// pid = fork();
   857                              <1> 	;		//
   858                              <1> 	;		// pid == 0 in child process; 
   859                              <1> 	;		// pid == -1 means error return
   860                              <1> 	;		// in child, 
   861                              <1> 	;		//	parents id is in par_uid if needed
   862                              <1> 	;		
   863                              <1> 	;		_fork:
   864                              <1> 	;			mov	$.fork,eax
   865                              <1> 	;			int	$0x30
   866                              <1> 	;			jmp	1f
   867                              <1> 	;			jnc	2f
   868                              <1> 	;			jmp	cerror
   869                              <1> 	;		1:
   870                              <1> 	;			mov	eax,_par_uid
   871                              <1> 	;			xor	eax,eax
   872                              <1> 	;		2:
   873                              <1> 	;			ret
   874                              <1> 	;
   875                              <1> 	;	In Retro UNIX 8086 v1,
   876                              <1> 	;	'sysfork' returns in following manner:
   877                              <1> 	;	
   878                              <1> 	;		mov	ax, sys_fork
   879                              <1> 	;		mov	bx, offset @f ; routine for child
   880                              <1> 	;		int	20h
   881                              <1> 	;		jc	error
   882                              <1> 	;		
   883                              <1> 	;	; Routine for parent process here (just after 'jc')
   884                              <1> 	;		mov	word ptr [pid_of_child], ax
   885                              <1> 	;		jmp	next_routine_for_parent	
   886                              <1> 	;
   887                              <1> 	;	@@: ; routine for child process here				
   888                              <1> 	;		....	
   889                              <1> 	;	NOTE: 'sysfork' returns to specified offset
   890                              <1> 	;	       for child process by using BX input.
   891                              <1> 	;	      (at first, parent process will return then 
   892                              <1> 	;	      child process will return -after swapped in-
   893                              <1> 	;	      'syswait' is needed in parent process
   894                              <1> 	;	      if return from child process will be waited for.)
   895                              <1> 	;	  				
   896                              <1> 	
   897                              <1> ; / create a new process
   898                              <1> 	; EBX = return address for child process 
   899                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
   900 0000A212 31F6                <1> 	xor 	esi, esi
   901                              <1> 		; clr r1
   902                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
   903 0000A214 46                  <1> 	inc	esi
   904                              <1> 		; inc r1
   905 0000A215 80BE[07DD0000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
   906                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
   907 0000A21C 760B                <1> 	jna	short sysfork_2	
   908                              <1> 		; beq 1f / it's unused so branch
   909 0000A21E 6683FE10            <1> 	cmp	si, nproc
   910                              <1> 		; cmp r1,$nproc / all processes checked
   911 0000A222 72F0                <1> 	jb	short sysfork_1
   912                              <1> 		; blt 1b / no, branch back
   913                              <1> 	;
   914                              <1> 	; Retro UNIX 8086 v1. modification:
   915                              <1> 	;	Parent process returns from 'sysfork' to address 
   916                              <1> 	;	which is just after 'sysfork' system call in parent
   917                              <1> 	;	process. Child process returns to address which is put
   918                              <1> 	;	in BX register by parent process for 'sysfork'. 
   919                              <1> 	;
   920                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
   921                              <1> 		             ; / to old process return
   922                              <1> 		; br error1 / no room for a new process
   923 0000A224 E9BBFDFFFF          <1> 	jmp	error
   924                              <1> sysfork_2: ; 1:
   925 0000A229 E8E18EFFFF          <1> 	call	allocate_page
   926 0000A22E 0F82B0FDFFFF        <1> 	jc	error
   927 0000A234 50                  <1> 	push	eax   ; UPAGE (user structure page) address
   928                              <1> 	; Retro UNIX 386 v1 modification!
   929 0000A235 E8DE90FFFF          <1> 	call	duplicate_page_dir
   930                              <1> 		; EAX = New page directory 
   931 0000A23A 730B                <1> 	jnc	short sysfork_3
   932 0000A23C 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
   933 0000A23D E8A590FFFF          <1> 	call 	deallocate_page
   934 0000A242 E99DFDFFFF          <1> 	jmp	error
   935                              <1> sysfork_3:
   936                              <1> 	; Retro UNIX 386 v1 modification !
   937 0000A247 56                  <1> 	push	esi
   938 0000A248 E830170000          <1> 	call	wswap ; save current user (u) structure, user registers
   939                              <1> 		      ; and interrupt return components (for IRET)
   940 0000A24D 8705[D9DF0000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
   941 0000A253 A3[DDDF0000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
   942 0000A258 5E                  <1> 	pop	esi
   943 0000A259 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
   944                              <1> 		; [u.usp] = esp
   945 0000A25A 89F7                <1> 	mov	edi, esi
   946 0000A25C 66C1E702            <1> 	shl	di, 2
   947 0000A260 8987[14DD0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
   948 0000A266 A3[D0DF0000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
   949                              <1> 	; 28/08/2015
   950 0000A26B 0FB605[CFDF0000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
   951                              <1> 		; movb u.uno,-(sp) / save parent process number
   952 0000A272 89C7                <1> 	mov	edi, eax
   953 0000A274 50                  <1>         push	eax ; ** 
   954 0000A275 8A87[D7DC0000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
   955                              <1> 	; 18/09/2015
   956                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
   957                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
   958 0000A27B 668986[D7DC0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
   959                              <1> 				   ; ah - reset child's wait channel	
   960 0000A282 89F0                <1> 	mov	eax, esi
   961 0000A284 A2[CFDF0000]        <1> 	mov	[u.uno], al ; child process number
   962                              <1> 		;movb r1,u.uno / set child process number to r1
   963 0000A289 FE86[07DD0000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
   964                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
   965                              <1> 				; / process to active status
   966                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
   967                              <1> 			      ; / control tty buffer in r2
   968                              <1>                 ; beq 2f / branch, if no such tty assigned
   969                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
   970                              <1> 	; 2:
   971 0000A28F 53                  <1> 	push	ebx  ; * return address for the child process
   972                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
   973                              <1> 	; (Retro UNIX 8086 v1 modification!)
   974                              <1> 		; mov $runq+4,r2
   975 0000A290 E83E170000          <1> 	call	putlu 
   976                              <1>  		; jsr r0,putlu / put child process on lowest priority 
   977                              <1> 			   ; / run queue
   978 0000A295 66D1E6              <1> 	shl	si, 1
   979                              <1> 		; asl r1 / multiply r1 by 2 to get index 
   980                              <1> 		       ; / into p.pid table
   981 0000A298 66FF05[6EDF0000]    <1> 	inc	word [mpid]
   982                              <1> 		; inc mpid / increment m.pid; get a new process name
   983 0000A29F 66A1[6EDF0000]      <1> 	mov	ax, [mpid]
   984 0000A2A5 668986[76DC0000]    <1> 	mov	[esi+p.pid-2], ax
   985                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
   986                              <1> 				    ; / in child process' name slot
   987 0000A2AC 5A                  <1> 	pop	edx  ; * return address for the child process
   988                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
   989 0000A2AD 5B                  <1>   	pop	ebx  ; **
   990                              <1> 	;mov	ebx, [esp] ; ** parent process number
   991                              <1> 		; movb (sp),r2 / put parent process number in r2
   992 0000A2AE 66D1E3              <1> 	shl 	bx, 1
   993                              <1> 		;asl r2 / multiply by 2 to get index into below tables
   994                              <1> 	;movzx eax, word [ebx+p.pid-2]
   995 0000A2B1 668B83[76DC0000]    <1> 	mov	ax, [ebx+p.pid-2]
   996                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
   997                              <1> 				   ; / process
   998 0000A2B8 668986[96DC0000]    <1> 	mov	[esi+p.ppid-2], ax
   999                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  1000                              <1> 			  ; / in parent process slot for child
  1001 0000A2BF A3[80DF0000]        <1> 	mov	[u.r0], eax	
  1002                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  1003                              <1> 			     ; / at location where r0 was saved
  1004 0000A2C4 8B2D[78DF0000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1005 0000A2CA 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  1006                              <1> 			   ; * return address for the child process
  1007                              <1> 		; mov $sysret1,-(sp) /
  1008                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  1009                              <1> 			      ; / user is swapped out
  1010                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  1011                              <1> 	; 04/09/2015 - 01/09/2015
  1012                              <1> 	; [u.usp] = esp
  1013 0000A2CD 68[04A00000]        <1> 	push	sysret ; ***
  1014 0000A2D2 8925[7CDF0000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1015                              <1> 			     ; (for child process)	
  1016 0000A2D8 31C0                <1> 	xor 	eax, eax
  1017 0000A2DA 66A3[B0DF0000]      <1> 	mov 	[u.ttyp], ax ; 0
  1018                              <1> 	;
  1019 0000A2E0 E898160000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  1020                              <1> 		;jsr r0,wswap / put child process out on drum
  1021                              <1> 		;jsr r0,unpack / unpack user stack
  1022                              <1> 		;mov u.usp,sp / restore user stack pointer
  1023                              <1> 		; tst (sp)+ / bump stack pointer
  1024                              <1> 	; Retro UNIX 386 v1 modification !
  1025 0000A2E5 58                  <1> 	pop	eax ; ***
  1026 0000A2E6 66D1E3              <1> 	shl	bx, 1
  1027 0000A2E9 8B83[14DD0000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1028 0000A2EF E8B2160000          <1> 	call	rswap ; restore parent process 'u' structure, 
  1029                              <1> 		      ; registers and return address (for IRET)
  1030                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  1031 0000A2F4 0FB705[6EDF0000]    <1>         movzx   eax, word [mpid]
  1032 0000A2FB A3[80DF0000]        <1> 	mov	[u.r0], eax
  1033                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  1034                              <1> 			       ; / where r0 was saved
  1035                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  1036                              <1> 			          ; / process return
  1037                              <1> 	;xor	ebx, ebx
  1038 0000A300 31F6                <1> 	xor     esi, esi
  1039                              <1> 		;clr r1
  1040                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  1041                              <1> 	      ; / opened by the parent process
  1042                              <1> 	; 01/09/2015
  1043                              <1> 	;xor	bh, bh
  1044                              <1> 	;mov 	bl, [esi+u.fp]
  1045 0000A302 8A86[86DF0000]      <1> 	mov 	al, [esi+u.fp]
  1046                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  1047                              <1>         ;or      bl, bl
  1048 0000A308 08C0                <1> 	or	al, al
  1049 0000A30A 740D                <1> 	jz	short sysfork_5	
  1050                              <1> 		; beq 2f / file has not been opened by parent, 
  1051                              <1> 		       ; / so branch
  1052 0000A30C B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1053 0000A30E F6E4                <1> 	mul	ah
  1054                              <1> 	;movzx	ebx, ax
  1055 0000A310 6689C3              <1> 	mov	bx, ax
  1056                              <1> 	;shl     bx, 3
  1057                              <1> 		; asl r2 / multiply by 8
  1058                              <1>        		; asl r2 / to get index into fsp table
  1059                              <1>        		; asl r2
  1060 0000A313 FE83[56DD0000]      <1>   	inc     byte [ebx+fsp-2]
  1061                              <1> 		; incb fsp-2(r2) / increment number of processes
  1062                              <1> 			     ; / using file, because child will now be
  1063                              <1> 			     ; / using this file
  1064                              <1> sysfork_5: ; 2:
  1065 0000A319 46                  <1>         inc     esi
  1066                              <1> 		; inc r1 / get next open file
  1067 0000A31A 6683FE0A            <1>         cmp     si, 10
  1068                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1069                              <1> 			  ; / can be opened
  1070 0000A31E 72E2                <1> 	jb	short sysfork_4	
  1071                              <1> 		; blt 1b / check next entry
  1072 0000A320 E9DFFCFFFF          <1> 	jmp	sysret
  1073                              <1> 		; br sysret1
  1074                              <1> 
  1075                              <1> sysread: ; < read from file >
  1076                              <1> 	; 13/05/2015
  1077                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1078                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1079                              <1> 	;
  1080                              <1> 	; 'sysread' is given a buffer to read into and the number of
  1081                              <1> 	; characters to be read. If finds the file from the file
  1082                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  1083                              <1> 	; is returned from a successful open call (sysopen).
  1084                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  1085                              <1> 	; is read into core via 'readi'.
  1086                              <1> 	;
  1087                              <1> 	; Calling sequence:
  1088                              <1> 	;	sysread; buffer; nchars
  1089                              <1> 	; Arguments:
  1090                              <1> 	;	buffer - location of contiguous bytes where 
  1091                              <1> 	;		 input will be placed.
  1092                              <1> 	;	nchars - number of bytes or characters to be read.
  1093                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1094                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  1095                              <1> 	; ...............................................................
  1096                              <1> 	;				
  1097                              <1> 	; Retro UNIX 8086 v1 modification: 
  1098                              <1> 	;       'sysread' system call has three arguments; so,
  1099                              <1> 	;	* 1st argument, file descriptor is in BX register
  1100                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1101                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1102                              <1> 	;
  1103                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1104                              <1> 	;	to the user with number of bytes read. 
  1105                              <1> 	;
  1106 0000A325 E83D000000          <1> 	call	rw1
  1107 0000A32A 0F82B4FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1108                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
  1109 0000A330 F6C480              <1> 	test	ah, 80h
  1110                              <1> 		; tst r1 / negative i-number?
  1111 0000A333 0F85ABFCFFFF        <1> 	jnz	error
  1112                              <1> 		; ble error1 / yes, error 1 to read
  1113                              <1> 			   ; / it should be positive
  1114 0000A339 E8F5120000          <1> 	call	readi
  1115                              <1> 		; jsr r0,readi / read data into core
  1116 0000A33E EB18                <1> 	jmp	short rw0
  1117                              <1> 		; br 1f
  1118                              <1> syswrite: ; < write to file >
  1119                              <1> 	; 13/05/2015
  1120                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1121                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1122                              <1> 	;
  1123                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  1124                              <1> 	; and the number of characters to write. If finds the file
  1125                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  1126                              <1> 	; descriptor is returned from a successful open or create call
  1127                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  1128                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  1129                              <1> 	;
  1130                              <1> 	; Calling sequence:
  1131                              <1> 	;	syswrite; buffer; nchars
  1132                              <1> 	; Arguments:
  1133                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  1134                              <1> 	;	nchars - number of characters to be written.
  1135                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1136                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  1137                              <1> 	; ...............................................................
  1138                              <1> 	;				
  1139                              <1> 	; Retro UNIX 8086 v1 modification: 
  1140                              <1> 	;       'syswrite' system call has three arguments; so,
  1141                              <1> 	;	* 1st argument, file descriptor is in BX register
  1142                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1143                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1144                              <1> 	;
  1145                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1146                              <1> 	;	to the user with number of bytes written. 
  1147                              <1> 	;
  1148 0000A340 E822000000          <1> 	call	rw1
  1149 0000A345 0F8299FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1150                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
  1151 0000A34B F6C480              <1>         test	ah, 80h
  1152                              <1> 		; tst r1 / positive i-number ?
  1153 0000A34E 744E                <1>         jz	short rw3 ; 13/05/2015
  1154                              <1> 	;jz	error
  1155                              <1> 		; bge error1 / yes, error 1 
  1156                              <1> 			   ; / negative i-number means write
  1157 0000A350 66F7D8              <1>         neg	ax
  1158                              <1> 		; neg r1 / make it positive
  1159 0000A353 E813170000          <1> 	call	writei
  1160                              <1>         	; jsr r0,writei / write data
  1161                              <1> rw0: ; 1:
  1162 0000A358 A1[A8DF0000]        <1>         mov	eax, [u.nread]
  1163 0000A35D A3[80DF0000]        <1> 	mov	[u.r0], eax
  1164                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  1165                              <1> 				  ; / into (u.r0)
  1166 0000A362 E99DFCFFFF          <1> 	jmp	sysret
  1167                              <1>         	; br sysret1
  1168                              <1> rw1:	
  1169                              <1> 	; 14/05/2015
  1170                              <1> 	; 13/05/2015
  1171                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1172                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  1173                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
  1174                              <1> 	;
  1175                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
  1176                              <1> 				;(in the user's virtual memory space)
  1177                              <1> 	;mov	[u.count], edx 
  1178                              <1> 		; jsr r0,arg; u.base / get buffer pointer
  1179                              <1>         	; jsr r0,arg; u.count / get no. of characters
  1180                              <1> 	;;mov	eax, ebx ; file descriptor
  1181                              <1> 		; mov *u.r0,r1 / put file descriptor 
  1182                              <1> 		             ; / (index to u.fp table) in r1
  1183                              <1> 	; 13/05/2015
  1184 0000A367 C705[80DF0000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  1184 0000A36F 0000                <1>
  1185                              <1> 	;
  1186                              <1> 	;; call	getf
  1187                              <1>         ; eBX = File descriptor
  1188 0000A371 E8D6080000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
  1189                              <1> 		; jsr r0,getf / get i-number of the file in r1
  1190                              <1> 	; AX = I-number of the file ; negative i-number means write
  1191                              <1> 	; 13/05/2015
  1192 0000A376 6683F801            <1> 	cmp 	ax, 1
  1193 0000A37A 7217                <1> 	jb	short rw2
  1194                              <1> 	;
  1195 0000A37C 890D[A0DF0000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  1196                              <1> 				;(in the user's virtual memory space)
  1197 0000A382 8915[A4DF0000]      <1> 	mov	[u.count], edx 
  1198                              <1> 	; 14/05/2015
  1199 0000A388 C705[D5DF0000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  1199 0000A390 0000                <1>
  1200 0000A392 C3                  <1> 	retn
  1201                              <1>         	; rts r0
  1202                              <1> rw2:
  1203                              <1> 	; 13/05/2015
  1204 0000A393 C705[D5DF0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1204 0000A39B 0000                <1>
  1205 0000A39D C3                  <1> 	retn
  1206                              <1> rw3: 
  1207                              <1> 	; 13/05/2015
  1208 0000A39E C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1208 0000A3A6 0000                <1>
  1209 0000A3A8 F9                  <1> 	stc
  1210 0000A3A9 C3                  <1> 	retn
  1211                              <1> 
  1212                              <1> sysopen: ;<open file>
  1213                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1214                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  1215                              <1> 	;
  1216                              <1> 	; 'sysopen' opens a file in following manner:
  1217                              <1> 	;    1) The second argument in a sysopen says whether to
  1218                              <1> 	;	open the file ro read (0) or write (>0).
  1219                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  1220                              <1> 	;    3) The file is opened by 'iopen'.
  1221                              <1> 	;    4) Next housekeeping is performed on the fsp table
  1222                              <1> 	;	and the user's open file list - u.fp.
  1223                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  1224                              <1> 	;	b) An entry for the file is created in the fsp table.
  1225                              <1> 	;	c) The number of this entry is put on u.fp list.
  1226                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  1227                              <1> 	;	   to by u.r0.
  1228                              <1> 	;
  1229                              <1> 	; Calling sequence:
  1230                              <1> 	;	sysopen; name; mode
  1231                              <1> 	; Arguments:
  1232                              <1> 	;	name - file name or path name
  1233                              <1> 	;	mode - 0 to open for reading
  1234                              <1> 	;	       1 to open for writing
  1235                              <1> 	; Inputs: (arguments)
  1236                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  1237                              <1> 	;		  is put into r0's location on the stack.	
  1238                              <1> 	; ...............................................................
  1239                              <1> 	;				
  1240                              <1> 	; Retro UNIX 8086 v1 modification: 
  1241                              <1> 	;       'sysopen' system call has two arguments; so,
  1242                              <1> 	;	* 1st argument, name is pointed to by BX register
  1243                              <1> 	;	* 2nd argument, mode is in CX register
  1244                              <1> 	;
  1245                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1246                              <1> 	;	to the user with the file descriptor/number 
  1247                              <1> 	;	(index to u.fp list).
  1248                              <1> 	;
  1249                              <1> 	;call	arg2
  1250                              <1> 	; * name - 'u.namep' points to address of file/path name
  1251                              <1> 	;          in the user's program segment ('u.segmnt')
  1252                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1253                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1254                              <1> 	;          which is on top of stack.
  1255                              <1> 	;
  1256                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  1257                              <1> 	;
  1258                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  1259                              <1> 
  1260 0000A3AA 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  1261 0000A3B0 6651                <1> 	push	cx
  1262 0000A3B2 E8CC080000          <1> 	call	namei
  1263                              <1> 		; jsr r0,namei / i-number of file in r1
  1264                              <1>      	;and	ax, ax
  1265                              <1> 	;jz	error ; File not found
  1266 0000A3B7 723B                <1> 	jc	short fnotfound ; 14/05/2015
  1267                              <1> 	;jc	error ; 27/05/2013
  1268                              <1> 		; br  error2 / file not found
  1269 0000A3B9 665A                <1>    	pop	dx ; mode
  1270 0000A3BB 6652                <1> 	push	dx
  1271                              <1> 	;or	dx, dx
  1272 0000A3BD 08D2                <1> 	or	dl, dl
  1273                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
  1274                              <1> 		         ; / 0 means, open for read)
  1275 0000A3BF 7403                <1> 	jz	short sysopen_0
  1276                              <1> 		; beq 1f / yes, leave i-number positive
  1277                              <1> syscreat_0: ; 27/12/2015
  1278 0000A3C1 66F7D8              <1> 	neg	ax
  1279                              <1>         	; neg r1 / open for writing so make i-number negative
  1280                              <1> sysopen_0: ;1:
  1281 0000A3C4 E8A3160000          <1> 	call	iopen
  1282                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
  1283 0000A3C9 665A                <1> 	pop	dx
  1284                              <1> 	;and	dx, dx
  1285 0000A3CB 20D2                <1> 	and	dl, dl
  1286                              <1>         	; tst (sp)+ / pop the stack and test the mode
  1287 0000A3CD 7403                <1> 	jz	short sysopen_2
  1288                              <1>         	; beq op1 / is open for read op1
  1289                              <1> sysopen_1: ;op0:
  1290 0000A3CF 66F7D8              <1> 	neg	ax
  1291                              <1>         	; neg r1 
  1292                              <1> 		     ;/ make i-number positive if open for writing [???]
  1293                              <1> 	;; NOTE: iopen always make i-number positive.
  1294                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
  1295                              <1> sysopen_2: ;op1:
  1296 0000A3D2 31F6                <1>         xor     esi, esi
  1297                              <1>         	; clr r2 / clear registers
  1298 0000A3D4 31DB                <1>         xor     ebx, ebx
  1299                              <1> 		; clr r3
  1300                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  1301 0000A3D6 389E[86DF0000]      <1>         cmp     [esi+u.fp], bl ; 0
  1302                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  1303 0000A3DC 7625                <1>         jna      short sysopen_4
  1304                              <1> 		; beq 1f / if byte in list is 0 branch
  1305 0000A3DE 46                  <1>         inc     esi
  1306                              <1> 		; inc r2 / bump r2 so next byte can be checked
  1307 0000A3DF 6683FE0A            <1>         cmp     si, 10
  1308                              <1> 		; cmp r2,$10. / reached end of list?
  1309 0000A3E3 72F1                <1> 	jb	short sysopen_3
  1310                              <1> 		; blt 1b / no, go back
  1311                              <1> toomanyf:
  1312                              <1> 	; 14/05/2015
  1313 0000A3E5 C705[D5DF0000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  1313 0000A3ED 0000                <1>
  1314 0000A3EF E9F0FBFFFF          <1> 	jmp	error
  1315                              <1>         	; br error2 / yes, error (no files open)
  1316                              <1> fnotfound: 
  1317                              <1> 	; 14/05/2015
  1318 0000A3F4 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  1318 0000A3FC 0000                <1>
  1319 0000A3FE E9E1FBFFFF          <1> 	jmp	error
  1320                              <1> 
  1321                              <1> sysopen_4: ; 1:
  1322 0000A403 6683BB[58DD0000]00  <1>         cmp     word [ebx+fsp], 0
  1323                              <1> 		; tst fsp(r3) / scan fsp entries
  1324 0000A40B 7610                <1>         jna     short sysopen_5
  1325                              <1> 		; beq 1f / if 0 branch
  1326                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
  1327 0000A40D 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
  1328                              <1> 		; add $8.,r3 / add 8 to r3 
  1329                              <1> 			; / to bump it to next entry mfsp table
  1330 0000A411 6681FBF401          <1>         cmp     bx, nfiles*10
  1331                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  1332 0000A416 72EB                <1> 	jb	short sysopen_4
  1333                              <1>        		; blt 1b / no, back
  1334 0000A418 E9C7FBFFFF          <1> 	jmp	error
  1335                              <1>         	; br error2 / yes, error
  1336                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
  1337 0000A41D 668983[58DD0000]    <1>         mov     [ebx+fsp], ax
  1338                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
  1339                              <1> 			; / into next available entry in fsp table,
  1340 0000A424 668B3D[66DF0000]    <1> 	mov	di, [cdev] ; word ? byte ?
  1341 0000A42B 6689BB[5ADD0000]    <1>         mov     [ebx+fsp+2], di ; device number
  1342                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
  1343 0000A432 31FF                <1>         xor	edi, edi
  1344 0000A434 89BB[5CDD0000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
  1345                              <1> 		; clr fsp+4(r3)
  1346 0000A43A 6689BB[60DD0000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
  1347                              <1>        		; clr fsp+6(r3) / clear the next two words
  1348 0000A441 89D8                <1>   	mov	eax, ebx
  1349 0000A443 B30A                <1> 	mov	bl, 10
  1350 0000A445 F6F3                <1> 	div	bl 
  1351                              <1> 		; asr r3
  1352                              <1> 		; asr r3 / divide by 8 
  1353                              <1> 		; asr r3 ; / to get number of the fsp entry-1
  1354 0000A447 FEC0                <1> 	inc	al
  1355                              <1>         	; inc r3 / add 1 to get fsp entry number
  1356 0000A449 8886[86DF0000]      <1>         mov     [esi+u.fp], al
  1357                              <1> 		; movb r3,u.fp(r2) / move entry number into 
  1358                              <1> 			; / next available slot in u.fp list
  1359 0000A44F 8935[80DF0000]      <1>         mov     [u.r0], esi
  1360                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
  1361                              <1> 			     ; / into r0 loc on stack
  1362 0000A455 E9AAFBFFFF          <1>         jmp	sysret
  1363                              <1> 		; br sysret2
  1364                              <1> 
  1365                              <1> 	;
  1366                              <1> 	; 'fsp' table (10 bytes/entry)
  1367                              <1> 	; bit 15				   bit 0
  1368                              <1> 	; ---|-------------------------------------------
  1369                              <1> 	; r/w|		i-number of open file
  1370                              <1> 	; ---|-------------------------------------------
  1371                              <1> 	;		   device number
  1372                              <1> 	; -----------------------------------------------
  1373                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  1374                              <1> 	; -----------------------------------------------
  1375                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  1376                              <1> 	; ----------------------|------------------------
  1377                              <1> 	;  flag that says file 	| number of processes
  1378                              <1> 	;   has been deleted	| that have file open 
  1379                              <1> 	; ----------------------|------------------------
  1380                              <1> 	;
  1381                              <1> 
  1382                              <1> syscreat: ; < create file >
  1383                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  1384                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1385                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  1386                              <1> 	;
  1387                              <1> 	; 'syscreat' called with two arguments; name and mode.
  1388                              <1> 	; u.namep points to name of the file and mode is put
  1389                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  1390                              <1> 	; If the file aready exists, it's mode and owner remain 
  1391                              <1> 	; unchanged, but it is truncated to zero length. If the file
  1392                              <1> 	; did not exist, an i-node is created with the new mode via
  1393                              <1> 	; 'maknod' whether or not the file already existed, it is
  1394                              <1> 	; open for writing. The fsp table is then searched for a free
  1395                              <1> 	; entry. When a free entry is found, proper data is placed
  1396                              <1> 	; in it and the number of this entry is put in the u.fp list.
  1397                              <1> 	; The index to the u.fp (also know as the file descriptor)
  1398                              <1> 	; is put in the user's r0. 			
  1399                              <1> 	;
  1400                              <1> 	; Calling sequence:
  1401                              <1> 	;	syscreate; name; mode
  1402                              <1> 	; Arguments:
  1403                              <1> 	;	name - name of the file to be created
  1404                              <1> 	;	mode - mode of the file to be created
  1405                              <1> 	; Inputs: (arguments)
  1406                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  1407                              <1> 	;		   (the file descriptor of new file)
  1408                              <1> 	; ...............................................................
  1409                              <1> 	;				
  1410                              <1> 	; Retro UNIX 8086 v1 modification: 
  1411                              <1> 	;       'syscreate' system call has two arguments; so,
  1412                              <1> 	;	* 1st argument, name is pointed to by BX register
  1413                              <1> 	;	* 2nd argument, mode is in CX register
  1414                              <1> 	;
  1415                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1416                              <1> 	;	to the user with the file descriptor/number 
  1417                              <1> 	;	(index to u.fp list).
  1418                              <1> 	;
  1419                              <1> 	;call	arg2
  1420                              <1> 	; * name - 'u.namep' points to address of file/path name
  1421                              <1> 	;          in the user's program segment ('u.segmnt')
  1422                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1423                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1424                              <1> 	;          which is on top of stack.
  1425                              <1> 	;
  1426                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
  1427                              <1> 			    ; / on stack
  1428 0000A45A 891D[98DF0000]      <1> 	mov	[u.namep], ebx ; file name address
  1429 0000A460 6651                <1> 	push	cx ; mode
  1430 0000A462 E81C080000          <1> 	call 	namei        	
  1431                              <1> 		; jsr r0,namei / get the i-number
  1432                              <1>         ;and	ax, ax
  1433                              <1> 	;jz	short syscreat_1	       	
  1434 0000A467 721E                <1> 	jc	short syscreat_1
  1435                              <1> 		; br  2f / if file doesn't exist 2f
  1436                              <1> 	; 27/12/2015
  1437 0000A469 6683F829            <1> 	cmp	ax, 41 ; device inode ?
  1438 0000A46D 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
  1439                              <1> 	;
  1440 0000A473 66F7D8              <1> 	neg 	ax
  1441                              <1>         	; neg r1 / if file already exists make i-number 
  1442                              <1> 		       ; / negative (open for writing)
  1443 0000A476 E8F1150000          <1> 	call	iopen
  1444                              <1>         	; jsr r0,iopen /
  1445 0000A47B E8EE150000          <1> 	call	itrunc
  1446                              <1>         	; jsr r0,itrunc / truncate to 0 length
  1447 0000A480 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
  1448 0000A482 E948FFFFFF          <1>         jmp     sysopen_1
  1449                              <1>         	; br op0
  1450                              <1> syscreat_1: ; 2: / file doesn't exist
  1451 0000A487 6658                <1> 	pop	ax
  1452                              <1>         	; mov (sp)+,r1 / put the mode in r1
  1453 0000A489 30E4                <1> 	xor	ah, ah	
  1454                              <1>         	; bic $!377,r1 / clear upper byte
  1455 0000A48B E8C60A0000          <1> 	call 	maknod
  1456                              <1>         	; jsr r0,maknod / make an i-node for this file
  1457 0000A490 66A1[B2DF0000]      <1> 	mov	ax, [u.dirbuf]
  1458                              <1>         	; mov u.dirbuf,r1 / put i-number 
  1459                              <1> 			        ; / for this new file in r1
  1460 0000A496 E934FFFFFF          <1>         jmp     sysopen_1
  1461                              <1>         	; br op0 / open the file
  1462                              <1> 
  1463                              <1> sysmkdir: ; < make directory >
  1464                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1465                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1466                              <1> 	;
  1467                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  1468                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  1469                              <1> 	; The special entries '.' and '..' are not present.
  1470                              <1> 	; Errors are indicated if the directory already exists or		
  1471                              <1> 	; user is not the super user. 
  1472                              <1> 	;
  1473                              <1> 	; Calling sequence:
  1474                              <1> 	;	sysmkdir; name; mode
  1475                              <1> 	; Arguments:
  1476                              <1> 	;	name - points to the name of the directory
  1477                              <1> 	;	mode - mode of the directory
  1478                              <1> 	; Inputs: (arguments)
  1479                              <1> 	; Outputs: -
  1480                              <1> 	;    (sets 'directory' flag to 1; 
  1481                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  1482                              <1> 	; ...............................................................
  1483                              <1> 	;				
  1484                              <1> 	; Retro UNIX 8086 v1 modification: 
  1485                              <1> 	;       'sysmkdir' system call has two arguments; so,
  1486                              <1> 	;	* 1st argument, name is pointed to by BX register
  1487                              <1> 	;	* 2nd argument, mode is in CX register
  1488                              <1> 	;
  1489                              <1> 		
  1490                              <1> ; / make a directory
  1491                              <1> 
  1492                              <1> 	;call	arg2
  1493                              <1> 	; * name - 'u.namep' points to address of file/path name
  1494                              <1> 	;          in the user's program segment ('u.segmnt')
  1495                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1496                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1497                              <1> 	;          which is on top of stack.
  1498                              <1> 
  1499                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
  1500                              <1> 			    ; / on stack
  1501 0000A49B 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  1502 0000A4A1 6651                <1> 	push	cx ; mode
  1503 0000A4A3 E8DB070000          <1> 	call	namei
  1504                              <1>         	; jsr r0,namei / get the i-number
  1505                              <1>         	;     br .+4 / if file not found branch around error
  1506                              <1>         ;xor 	ax, ax
  1507                              <1> 	;jnz	error
  1508 0000A4A8 731C                <1> 	jnc	short dir_exists ; 14/05/2015
  1509                              <1> 	;jnc	error	
  1510                              <1> 		; br  error2 / directory already exists (error)
  1511 0000A4AA 803D[CCDF0000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  1512                              <1>         	;tstb u.uid / is user the super user
  1513 0000A4B1 7622                <1> 	jna	short dir_access_err ; 14/05/2015
  1514                              <1> 	;jna	error
  1515                              <1>         	;bne error2 / no, not allowed
  1516 0000A4B3 6658                <1> 	pop	ax
  1517                              <1>         	;mov (sp)+,r1 / put the mode in r1
  1518 0000A4B5 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
  1519                              <1>         	;bic $!317,r1 / all but su and ex
  1520                              <1> 	;or	ax , 4000h ; 1011111111111111b
  1521 0000A4B9 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
  1522                              <1>         	;bis $40000,r1 / directory flag
  1523 0000A4BC E8950A0000          <1> 	call	maknod
  1524                              <1>         	;jsr r0,maknod / make the i-node for the directory
  1525 0000A4C1 E93EFBFFFF          <1> 	jmp	sysret
  1526                              <1>         	;br sysret2 /
  1527                              <1> dir_exists:
  1528                              <1> 	; 14/05/2015
  1529 0000A4C6 C705[D5DF0000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
  1529 0000A4CE 0000                <1>
  1530 0000A4D0 E90FFBFFFF          <1> 	jmp	error
  1531                              <1> dir_access_err:
  1532                              <1> 	; 14/05/2015
  1533 0000A4D5 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  1533 0000A4DD 0000                <1>
  1534 0000A4DF E900FBFFFF          <1> 	jmp	error
  1535                              <1> 
  1536                              <1> sysclose: ;<close file>
  1537                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1538                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  1539                              <1> 	;
  1540                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  1541                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  1542                              <1> 	; is put in r1 and 'fclose' is called.
  1543                              <1> 	;
  1544                              <1> 	; Calling sequence:
  1545                              <1> 	;	sysclose
  1546                              <1> 	; Arguments:
  1547                              <1> 	;	-  
  1548                              <1> 	; Inputs: *u.r0 - file descriptor
  1549                              <1> 	; Outputs: -
  1550                              <1> 	; ...............................................................
  1551                              <1> 	;				
  1552                              <1> 	; Retro UNIX 8086 v1 modification:
  1553                              <1> 	;	 The user/application program puts file descriptor
  1554                              <1> 	;        in BX register as 'sysclose' system call argument.
  1555                              <1> 	; 	 (argument transfer method 1)
  1556                              <1> 
  1557                              <1> 	; / close the file
  1558                              <1> 	
  1559 0000A4E4 89D8                <1> 	mov 	eax, ebx
  1560 0000A4E6 E816070000          <1> 	call 	fclose
  1561                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
  1562                              <1> 		; jsr r0,fclose / close the file
  1563                              <1>                	; br error2 / unknown file descriptor
  1564                              <1> 		; br sysret2
  1565                              <1> 	; 14/05/2015
  1566 0000A4EB 0F8313FBFFFF        <1> 	jnc	sysret
  1567 0000A4F1 C705[D5DF0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1567 0000A4F9 0000                <1>
  1568 0000A4FB E9E4FAFFFF          <1> 	jmp	error
  1569                              <1> 
  1570                              <1> sysemt:
  1571                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1572                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  1573                              <1> 	;
  1574                              <1> 	; Retro UNIX 8086 v1 modification: 
  1575                              <1> 	;	'Enable Multi Tasking'  system call instead 
  1576                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  1577                              <1> 	;
  1578                              <1> 	; Retro UNIX 8086 v1 feature only!
  1579                              <1> 	;	Using purpose: Kernel will start without time-out
  1580                              <1> 	;	(internal clock/timer) functionality.
  1581                              <1> 	;	Then etc/init will enable clock/timer for
  1582                              <1> 	;	multi tasking. (Then it will not be disabled again
  1583                              <1> 	;	except hardware reset/restart.)
  1584                              <1> 	;
  1585                              <1> 
  1586 0000A500 803D[CCDF0000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  1587                              <1> 	;ja	error
  1588 0000A507 0F8780FBFFFF        <1> 	ja	badsys ; 14/05/2015
  1589                              <1> emt_0:
  1590 0000A50D FA                  <1> 	cli
  1591 0000A50E 21DB                <1> 	and	ebx, ebx
  1592 0000A510 7410                <1> 	jz	short emt_2
  1593                              <1> 	; Enable multi tasking -time sharing-
  1594 0000A512 B8[6FBA0000]        <1> 	mov	eax, clock
  1595                              <1> emt_1:
  1596 0000A517 A3[C2070000]        <1> 	mov	[x_timer], eax
  1597 0000A51C FB                  <1> 	sti
  1598 0000A51D E9E2FAFFFF          <1> 	jmp	sysret
  1599                              <1> emt_2:
  1600                              <1> 	; Disable multi tasking -time sharing-
  1601 0000A522 B8[CA070000]        <1> 	mov	eax, u_timer
  1602 0000A527 EBEE                <1> 	jmp	short emt_1
  1603                              <1> 
  1604                              <1> 	; Original UNIX v1 'sysemt' routine
  1605                              <1> ;sysemt:
  1606                              <1>         ;
  1607                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
  1608                              <1> 			 ; / in loc 30
  1609                              <1>         ;cmp    30,$core / was the argument a lower address 
  1610                              <1> 			; / than core
  1611                              <1>         ;blo    1f / yes, rtssym
  1612                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
  1613                              <1> 			; / and less than "ecore"
  1614                              <1>         ;blo    2f / yes, sysret2
  1615                              <1> ;1:
  1616                              <1>         ;mov    $rtssym,30
  1617                              <1> ;2:
  1618                              <1>         ;br     sysret2
  1619                              <1> 
  1620                              <1> sysilgins:
  1621                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1622                              <1> 	; 03/06/2013
  1623                              <1> 	; Retro UNIX 8086 v1 modification: 
  1624                              <1> 	;	not a valid system call ! (not in use)
  1625                              <1> 	;
  1626 0000A529 E95FFBFFFF          <1> 	jmp	badsys
  1627                              <1> 	;jmp	error
  1628                              <1> 	;;jmp 	sysret
  1629                              <1> 
  1630                              <1> 	; Original UNIX v1 'sysemt' routine
  1631                              <1> ;sysilgins: / calculate proper illegal instruction trap address
  1632                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
  1633                              <1> 			  ;/ put it in loc 8.,
  1634                              <1>         ;cmp    10,$core / making it the illegal instruction 
  1635                              <1> 		       ; / trap address
  1636                              <1>         ;blo    1f / is the address a user core address?  
  1637                              <1> 		; / yes, go to 2f
  1638                              <1>         ;cmp    10,$ecore
  1639                              <1>         ;blo    2f
  1640                              <1> ;1:
  1641                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
  1642                              <1> 		    ; / instruction trap address for the system
  1643                              <1> ;2:
  1644                              <1>         ;br     sysret2 / return to the caller via 'sysret'
  1645                              <1> 
  1646                              <1> sysmdate: ; < change the modification time of a file >
  1647                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  1648                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1649                              <1> 	;
  1650                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
  1651                              <1> 	; file into core. The user is checked if he is the owner 
  1652                              <1> 	; or super user. If he is neither an error occurs.
  1653                              <1> 	; 'setimod' is then called to set the i-node modification
  1654                              <1> 	; byte and the modification time, but the modification time
  1655                              <1> 	; is overwritten by whatever get put on the stack during
  1656                              <1> 	; a 'systime' system call. This calls are restricted to
  1657                              <1> 	; the super user.		
  1658                              <1> 	;
  1659                              <1> 	; Calling sequence:
  1660                              <1> 	;	sysmdate; name
  1661                              <1> 	; Arguments:
  1662                              <1> 	;	name - points to the name of file
  1663                              <1> 	; Inputs: (arguments)
  1664                              <1> 	; Outputs: -
  1665                              <1> 	; ...............................................................
  1666                              <1> 	;				
  1667                              <1> 	; Retro UNIX 8086 v1 modification: 
  1668                              <1> 	;	 The user/application program puts address 
  1669                              <1> 	;	 of the file name in BX register 
  1670                              <1> 	;	 as 'sysmdate' system call argument.
  1671                              <1> 	;
  1672                              <1> ; / change the modification time of a file
  1673                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
  1674 0000A52E 891D[98DF0000]      <1>         mov	[u.namep], ebx
  1675 0000A534 E84A070000          <1> 	call	namei
  1676                              <1> 		; jsr r0,namei / get its i-number
  1677 0000A539 0F82B5FEFFFF        <1>         jc	fnotfound ; file not found !
  1678                              <1> 	;jc	error       
  1679                              <1> 		; br error2 / no, such file
  1680 0000A53F E823150000          <1> 	call	iget
  1681                              <1> 		; jsr r0,iget / get i-node into core
  1682 0000A544 A0[CCDF0000]        <1> 	mov	al, [u.uid]
  1683 0000A549 3A05[5BDC0000]      <1> 	cmp	al, [i.uid]
  1684                              <1>         	; cmpb u.uid,i.uid / is user same as owner
  1685 0000A54F 7413                <1> 	je	short mdate_1
  1686                              <1>         	; beq 1f / yes
  1687 0000A551 20C0                <1> 	and	al, al
  1688                              <1> 		; tstb u.uid / no, is user the super user
  1689                              <1> 	;jnz	error
  1690                              <1> 		; bne error2 / no, error
  1691 0000A553 740F                <1> 	jz	short mdate_1
  1692 0000A555 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1692 0000A55D 0000                <1>
  1693 0000A55F E980FAFFFF          <1> 	jmp	error
  1694                              <1> mdate_1: ;1:
  1695 0000A564 E807150000          <1> 	call	setimod
  1696                              <1>         	; jsr r0,setimod / fill in modification data,
  1697                              <1> 		               ; / time etc.
  1698 0000A569 BE[22CF0000]        <1> 	mov	esi, p_time
  1699 0000A56E BF[72DC0000]        <1> 	mov	edi, i.mtim
  1700 0000A573 A5                  <1> 	movsd
  1701                              <1> 		; mov 4(sp),i.mtim / move present time to
  1702                              <1>         	; mov 2(sp),i.mtim+2 / modification time
  1703 0000A574 E98BFAFFFF          <1>         jmp	sysret
  1704                              <1> 		; br sysret2
  1705                              <1> 
  1706                              <1> sysstty: ; < set tty status and mode >
  1707                              <1> 	; 17/11/2015
  1708                              <1> 	; 12/11/2015
  1709                              <1> 	; 29/10/2015
  1710                              <1> 	; 17/10/2015
  1711                              <1> 	; 13/10/2015
  1712                              <1> 	; 29/06/2015
  1713                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
  1714                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  1715                              <1> 	;
  1716                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
  1717                              <1> 	; whose file descriptor is in (u.r0).
  1718                              <1> 	;
  1719                              <1> 	; Calling sequence:
  1720                              <1> 	;	sysstty; arg
  1721                              <1> 	; Arguments:
  1722                              <1> 	;	arg - address of 3 consequitive words that contain
  1723                              <1> 	;	      the source of status data	
  1724                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
  1725                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  1726                              <1> 	; ...............................................................
  1727                              <1> 	;	
  1728                              <1> 	; Retro UNIX 8086 v1 modification: 
  1729                              <1> 	;	'sysstty' system call will set the tty
  1730                              <1> 	;	(clear keyboard buffer and set cursor position)
  1731                              <1> 	;	 in following manner:
  1732                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
  1733                              <1> 	;
  1734                              <1> 	; Inputs:
  1735                              <1> 	;	BX = 0 --> means
  1736                              <1> 	;	   If CL = FFh
  1737                              <1> 	;	      set cursor position for console tty, only 
  1738                              <1> 	;	      CH will be ignored (char. will not be written)	
  1739                              <1> 	;	   If CH = 0 (CL < FFh)
  1740                              <1> 	;	      set console tty for (current) process
  1741                              <1> 	;	      CL = tty number (0 to 9)
  1742                              <1> 	;	      (If CH = 0, character will not be written)			
  1743                              <1> 	;          If CH > 0 (CL < FFh)	
  1744                              <1> 	;             CL = tty number (0 to 9)
  1745                              <1> 	;	      CH = character will be written
  1746                              <1> 	;	        at requested cursor position (in DX)	
  1747                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
  1748                              <1>   	;		(only tty number 0 to 7) 
  1749                              <1> 	;          DL = communication parameters (for serial ports) 
  1750                              <1> 	;	        (only for COM1 and COM2 serial ports)
  1751                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
  1752                              <1> 	;			or set cursor position	
  1753                              <1> 	;	   DH = 0FFh -> DL is not valid
  1754                              <1> 	;		do not set serial port parameters 
  1755                              <1> 	;		or do not set cursor position
  1756                              <1> 	;
  1757                              <1> 	;	BX > 0 --> points to name of tty
  1758                              <1> 	;    	   CH > 0 -->
  1759                              <1> 	;		CH = character will be written in current 
  1760                              <1> 	;            	cursor position (for tty number from 0 to 7)
  1761                              <1> 	;	     	or character will be sent to serial port
  1762                              <1> 	;	     	(for tty number 8 or 9)
  1763                              <1> 	;		CL = color of the character if tty number < 8.
  1764                              <1> 	;    	   CH = 0 --> Do not write a character, 
  1765                              <1> 	;		set mode (tty 8 to 9) or 
  1766                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
  1767                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
  1768                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
  1769                              <1> 	;		(DL is not valid)
  1770                              <1> 	;	   DL = communication parameters 
  1771                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
  1772                              <1> 	; Outputs:
  1773                              <1> 	;	cf = 0 -> OK
  1774                              <1> 	;	     AL = tty number (0 to 9)
  1775                              <1> 	;	     AH = line status if tty number is 8 or 9
  1776                              <1> 	;	     AH = process number (of the caller) 	
  1777                              <1> 	;	cf = 1 means error (requested tty is not ready)
  1778                              <1> 	;	     AH = FFh if the tty is locked 
  1779                              <1> 	;		  (owned by another process)
  1780                              <1> 	;	        = process number (of the caller) 
  1781                              <1> 	;		  (if < FFh and tty number < 8)
  1782                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  1783                              <1> 	;	     AH = line status if tty number is 8 or 9
  1784                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
  1785                              <1> 	;
  1786                              <1> 	; 27/06/2015 (32 bit modifications)
  1787                              <1> 	; 14/01/2014
  1788 0000A579 31C0                <1> 	xor 	eax, eax
  1789 0000A57B 6648                <1> 	dec	ax ; 17/10/2015
  1790 0000A57D A3[80DF0000]        <1> 	mov	[u.r0], eax ; 0FFFFh
  1791 0000A582 21DB                <1> 	and	ebx, ebx
  1792 0000A584 0F85CB000000        <1>         jnz     sysstty_6
  1793                              <1> ; set console tty
  1794                              <1> 	; 29/10/2015
  1795                              <1> 	; 17/01/2014 
  1796 0000A58A 80F909              <1> 	cmp	cl, 9
  1797 0000A58D 7613                <1> 	jna	short sysstty_0
  1798                              <1> 	; 17/11/2015
  1799 0000A58F 80F9FF              <1> 	cmp	cl, 0FFh
  1800 0000A592 7202                <1> 	jb	short sysstty_13
  1801 0000A594 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
  1802                              <1> sysstty_13:
  1803 0000A596 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno] ; process number
  1804 0000A59C 8A8B[D7DC0000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
  1805                              <1> sysstty_0:
  1806                              <1> 	; 29/06/2015
  1807 0000A5A2 6652                <1> 	push	dx
  1808 0000A5A4 6651                <1> 	push	cx
  1809 0000A5A6 30D2                <1> 	xor 	dl, dl	; sysstty call sign
  1810 0000A5A8 88C8                <1> 	mov	al, cl
  1811 0000A5AA A2[80DF0000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
  1812 0000A5AF E8BD140000          <1> 	call	ottyp
  1813 0000A5B4 6659                <1> 	pop	cx
  1814 0000A5B6 665A                <1> 	pop	dx
  1815                              <1> 	;
  1816 0000A5B8 7257                <1> 	jc	short sysstty_pd_err
  1817                              <1> 	;
  1818 0000A5BA 80F908              <1> 	cmp	cl, 8
  1819 0000A5BD 7222                <1> 	jb	short sysstty_2
  1820                              <1> 	;
  1821 0000A5BF 80FEFF              <1> 	cmp	dh, 0FFh
  1822 0000A5C2 741D                <1> 	je	short sysstty_2
  1823                              <1> 		; set communication parameters for serial ports
  1824                              <1> 	; 29/10/2015
  1825 0000A5C4 88D4                <1> 	mov	ah, dl ; communication parameters
  1826                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
  1827                              <1> 		;			 THRE int + RDA int 
  1828                              <1> 		; ah = 23h = 00100011b = 9600 baud,
  1829                              <1> 		;			 THRE int + RDA int 
  1830 0000A5C6 28C0                <1> 	sub	al, al ; 0
  1831                              <1> 	; 12/07/2014
  1832 0000A5C8 80F909              <1> 	cmp	cl, 9
  1833 0000A5CB 7202                <1> 	jb	short sysstty_1
  1834 0000A5CD FEC0                <1> 	inc	al
  1835                              <1> sysstty_1:
  1836 0000A5CF 6651                <1> 	push	cx
  1837                              <1> 	; 29/06/2015	
  1838 0000A5D1 E857170000          <1> 	call 	sp_setp ; Set serial port communication parameters
  1839 0000A5D6 66890D[81DF0000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
  1840                              <1> 			     ; Modem status (EAX bits 16 to 23)
  1841 0000A5DD 6659                <1> 	pop	cx
  1842 0000A5DF 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
  1843                              <1> sysstty_2:
  1844                              <1> 	; 17/01/2014
  1845 0000A5E1 20ED                <1> 	and	ch, ch 	; set cursor position 
  1846                              <1> 			; or comm. parameters ONLY
  1847 0000A5E3 750D                <1> 	jnz	short sysstty_3
  1848 0000A5E5 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  1849 0000A5EC 888B[D7DC0000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
  1850                              <1> sysstty_3:
  1851                              <1> 	; 16/01/2014
  1852 0000A5F2 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
  1853                              <1> 	; 17/11/2015
  1854 0000A5F4 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
  1855 0000A5F6 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
  1856 0000A5F8 0F86C5000000        <1>         jna     sysstty_9
  1857                              <1> sysstty_12:
  1858                              <1> 	;; BX = 0, CL = 8 or CL = 9
  1859                              <1> 	; (Set specified serial port as console tty port)
  1860                              <1> 	; CH = character to be written
  1861                              <1> 	; 15/04/2014
  1862                              <1> 	; CH = 0 --> initialization only
  1863                              <1> 	; AL = character
  1864                              <1> 	; 26/06/2014
  1865 0000A5FE 880D[D4DF0000]      <1> 	mov	[u.ttyn], cl
  1866                              <1> 	; 12/07/2014
  1867 0000A604 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
  1868 0000A606 20C0                <1> 	and	al, al
  1869 0000A608 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
  1870                              <1>  	; 04/07/2014
  1871 0000A60A E864140000          <1> 	call 	sndc
  1872                              <1> 	; 12/07/2014
  1873 0000A60F EB1B                <1> 	jmp	short sysstty_5
  1874                              <1> sysstty_pd_err: ; 29/06/2015
  1875                              <1> 	; 'permission denied !' error
  1876 0000A611 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
  1876 0000A619 0000                <1>
  1877 0000A61B E9C4F9FFFF          <1> 	jmp	error
  1878                              <1> sysstty_4:
  1879                              <1> 	; 12/07/2014
  1880                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
  1881 0000A620 88E0                <1> 	mov	al, ah ; 29/06/2015
  1882 0000A622 2C08                <1> 	sub	al, 8
  1883                              <1> 	; 27/06/2015
  1884 0000A624 E8FC160000          <1> 	call	sp_status ; get serial port status
  1885                              <1> 	; AL = Line status, AH = Modem status
  1886                              <1> 	; 12/11/2015
  1887 0000A629 3C80                <1> 	cmp	al, 80h
  1888 0000A62B F5                  <1> 	cmc
  1889                              <1> sysstty_5:
  1890 0000A62C 66A3[81DF0000]      <1> 	mov	[u.r0+1], ax ; ah = line status
  1891                              <1> 		     ; EAX bits 16-23 = modem status	
  1892 0000A632 9C                  <1> 	pushf
  1893 0000A633 30D2                <1> 	xor	dl, dl ; sysstty call sign
  1894 0000A635 A0[D4DF0000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
  1895 0000A63A E833140000          <1> 	call	cttyp
  1896 0000A63F 9D                  <1> 	popf
  1897 0000A640 0F83BEF9FFFF        <1> 	jnc	sysret	; time out error 
  1898                              <1> 
  1899                              <1> sysstty_tmout_err:
  1900 0000A646 C705[D5DF0000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
  1900 0000A64E 0000                <1>
  1901 0000A650 E98FF9FFFF          <1> 	jmp	error
  1902                              <1> sysstty_6:
  1903 0000A655 6652                <1> 	push	dx
  1904 0000A657 6651                <1> 	push	cx
  1905 0000A659 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  1906 0000A65F E81F060000          <1> 	call	namei
  1907 0000A664 6659                <1> 	pop	cx
  1908 0000A666 665A                <1> 	pop	dx
  1909 0000A668 720E                <1> 	jc	short sysstty_inv_dn
  1910                              <1> 	;
  1911 0000A66A 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
  1912 0000A66E 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
  1913                              <1> 	;
  1914 0000A670 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
  1915                              <1> 		       ; /dev/COM1, /dev/COM2
  1916 0000A672 7213                <1> 	jb	short sysstty_7
  1917 0000A674 2C0A                <1> 	sub	al, 10
  1918 0000A676 EB20                <1> 	jmp	short sysstty_8
  1919                              <1> sysstty_inv_dn: 
  1920                              <1> 	; 27/06/2015
  1921                              <1> 	; Invalid device name (not a tty) ! error
  1922                              <1> 	; (Device is not a tty or device name not found)
  1923 0000A678 C705[D5DF0000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
  1923 0000A680 0000                <1>
  1924 0000A682 E95DF9FFFF          <1> 	jmp	error 
  1925                              <1> sysstty_7:
  1926 0000A687 3C01                <1> 	cmp	al, 1 ; /dev/tty
  1927 0000A689 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
  1928 0000A68B 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  1929 0000A692 8A83[D7DC0000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
  1930                              <1> sysstty_8:	
  1931 0000A698 A2[80DF0000]        <1> 	mov	[u.r0], al
  1932 0000A69D 6652                <1> 	push	dx
  1933 0000A69F 6650                <1> 	push	ax
  1934 0000A6A1 6651                <1> 	push	cx	
  1935 0000A6A3 E8C9130000          <1> 	call	ottyp
  1936 0000A6A8 6659                <1> 	pop	cx
  1937 0000A6AA 6658                <1> 	pop	ax
  1938 0000A6AC 665A                <1> 	pop	dx
  1939 0000A6AE 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
  1940                              <1> 	; 29/10/2015
  1941 0000A6B4 86E9                <1> 	xchg 	ch, cl
  1942                              <1> 		; cl = character, ch = color code
  1943 0000A6B6 86C1                <1> 	xchg	al, cl
  1944                              <1> 		; al = character, cl = tty number
  1945 0000A6B8 80F907              <1> 	cmp	cl, 7
  1946 0000A6BB 0F873DFFFFFF        <1>         ja      sysstty_12
  1947                              <1> 	;
  1948                              <1> 	; 16/01/2014
  1949 0000A6C1 30FF                <1> 	xor	bh, bh
  1950                              <1> 	;
  1951                              <1> sysstty_9: 	; tty 0 to tty 7
  1952                              <1> 	; al = character
  1953 0000A6C3 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
  1954 0000A6C6 740F                <1> 	je	short sysstty_10
  1955 0000A6C8 6651                <1> 	push	cx
  1956 0000A6CA 6650                <1> 	push	ax	
  1957                              <1> 	; movzx, ebx, cl
  1958 0000A6CC 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
  1959 0000A6CE E88071FFFF          <1> 	call	_set_cpos
  1960 0000A6D3 6658                <1> 	pop	ax
  1961 0000A6D5 6659                <1> 	pop	cx
  1962                              <1> sysstty_10: 
  1963                              <1> 	; 29/10/2015
  1964 0000A6D7 08C0                <1> 	or	al, al ; character
  1965 0000A6D9 740F                <1> 	jz      short sysstty_11 ; al = 0
  1966                              <1> 	; 17/11/2015
  1967 0000A6DB 3CFF                <1> 	cmp	al, 0FFh
  1968 0000A6DD 730B                <1> 	jnb	short sysstty_11
  1969                              <1> 		; ch > 0 and ch < FFh
  1970                              <1> 	; write a character at current cursor position
  1971 0000A6DF 88EC                <1> 	mov	ah, ch ; color/attribute
  1972                              <1> 	; 12/07/2014
  1973 0000A6E1 6651                <1> 	push	cx
  1974 0000A6E3 E8A670FFFF          <1> 	call	_write_c_current
  1975 0000A6E8 6659                <1> 	pop	cx
  1976                              <1> sysstty_11:
  1977                              <1> 	; 14/01/2014
  1978 0000A6EA 30D2                <1> 	xor	dl, dl ; sysstty call sign
  1979                              <1> 	; 18/01/2014
  1980                              <1> 	;movzx	eax, cl ; 27/06/2015
  1981 0000A6EC 88C8                <1> 	mov	al, cl
  1982 0000A6EE E87F130000          <1> 	call	cttyp
  1983 0000A6F3 E90CF9FFFF          <1> 	jmp	sysret
  1984                              <1> 
  1985                              <1> ; Original UNIX v1 'sysstty' routine:
  1986                              <1> ; gtty:
  1987                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
  1988                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
  1989                              <1> 	; 		/ r2 has source
  1990                              <1>         ;mov    r2,-(sp)
  1991                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
  1992                              <1> ;1: / flush the clist wait till typewriter is quiescent
  1993                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
  1994                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
  1995                              <1>         ;mov    $240,*$ps / set processor priority to 5
  1996                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
  1997                              <1>         ;       br .+4 / list empty, skip branch
  1998                              <1>         ;br     1b / get another character until list is empty
  1999                              <1>         ;mov    0b,r1 / move cc offset to r1
  2000                              <1>         ;inc    r1 / bump it for output clist
  2001                              <1>         ;tstb   cc(r1) / is it 0
  2002                              <1>         ;beq    1f / yes, no characters to output
  2003                              <1>  	;mov    r1,0f / no, put offset in sleep arg
  2004                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
  2005                              <1>         ;br     1b / try to calm it down again
  2006                              <1> ;1:
  2007                              <1>         ;mov    (sp)+,r1
  2008                              <1>         ;mov    (sp)+,r2 / restore registers
  2009                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
  2010                              <1>         ;beq    1f / if 0, 1f
  2011                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
  2012                              <1>         ;                   / control status register
  2013                              <1> ;1:
  2014                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
  2015                              <1>         ;beq    1f / if 0 1f
  2016                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
  2017                              <1> 	;		    / control status reg
  2018                              <1> ;1:
  2019                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
  2020                              <1>         ;jmp     sysret2 / return to user
  2021                              <1> 
  2022                              <1> sysgtty: ; < get tty status >
  2023                              <1> 	; 23/11/2015
  2024                              <1> 	; 29/10/2015
  2025                              <1> 	; 17/10/2015
  2026                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
  2027                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  2028                              <1> 	;
  2029                              <1> 	; 'sysgtty' gets the status of tty in question. 
  2030                              <1> 	; It stores in the three words addressed by it's argument
  2031                              <1> 	; the status of the typewriter whose file descriptor
  2032                              <1> 	; in (u.r0).
  2033                              <1> 	;
  2034                              <1> 	; Calling sequence:
  2035                              <1> 	;	sysgtty; arg
  2036                              <1> 	; Arguments:
  2037                              <1> 	;	arg - address of 3 words destination of the status
  2038                              <1> 	; Inputs: ((*u.r0 - file descriptor))
  2039                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  2040                              <1> 	; ...............................................................
  2041                              <1> 	;	
  2042                              <1> 	; Retro UNIX 8086 v1 modification: 
  2043                              <1> 	;	'sysgtty' system call will return status of tty
  2044                              <1> 	;	(keyboard, serial port and video page status)
  2045                              <1> 	;	 in following manner:
  2046                              <1> 	;
  2047                              <1> 	; Inputs:
  2048                              <1> 	;	BX = 0 --> means 
  2049                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
  2050                              <1> 	;	                 for (current) process
  2051                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
  2052                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
  2053                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
  2054                              <1> 	;	     CH > 0 -->	tty number + 1
  2055                              <1> 	;
  2056                              <1> 	;	BX > 0 --> points to name of tty
  2057                              <1> 	;	     CL = 0 --> return keyboard status
  2058                              <1> 	;	     CL = 1 --> return video page status
  2059                              <1> 	;	     CH = undefined		 
  2060                              <1> 	;
  2061                              <1> 	; Outputs:
  2062                              <1> 	;	cf = 0 ->
  2063                              <1> 	;
  2064                              <1> 	;	     AL = tty number from 0 to 9
  2065                              <1> 	;		  (0 to 7 is also the video page of the tty)	
  2066                              <1> 	;	     AH = 0 if the tty is free/unused
  2067                              <1> 	;	     AH = the process number of the caller 
  2068                              <1>  	;	     AH = FFh if the tty is locked by another process
  2069                              <1> 	;
  2070                              <1> 	;	  (if calling is for serial port status)
  2071                              <1> 	;	     BX = serial port status if tty number is 8 or 9
  2072                              <1> 	;		  (BH = modem status, BL = Line status)
  2073                              <1> 	;	     CX = 0FFFFh (if data is ready)
  2074                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
  2075                              <1> 	;
  2076                              <1> 	;	  (if calling is for keyboard status)
  2077                              <1> 	;	     BX = current character in tty/keyboard buffer
  2078                              <1> 	;		  (BH = scan code, BL = ascii code)
  2079                              <1> 	;		  (BX=0 if there is not a waiting character)
  2080                              <1> 	;	     CX  is undefined
  2081                              <1> 	;
  2082                              <1> 	;	  (if calling is for video page status)	
  2083                              <1> 	;	     BX = cursor position on the video page
  2084                              <1> 	;		  if tty number < 8
  2085                              <1> 	;		  (BH = row, BL = column)
  2086                              <1> 	;	     CX = current character (in cursor position)
  2087                              <1> 	;		  on the video page of the tty 
  2088                              <1> 	;		  if tty number < 8
  2089                              <1> 	;		  (CH = color, CL = character)
  2090                              <1> 	;	
  2091                              <1> 	;	cf = 1 means error (requested tty is not ready)
  2092                              <1> 	;
  2093                              <1> 	;	     AH = FFh if the caller is not owner of
  2094                              <1> 	;		  specified tty or console tty
  2095                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  2096                              <1> 	;	     BX, CX are undefined if cf = 1
  2097                              <1> 	;
  2098                              <1> 	;	  (If tty number is 8 or 9)
  2099                              <1> 	;	     AL = tty number 
  2100                              <1> 	;	     AH = the process number of the caller 
  2101                              <1> 	;	     BX = serial port status
  2102                              <1> 	;  		 (BH = modem status, BL = Line status)
  2103                              <1> 	;	     CX = 0
  2104                              <1> 	;
  2105                              <1> 		
  2106                              <1> gtty:   ; get (requested) tty number
  2107                              <1> 	; 17/10/2015
  2108                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
  2109                              <1> 	; 30/05/2013 - 12/07/2014
  2110                              <1> 	; Retro UNIX 8086 v1 modification ! 
  2111                              <1> 	;
  2112                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
  2113                              <1> 	;
  2114                              <1> 	; 28/06/2015 (32 bit modifications)
  2115                              <1> 	; 16/01/2014
  2116 0000A6F8 31C0                <1> 	xor 	eax, eax
  2117 0000A6FA 6648                <1> 	dec	ax ; 17/10/2015
  2118 0000A6FC A3[80DF0000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
  2119 0000A701 80F901              <1> 	cmp	cl, 1
  2120 0000A704 760F                <1> 	jna	short sysgtty_0
  2121                              <1> sysgtty_invp:
  2122                              <1> 	; 28/06/2015
  2123 0000A706 C705[D5DF0000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
  2123 0000A70E 0000                <1>
  2124 0000A710 E9CFF8FFFF          <1> 	jmp	error
  2125                              <1> sysgtty_0:	
  2126 0000A715 21DB                <1> 	and	ebx, ebx
  2127 0000A717 7430                <1> 	jz	short sysgtty_1
  2128                              <1> 	;
  2129 0000A719 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  2130 0000A71F 6651                <1> 	push	cx ; 23/11/2015
  2131 0000A721 E85D050000          <1> 	call	namei
  2132 0000A726 6659                <1> 	pop	cx ; 23/11/2015
  2133 0000A728 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
  2134                              <1> 	;
  2135 0000A72A 6683F801            <1> 	cmp	ax, 1
  2136 0000A72E 7622                <1> 	jna	short sysgtty_2
  2137 0000A730 6683E80A            <1> 	sub	ax, 10
  2138 0000A734 6683F809            <1> 	cmp	ax, 9
  2139                              <1> 	;ja	short sysgtty_inv_dn
  2140                              <1> 	;mov	ch, al
  2141                              <1> 	;jmp	short sysgtty_4
  2142                              <1> 	; 23/11/2015
  2143 0000A738 7629                <1> 	jna	short sysgtty_4
  2144                              <1> sysgtty_inv_dn: 
  2145                              <1> 	; 28/06/2015
  2146                              <1> 	; Invalid device name (not a tty) ! error
  2147                              <1> 	; (Device is not a tty or device name not found)
  2148 0000A73A C705[D5DF0000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
  2148 0000A742 0000                <1>
  2149 0000A744 E99BF8FFFF          <1> 	jmp	error 
  2150                              <1> sysgtty_1:
  2151                              <1> 	; 16/01/2014
  2152 0000A749 80FD0A              <1> 	cmp	ch, 10
  2153 0000A74C 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
  2154 0000A74E FECD                <1> 	dec	ch ; 0 -> FFh (negative)
  2155 0000A750 790F                <1> 	jns	short sysgtty_3 ; not negative
  2156                              <1> 	;
  2157                              <1> sysgtty_2:
  2158                              <1> 	; get tty number of console tty
  2159 0000A752 8A25[CFDF0000]      <1> 	mov	ah, [u.uno]
  2160                              <1>  	; 28/06/2015
  2161 0000A758 0FB6DC              <1> 	movzx 	ebx, ah
  2162 0000A75B 8AAB[D7DC0000]      <1> 	mov	ch, [ebx+p.ttyc-1]
  2163                              <1> sysgtty_3:
  2164 0000A761 88E8                <1> 	mov	al, ch
  2165                              <1> sysgtty_4:
  2166 0000A763 A2[80DF0000]        <1> 	mov	[u.r0], al
  2167                              <1>  	; 28/06/2015
  2168                              <1> 	;cmp	al, 9
  2169                              <1> 	;ja	short sysgtty_invp
  2170 0000A768 8B2D[7CDF0000]      <1> 	mov	ebp, [u.usp]
  2171                              <1> 	; 23/11/2015
  2172 0000A76E 20C9                <1> 	and	cl, cl
  2173 0000A770 7436                <1> 	jz	short sysgtty_6 ; keyboard status
  2174 0000A772 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
  2175 0000A774 7232                <1> 	jb	short sysgtty_6 ; video page status
  2176                              <1> 	; serial port status
  2177                              <1> 	; 12/07/2014
  2178                              <1> 	;mov	dx, 0
  2179                              <1> 	;je	short sysgtty_5
  2180                              <1> 	;inc	dl
  2181                              <1> ;sysgtty_5:
  2182                              <1> 	; 28/06/2015
  2183 0000A776 2C08                <1> 	sub	al, 8
  2184 0000A778 E8A8150000          <1> 	call	sp_status ; serial (COM) port (line) status
  2185                              <1> 	; AL = Line status, AH = Modem status
  2186 0000A77D 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
  2187 0000A781 8A25[CFDF0000]      <1> 	mov	ah, [u.uno]
  2188 0000A787 8825[81DF0000]      <1>         mov     [u.r0+1], ah
  2189 0000A78D 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
  2190                              <1> 				; (in ECX)
  2191 0000A793 A880                <1> 	test	al, 80h
  2192 0000A795 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
  2193 0000A797 A801                <1> 	test	al, 1
  2194 0000A799 0F8465F8FFFF        <1> 	jz	sysret
  2195 0000A79F 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
  2196 0000A7A3 E95CF8FFFF          <1> 	jmp	sysret
  2197                              <1> sysgtty_6:
  2198 0000A7A8 A2[D4DF0000]        <1> 	mov	[u.ttyn], al ; tty number
  2199                              <1> 	;movzx	ebx, al
  2200 0000A7AD 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
  2201 0000A7AF D0E3                <1> 	shl 	bl, 1  ; aligned to word
  2202                              <1> 	; 22/04/2014 - 29/06/2015
  2203 0000A7B1 81C3[26CF0000]      <1>         add     ebx, ttyl
  2204 0000A7B7 8A23                <1>  	mov	ah, [ebx]
  2205 0000A7B9 3A25[CFDF0000]      <1> 	cmp	ah, [u.uno]
  2206 0000A7BF 7404                <1> 	je	short sysgtty_7
  2207 0000A7C1 20E4                <1> 	and	ah, ah
  2208                              <1> 	;jz	short sysgtty_7
  2209 0000A7C3 7506                <1> 	jnz	short sysgtty_8
  2210                              <1> 	;mov	ah, 0FFh
  2211                              <1> sysgtty_7:
  2212 0000A7C5 8825[81DF0000]      <1>         mov     [u.r0+1], ah
  2213                              <1> sysgtty_8:
  2214 0000A7CB 08C9                <1> 	or	cl, cl
  2215 0000A7CD 7510                <1> 	jnz	short sysgtty_9
  2216 0000A7CF B401                <1> 	mov	ah, 1  ; test a key is available
  2217 0000A7D1 E81964FFFF          <1> 	call	int16h ; 24/01/2016
  2218 0000A7D6 66894510            <1> 	mov	[ebp+16], ax ; bx, character
  2219 0000A7DA E925F8FFFF          <1> 	jmp	sysret
  2220                              <1> sysgtty_9:
  2221 0000A7DF 8A1D[D4DF0000]      <1> 	mov	bl, [u.ttyn]
  2222                              <1> 	; bl = video page number
  2223 0000A7E5 E89B6DFFFF          <1> 	call 	get_cpos
  2224                              <1> 	; dx = cursor position
  2225 0000A7EA 66895510            <1> 	mov	[ebp+16], dx ; bx
  2226                              <1> 	;mov	bl, [u.ttyn]
  2227                              <1> 	; bl = video page number
  2228 0000A7EE E8516FFFFF          <1> 	call	_read_ac_current ; 24/01/2016
  2229                              <1> 	; ax = character and attribute/color
  2230 0000A7F3 66894518            <1> 	mov	[ebp+24], ax ; cx
  2231 0000A7F7 E908F8FFFF          <1> 	jmp	sysret
  2232                              <1> sysgtty_dnr_err:
  2233                              <1> 	; 'device not responding !' error	
  2234                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
  2235 0000A7FC C705[D5DF0000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
  2235 0000A804 0000                <1>
  2236 0000A806 E9D9F7FFFF          <1> 	jmp	error	
  2237                              <1> 
  2238                              <1> ; Original UNIX v1 'sysgtty' routine:
  2239                              <1> ; sysgtty:
  2240                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
  2241                              <1> 	;	       / r2 has destination
  2242                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
  2243                              <1> 	;                     / in 1st word of dest
  2244                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
  2245                              <1> 	;                     / in 2nd word of dest
  2246                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
  2247                              <1>         ;jmp    sysret2 / return to user
  2248                              <1> 	
  2249                              <1> ; Original UNIX v1 'gtty' routine:
  2250                              <1> ; gtty:
  2251                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
  2252                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
  2253                              <1>         ;jsr    r0,getf / get the i-number of the file
  2254                              <1>         ;tst    r1 / is it open for reading
  2255                              <1>         ;bgt    1f / yes
  2256                              <1>         ;neg    r1 / no, i-number is negative, 
  2257                              <1> 	;          / so make it positive
  2258                              <1> ;1:
  2259                              <1>         ;sub    $14.,r1 / get i-number of tty0
  2260                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
  2261                              <1>         ;bhis   error9 / no, error
  2262                              <1>         ;asl    r1 / 0%2
  2263                              <1>         ;asl    r1 / 0%4 / yes
  2264                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
  2265                              <1> 	;	       ; / tty block
  2266                              <1>         ;mov    u.off,r2 / put argument in r2
  2267                              <1>         ;rts    r0 / return
  2268                              <1> 
  2269                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u2.s
  2270                              <1> ; Last Modification: 03/01/2016
  2271                              <1> 
  2272                              <1> syslink:
  2273                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2274                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2275                              <1> 	;
  2276                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
  2277                              <1> 	; name 1 is a file that already exists. name 2 is the name
  2278                              <1> 	; given to the entry that will go in the current directory.
  2279                              <1> 	; name2 will then be a link to the name 1 file. The i-number
  2280                              <1> 	; in the name 2 entry of current directory is the same
  2281                              <1> 	; i-number for the name 1 file.
  2282                              <1> 	;
  2283                              <1> 	; Calling sequence:
  2284                              <1> 	;	syslink; name 1; name 2
  2285                              <1> 	; Arguments:
  2286                              <1> 	;	name 1 - file name to which link will be created.
  2287                              <1> 	;	name 2 - name of entry in current directory that
  2288                              <1> 	;		 links to name 1.
  2289                              <1> 	; Inputs: -
  2290                              <1> 	; Outputs: -
  2291                              <1> 	; ...............................................................
  2292                              <1> 	;	
  2293                              <1> 	; Retro UNIX 8086 v1 modification: 
  2294                              <1> 	;       'syslink' system call has two arguments; so,
  2295                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
  2296                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
  2297                              <1> 	;
  2298                              <1> 		; / name1, name2
  2299                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
  2300 0000A80B 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  2301 0000A811 51                  <1> 	push	ecx
  2302 0000A812 E86C040000          <1> 	call	namei
  2303                              <1> 		; jsr r0,namei / find the i-number associated with
  2304                              <1> 			     ; / the 1st path name
  2305                              <1>      	;;and	ax, ax
  2306                              <1> 	;;jz	error ; File not found
  2307                              <1> 	;jc	error 
  2308                              <1> 		; br error9 / cannot be found
  2309 0000A817 730F                <1> 	jnc	short syslink0
  2310                              <1> 	;pop 	ecx
  2311                              <1> 	; 'file not found !' error
  2312 0000A819 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2312 0000A821 0000                <1>
  2313 0000A823 E9BCF7FFFF          <1> 	jmp	error
  2314                              <1> syslink0:
  2315 0000A828 E83A120000          <1> 	call	iget
  2316                              <1> 		; jsr r0,iget / get the i-node into core
  2317 0000A82D 8F05[98DF0000]      <1> 	pop	dword [u.namep] ; ecx
  2318                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2319 0000A833 6650                <1> 	push	ax
  2320                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
  2321                              <1> 			    ; / (a link to this file is to be created)
  2322 0000A835 66FF35[66DF0000]    <1> 	push	word [cdev]
  2323                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2324 0000A83C E855000000          <1> 	call	isdir
  2325                              <1> 		; jsr r0,isdir / is it a directory
  2326 0000A841 E83D040000          <1> 	call	namei
  2327                              <1> 		; jsr r0,namei / no, get i-number of name2
  2328                              <1> 	;jnc	error
  2329                              <1> 		; br .+4   / not found 
  2330                              <1> 			 ; / so r1 = i-number of current directory
  2331                              <1> 			 ; / ii = i-number of current directory
  2332                              <1> 		; br error9 / file already exists., error
  2333 0000A846 720F                <1> 	jc	short syslink1
  2334                              <1> 	; pop ax
  2335                              <1> 	; pop ax
  2336                              <1> 	; 'file exists !' error
  2337 0000A848 C705[D5DF0000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2337 0000A850 0000                <1>
  2338 0000A852 E98DF7FFFF          <1> 	jmp	error
  2339                              <1> syslink1:
  2340 0000A857 6659                <1> 	pop	cx
  2341                              <1> 	;cmp	cx, [cdev]
  2342 0000A859 3A0D[66DF0000]      <1> 	cmp	cl, [cdev]
  2343                              <1> 	;jne	error
  2344                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
  2345                              <1> 			       ; / end of current directory
  2346                              <1> 	        ; bne error9
  2347 0000A85F 740F                <1> 	je	short syslink2
  2348                              <1> 	; 'not same drive !' error
  2349 0000A861 C705[D5DF0000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2349 0000A869 0000                <1>
  2350 0000A86B E974F7FFFF          <1> 	jmp	error
  2351                              <1> syslink2:
  2352 0000A870 6658                <1> 	pop	ax
  2353 0000A872 6650                <1> 	push	ax
  2354 0000A874 66A3[B2DF0000]      <1> 	mov	[u.dirbuf], ax
  2355                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2356 0000A87A E8A8000000          <1> 	call	mkdir
  2357                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2358                              <1> 		 	     ; / in current directory
  2359 0000A87F 6658                <1> 	pop	ax
  2360                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2361 0000A881 E8E1110000          <1> 	call	iget
  2362                              <1> 		; jsr r0,iget / get i-node into core
  2363 0000A886 FE05[5ADC0000]      <1> 	inc	byte [i.nlks]
  2364                              <1> 		; incb i.nlks / add 1 to its number of links
  2365 0000A88C E8DF110000          <1> 	call	setimod
  2366                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2367 0000A891 E96EF7FFFF          <1> 	jmp	sysret
  2368                              <1> 
  2369                              <1> isdir:
  2370                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  2371                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  2372                              <1> 	;
  2373                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
  2374                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
  2375                              <1> 	;  called by syslink and sysunlink to make sure directories
  2376                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
  2377                              <1> 	; 'isdir' does not bother checking. The current i-node
  2378                              <1> 	;  is not disturbed.			
  2379                              <1> 	;		
  2380                              <1> 	; INPUTS ->
  2381                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
  2382                              <1> 	;    u.uid - user id
  2383                              <1> 	; OUTPUTS ->
  2384                              <1> 	;    r1 - contains current i-number upon exit
  2385                              <1> 	;    	 (current i-node back in core) 
  2386                              <1> 	;	
  2387                              <1> 	; ((AX = R1))
  2388                              <1> 	;
  2389                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2390                              <1> 	;
  2391                              <1> 
  2392                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
  2393                              <1> 	; / there is an error unless super user made the call
  2394                              <1> 	
  2395 0000A896 803D[CCDF0000]00    <1> 	cmp	byte [u.uid], 0 
  2396                              <1> 		; tstb u.uid / super user
  2397 0000A89D 762D                <1> 	jna	short isdir1
  2398                              <1> 		; beq 1f / yes, don't care
  2399 0000A89F 66FF35[05E00000]    <1> 	push	word [ii]
  2400                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2401 0000A8A6 E8BC110000          <1> 	call	iget
  2402                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2403 0000A8AB 66F705[58DC0000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2403 0000A8B3 40                  <1>
  2404                              <1> 		; bit $40000,i.flgs / is it a directory
  2405                              <1> 	;jnz	error
  2406                              <1> 		; bne error9 / yes, error
  2407 0000A8B4 740F                <1> 	jz	short isdir0
  2408 0000A8B6 C705[D5DF0000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2408 0000A8BE 0000                <1>
  2409                              <1> 				; 'permission denied !' error
  2410                              <1> 	; pop	ax
  2411 0000A8C0 E91FF7FFFF          <1> 	jmp	error	
  2412                              <1> isdir0:	
  2413 0000A8C5 6658                <1> 	pop	ax
  2414                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2415 0000A8C7 E89B110000          <1> 	call	iget
  2416                              <1> 		; jsr r0,iget / get it back in
  2417                              <1> isdir1: ; 1:
  2418 0000A8CC C3                  <1> 	retn
  2419                              <1> 		; rts r0
  2420                              <1> 
  2421                              <1> sysunlink:
  2422                              <1> 	; 04/12/2015 (14 byte file names)
  2423                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2424                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2425                              <1> 	;
  2426                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
  2427                              <1> 	; name from its directory. If this entry was the last link
  2428                              <1> 	; to the file, the contents of the file are freed and the
  2429                              <1> 	; file is destroyed. If, however, the file was open in any
  2430                              <1> 	; process, the actual destruction is delayed until it is 
  2431                              <1> 	; closed, even though the directory entry has disappeared.
  2432                              <1> 	; 
  2433                              <1> 	; The error bit (e-bit) is set to indicate that the file	
  2434                              <1> 	; does not exist or that its directory can not be written.
  2435                              <1> 	; Write permission is not required on the file itself.
  2436                              <1> 	; It is also illegal to unlink a directory (except for
  2437                              <1> 	; the superuser).
  2438                              <1> 	;
  2439                              <1> 	; Calling sequence:
  2440                              <1> 	;	sysunlink; name
  2441                              <1> 	; Arguments:
  2442                              <1> 	;	name - name of directory entry to be removed 
  2443                              <1> 	; Inputs: -
  2444                              <1> 	; Outputs: -
  2445                              <1> 	; ...............................................................
  2446                              <1> 	;				
  2447                              <1> 	; Retro UNIX 8086 v1 modification:
  2448                              <1> 	;	 The user/application program puts address of the name
  2449                              <1> 	;        in BX register as 'sysunlink' system call argument.
  2450                              <1> 
  2451                              <1> 	; / name - remove link name
  2452 0000A8CD 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  2453                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2454 0000A8D3 E8AB030000          <1> 	call	namei
  2455                              <1> 		; jsr r0,namei / find the i-number associated 
  2456                              <1> 			     ; / with the path name
  2457                              <1> 	;jc	error
  2458                              <1> 		; br error9 / not found
  2459 0000A8D8 730F                <1> 	jnc	short sysunlink1
  2460                              <1> 	; 'file not found !' error
  2461 0000A8DA C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2461 0000A8E2 0000                <1>
  2462 0000A8E4 E9FBF6FFFF          <1> 	jmp	error
  2463                              <1> sysunlink1:
  2464 0000A8E9 6650                <1> 	push	ax
  2465                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2466 0000A8EB E8A6FFFFFF          <1> 	call	isdir
  2467                              <1> 		; jsr r0,isdir / is it a directory
  2468 0000A8F0 6631C0              <1> 	xor 	ax, ax
  2469 0000A8F3 66A3[B2DF0000]      <1> 	mov	[u.dirbuf], ax ; 0
  2470                              <1> 		; clr u.dirbuf / no, clear the location that will
  2471                              <1> 			   ; / get written into the i-number portion
  2472                              <1> 			 ; / of the entry
  2473 0000A8F9 832D[9CDF0000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
  2474                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
  2475 0000A900 E86E000000          <1> 	call	wdir
  2476                              <1> 		; jsr r0,wdir / free the directory entry
  2477 0000A905 6658                <1> 	pop	ax
  2478                              <1> 		; mov (sp)+,r1 / get i-number back
  2479 0000A907 E85B110000          <1> 	call	iget
  2480                              <1> 		; jsr r0,iget / get i-node
  2481 0000A90C E85F110000          <1> 	call	setimod
  2482                              <1> 		; jsr r0,setimod / set modified flag
  2483 0000A911 FE0D[5ADC0000]      <1> 	dec	byte [i.nlks]
  2484                              <1> 		; decb i.nlks / decrement the number of links
  2485 0000A917 0F85E7F6FFFF        <1> 	jnz	sysret
  2486                              <1> 		; bgt sysret9 / if this was not the last link
  2487                              <1> 			    ; / to file return
  2488                              <1> 	; AX = r1 = i-number
  2489 0000A91D E886070000          <1> 	call	anyi
  2490                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
  2491                              <1> 			 ; / Then free contents of file and destroy it.
  2492 0000A922 E9DDF6FFFF          <1> 	jmp	sysret
  2493                              <1> 		; br sysret9
  2494                              <1> 
  2495                              <1> mkdir:
  2496                              <1> 	; 04/12/2015 (14 byte directory names)
  2497                              <1> 	; 12/10/2015
  2498                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  2499                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2500                              <1> 	;
  2501                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  2502                              <1> 	; by u.namep into the current directory.
  2503                              <1> 	;
  2504                              <1> 	; INPUTS ->
  2505                              <1> 	;    u.namep - points to a file name 
  2506                              <1> 	;	           that is about to be a directory entry.
  2507                              <1> 	;    ii - current directory's i-number.	
  2508                              <1> 	; OUTPUTS ->
  2509                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  2510                              <1> 	;    u.off - points to entry to be filled 
  2511                              <1> 	;	     in the current directory		
  2512                              <1> 	;    u.base - points to start of u.dirbuf.
  2513                              <1> 	;    r1 - contains i-number of current directory 
  2514                              <1> 	;	
  2515                              <1> 	; ((AX = R1)) output
  2516                              <1> 	;
  2517                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  2518                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2519                              <1> 	;
  2520                              <1> 
  2521                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  2522 0000A927 31C0                <1> 	xor 	eax, eax
  2523 0000A929 BF[B4DF0000]        <1> 	mov     edi, u.dirbuf+2
  2524 0000A92E 89FE                <1> 	mov	esi, edi
  2525 0000A930 AB                  <1> 	stosd
  2526 0000A931 AB                  <1> 	stosd
  2527                              <1> 	; 04/12/2015 (14 byte directory names)
  2528 0000A932 AB                  <1> 	stosd
  2529 0000A933 66AB                <1> 	stosw
  2530                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2531 0000A935 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2532                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2533                              <1> 	;mov 	ebp, [u.namep]
  2534 0000A937 E88C040000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  2535                              <1> 		; esi = physical address (page start + offset)
  2536                              <1> 		; ecx = byte count in the page (1 - 4096)
  2537                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2538                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  2539                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  2540                              <1> mkdir_1: ; 1: 
  2541 0000A93C 45                  <1> 	inc	ebp ; 12/10/2015
  2542                              <1> 	;
  2543                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  2544                              <1> 	 ; 01/08/2013
  2545 0000A93D AC                  <1> 	lodsb
  2546                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2547 0000A93E 20C0                <1> 	and 	al, al
  2548 0000A940 7427                <1> 	jz 	short mkdir_3 	  
  2549                              <1> 		; beq 1f / if null, done
  2550 0000A942 3C2F                <1> 	cmp	al, '/'
  2551                              <1> 		; cmp r1,$'/ / is it a "/"?
  2552 0000A944 7414                <1> 	je	short mkdir_err
  2553                              <1> 	;je	error
  2554                              <1> 		; beq error9 / yes, error
  2555                              <1> 	; 12/10/2015
  2556 0000A946 6649                <1> 	dec	cx
  2557 0000A948 7505                <1> 	jnz	short mkdir_2
  2558                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2559 0000A94A E87F040000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  2560                              <1> 		; esi = physical address (page start + offset)
  2561                              <1> 		; ecx = byte count in the page
  2562                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2563                              <1> mkdir_2:
  2564 0000A94F 81FF[C2DF0000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  2565                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  2566                              <1> 				     ; / a char?
  2567 0000A955 74E5                <1> 	je	short mkdir_1
  2568                              <1> 		; beq 1b / yes, go back
  2569 0000A957 AA                  <1> 	stosb
  2570                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2571 0000A958 EBE2                <1> 	jmp 	short mkdir_1
  2572                              <1> 		; br 1b / get next char
  2573                              <1> mkdir_err:
  2574                              <1> 	; 17/06/2015
  2575 0000A95A C705[D5DF0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2575 0000A962 0000                <1>
  2576 0000A964 E97BF6FFFF          <1> 	jmp	error
  2577                              <1> 
  2578                              <1> mkdir_3: ; 1:
  2579 0000A969 A1[94DF0000]        <1> 	mov	eax, [u.dirp]
  2580 0000A96E A3[9CDF0000]        <1> 	mov	[u.off], eax
  2581                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  2582                              <1> 				 ; / slot to u.off
  2583                              <1> wdir: ; 29/04/2013
  2584 0000A973 C705[A0DF0000]-     <1>         mov     dword [u.base], u.dirbuf
  2584 0000A979 [B2DF0000]          <1>
  2585                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2586 0000A97D C705[A4DF0000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2586 0000A985 0000                <1>
  2587                              <1> 		; mov $10.,u.count / u.count = 10
  2588 0000A987 66A1[05E00000]      <1> 	mov	ax, [ii] 
  2589                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2590 0000A98D B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2591 0000A98F E8E0100000          <1> 	call 	access
  2592                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  2593                              <1> 				 ; / for writing
  2594                              <1> 	; AX = i-number of current directory
  2595                              <1> 	; 01/08/2013
  2596 0000A994 FE05[E7DF0000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2597 0000A99A E8CC100000          <1> 	call	writei
  2598                              <1> 		; jsr r0,writei / write into directory
  2599 0000A99F C3                  <1> 	retn	
  2600                              <1> 		; rts r0
  2601                              <1> 
  2602                              <1> sysexec:
  2603                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  2604                              <1> 	; 23/06/2015 - 23/10/2015 (Retro UNIX 386 v1)
  2605                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2606                              <1> 	;
  2607                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  2608                              <1> 	; pointed to by 'name' in the sysexec call. 
  2609                              <1> 	; 'sysexec' performs the following operations:
  2610                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  2611                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
  2612                              <1> 	;    3. sets trap vectors to system routines.
  2613                              <1> 	;    4. loads arguments to be passed to executing file into
  2614                              <1> 	;	highest locations of user's core
  2615                              <1> 	;    5. puts pointers to arguments in locations immediately
  2616                              <1> 	;	following arguments.
  2617                              <1> 	;    6.	saves number of arguments in next location.
  2618                              <1> 	;    7. intializes user's stack area so that all registers
  2619                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  2620                              <1> 	;	to core when 'sysret' restores registers 
  2621                              <1> 	;	and does an rti.
  2622                              <1> 	;    8. inializes u.r0 and u.sp
  2623                              <1> 	;    9. zeros user's core down to u.r0
  2624                              <1> 	;   10.	reads executable file from storage device into core
  2625                              <1> 	;	starting at location 'core'.
  2626                              <1> 	;   11.	sets u.break to point to end of user's code with
  2627                              <1> 	;	data area appended.
  2628                              <1> 	;   12.	calls 'sysret' which returns control at location
  2629                              <1> 	;	'core' via 'rti' instruction. 		  		
  2630                              <1> 	;
  2631                              <1> 	; Calling sequence:
  2632                              <1> 	;	sysexec; namep; argp
  2633                              <1> 	; Arguments:
  2634                              <1> 	;	namep - points to pathname of file to be executed
  2635                              <1> 	;	argp  - address of table of argument pointers
  2636                              <1> 	;	argp1... argpn - table of argument pointers
  2637                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  2638                              <1> 	; Inputs: (arguments)
  2639                              <1> 	; Outputs: -	
  2640                              <1> 	; ...............................................................
  2641                              <1> 	;
  2642                              <1> 	; Retro UNIX 386 v1 modification: 
  2643                              <1> 	;	User application runs in it's own virtual space 
  2644                              <1> 	;	which is izolated from kernel memory (and other
  2645                              <1> 	;	memory pages) via 80386	paging in ring 3 
  2646                              <1> 	;	privilige mode. Virtual start address is always 0.
  2647                              <1> 	;	User's core memory starts at linear address 400000h
  2648                              <1> 	;	(the end of the 1st 4MB).
  2649                              <1> 	;
  2650                              <1> 	; Retro UNIX 8086 v1 modification: 
  2651                              <1> 	;	user/application segment and system/kernel segment
  2652                              <1> 	;	are different and sysenter/sysret/sysrele routines
  2653                              <1> 	;	are different (user's registers are saved to 
  2654                              <1> 	;	and then restored from system's stack.)
  2655                              <1> 	;
  2656                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2657                              <1> 	;	      arguments which were in these registers;
  2658                              <1> 	;	      but, it returns by putting the 1st argument
  2659                              <1> 	;	      in 'u.namep' and the 2nd argument
  2660                              <1> 	;	      on top of stack. (1st argument is offset of the
  2661                              <1> 	;	      file/path name in the user's program segment.)		 	
  2662                              <1> 	
  2663                              <1> 	;call	arg2
  2664                              <1> 	; * name - 'u.namep' points to address of file/path name
  2665                              <1> 	;          in the user's program segment ('u.segmnt')
  2666                              <1> 	;          with offset in BX register (as sysopen argument 1).
  2667                              <1> 	; * argp - sysexec argument 2 is in CX register 
  2668                              <1> 	;          which is on top of stack.
  2669                              <1> 	;
  2670                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  2671                              <1> 
  2672                              <1> 	; 23/06/2015 (32 bit modifications)
  2673                              <1> 
  2674 0000A9A0 891D[98DF0000]      <1> 	mov	[u.namep], ebx ; argument 1
  2675                              <1>         ; 18/10/2015
  2676 0000A9A6 890D[00E00000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2677 0000A9AC E8D2020000          <1> 	call	namei
  2678                              <1> 		; jsr r0,namei / namei returns i-number of file 
  2679                              <1> 			     ; / named in sysexec call in r1
  2680                              <1> 	;jc	error
  2681                              <1> 		; br error9
  2682 0000A9B1 731E                <1> 	jnc	short sysexec_0
  2683                              <1> 	;
  2684                              <1> 	; 'file not found !' error
  2685 0000A9B3 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2685 0000A9BB 0000                <1>
  2686 0000A9BD E922F6FFFF          <1> 	jmp	error 
  2687                              <1> sysexec_not_exf:
  2688                              <1> 	; 'not executable file !' error
  2689 0000A9C2 C705[D5DF0000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
  2689 0000A9CA 0000                <1>
  2690 0000A9CC E913F6FFFF          <1> 	jmp	error 
  2691                              <1> sysexec_0:
  2692 0000A9D1 E891100000          <1> 	call	iget
  2693                              <1> 		; jsr r0,iget / get i-node for file to be executed
  2694 0000A9D6 66F705[58DC0000]10- <1>         test    word [i.flgs], 10h
  2694 0000A9DE 00                  <1>
  2695                              <1> 		; bit $20,i.flgs / is file executable
  2696 0000A9DF 74E1                <1> 	jz	short sysexec_not_exf
  2697                              <1> 	;jz	error
  2698                              <1> 		; beq error9
  2699                              <1> 	;;
  2700 0000A9E1 E886100000          <1> 	call	iopen
  2701                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
  2702                              <1> 			     ; / given in r1 (opens file)
  2703                              <1> 	; AX = i-number of the file
  2704 0000A9E6 66F705[58DC0000]20- <1> 	test	word [i.flgs], 20h
  2704 0000A9EE 00                  <1>
  2705                              <1> 		; bit $40,i.flgs / test user id on execution bit
  2706 0000A9EF 7415                <1> 	jz	short sysexec_1
  2707                              <1> 		; beq 1f
  2708 0000A9F1 803D[CCDF0000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
  2709                              <1> 		; tstb u.uid / test user id
  2710 0000A9F8 760C                <1> 	jna	short sysexec_1
  2711                              <1> 		; beq 1f / super user
  2712 0000A9FA 8A0D[5BDC0000]      <1> 	mov	cl, [i.uid]
  2713 0000AA00 880D[CCDF0000]      <1> 	mov	[u.uid], cl ; 02/08/2013
  2714                              <1> 		; movb i.uid,u.uid / put user id of owner of file
  2715                              <1> 				 ; / as process user id
  2716                              <1> sysexec_1:
  2717                              <1> 	; 18/10/2215
  2718                              <1> 	; 10/10/2015
  2719                              <1> 	; 24/07/2015
  2720                              <1> 	; 21/07/2015
  2721                              <1> 	; 25/06/2015
  2722                              <1> 	; 24/06/2015
  2723                              <1>         ; Moving arguments to the end of [u.upage]
  2724                              <1> 	; (by regarding page borders in user's memory space)
  2725                              <1> 	;
  2726                              <1> 	; 10/10/2015
  2727                              <1> 	; 21/07/2015
  2728 0000AA06 89E5                <1> 	mov	ebp, esp ; (**)
  2729                              <1> 	; 18/10/2015
  2730 0000AA08 89EF                <1> 	mov 	edi, ebp
  2731 0000AA0A B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2732                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2733 0000AA0F 29CF                <1> 	sub	edi, ecx
  2734 0000AA11 89FC                <1> 	mov	esp, edi
  2735 0000AA13 31C0                <1> 	xor	eax, eax
  2736 0000AA15 A3[A8DF0000]        <1> 	mov 	[u.nread], eax ; 0
  2737 0000AA1A 49                  <1> 	dec	ecx ; 256 - 1
  2738 0000AA1B 890D[A4DF0000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  2739                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  2740                              <1> sysexec_2:
  2741 0000AA21 8B35[00E00000]      <1> 	mov	esi, [argv] ; 18/10/2015 
  2742 0000AA27 E866000000          <1> 	call	get_argp
  2743 0000AA2C B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  2744                              <1> sysexec_3:
  2745 0000AA31 21C0                <1> 	and	eax, eax
  2746 0000AA33 0F84BE090000        <1>         jz      sysexec_6
  2747                              <1> 	; 18/10/2015
  2748 0000AA39 010D[00E00000]      <1> 	add	[argv], ecx ; 4
  2749 0000AA3F 66FF05[FEDF0000]    <1> 	inc	word [argc]
  2750                              <1> 	;
  2751 0000AA46 A3[A0DF0000]        <1> 	mov	[u.base], eax
  2752                              <1>  	; 23/10/2015
  2753 0000AA4B 66C705[E5DF0000]00- <1> 	mov	word [u.pcount], 0
  2753 0000AA53 00                  <1>
  2754                              <1> sysexec_4:
  2755 0000AA54 E8AE0F0000          <1> 	call	cpass ; get a character from user's core memory
  2756 0000AA59 750E                <1>         jnz      short sysexec_5
  2757                              <1> 		; (max. 255 chars + null)
  2758                              <1> 	; 18/10/2015
  2759 0000AA5B 28C0                <1> 	sub 	al, al
  2760 0000AA5D AA                  <1> 	stosb
  2761 0000AA5E FF05[A8DF0000]      <1> 	inc	dword [u.nread]
  2762 0000AA64 E98E090000          <1> 	jmp	sysexec_6 ; 24/04/2016
  2763                              <1> sysexec_5:
  2764 0000AA69 AA                  <1> 	stosb
  2765 0000AA6A 20C0                <1> 	and 	al, al
  2766 0000AA6C 75E6                <1> 	jnz	short sysexec_4
  2767 0000AA6E B904000000          <1> 	mov	ecx, 4
  2768 0000AA73 390D[FCDF0000]      <1> 	cmp	[ncount], ecx ; 4
  2769 0000AA79 72A6                <1> 	jb	short sysexec_2
  2770 0000AA7B 8B35[F8DF0000]      <1> 	mov	esi, [nbase]
  2771 0000AA81 010D[F8DF0000]      <1> 	add	[nbase], ecx ; 4	
  2772 0000AA87 66290D[FCDF0000]    <1> 	sub	[ncount], cx 
  2773 0000AA8E 8B06                <1> 	mov	eax, [esi]
  2774 0000AA90 EB9F                <1> 	jmp	short sysexec_3
  2775                              <1> 
  2776                              <1> get_argp:
  2777                              <1> 	; 18/10/2015 (nbase, ncount)
  2778                              <1> 	; 21/07/2015
  2779                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  2780                              <1> 	; Get (virtual) address of argument from user's core memory
  2781                              <1> 	;
  2782                              <1> 	; INPUT:
  2783                              <1> 	;	esi = virtual address of argument pointer
  2784                              <1> 	; OUTPUT:
  2785                              <1> 	;	eax = virtual address of argument
  2786                              <1> 	;
  2787                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  2788                              <1> 	;
  2789 0000AA92 833D[DDDF0000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  2790                              <1> 				    ; (the caller is kernel)
  2791 0000AA99 7667                <1>         jna     short get_argpk 
  2792                              <1> 	;
  2793 0000AA9B 89F3                <1>      	mov	ebx, esi
  2794 0000AA9D E8008DFFFF          <1> 	call	get_physical_addr ; get physical address
  2795 0000AAA2 0F8289000000        <1>         jc      get_argp_err
  2796 0000AAA8 A3[F8DF0000]        <1> 	mov 	[nbase], eax ; physical address	
  2797 0000AAAD 66890D[FCDF0000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  2798 0000AAB4 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  2799 0000AAB9 6639C1              <1> 	cmp	cx, ax ; 4
  2800 0000AABC 735D                <1> 	jnb	short get_argp2
  2801 0000AABE 89F3                <1> 	mov	ebx, esi
  2802 0000AAC0 01CB                <1> 	add	ebx, ecx
  2803 0000AAC2 E8DB8CFFFF          <1> 	call	get_physical_addr ; get physical address
  2804 0000AAC7 7268                <1> 	jc	short get_argp_err
  2805                              <1> 	;push	esi
  2806 0000AAC9 89C6                <1> 	mov	esi, eax
  2807 0000AACB 66870D[FCDF0000]    <1> 	xchg	cx, [ncount]
  2808 0000AAD2 8735[F8DF0000]      <1> 	xchg	esi, [nbase]
  2809 0000AAD8 B504                <1> 	mov	ch, 4
  2810 0000AADA 28CD                <1> 	sub	ch, cl
  2811                              <1> get_argp0:
  2812 0000AADC AC                  <1> 	lodsb
  2813 0000AADD 6650                <1> 	push	ax
  2814 0000AADF FEC9                <1> 	dec	cl
  2815 0000AAE1 75F9                <1>         jnz     short get_argp0
  2816 0000AAE3 8B35[F8DF0000]      <1> 	mov	esi, [nbase]
  2817                              <1> 	; 21/07/2015
  2818 0000AAE9 0FB6C5              <1> 	movzx	eax, ch
  2819 0000AAEC 0105[F8DF0000]      <1> 	add	[nbase], eax
  2820 0000AAF2 662905[FCDF0000]    <1> 	sub	[ncount], ax
  2821                              <1> get_argp1:
  2822 0000AAF9 AC                  <1> 	lodsb
  2823 0000AAFA FECD                <1> 	dec	ch
  2824 0000AAFC 743D                <1>         jz      short get_argp3
  2825 0000AAFE 6650                <1>         push	ax
  2826 0000AB00 EBF7                <1> 	jmp     short get_argp1
  2827                              <1> get_argpk:
  2828                              <1> 	; Argument is in kernel's memory space
  2829 0000AB02 66C705[FCDF0000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  2829 0000AB0A 10                  <1>
  2830 0000AB0B 8935[F8DF0000]      <1> 	mov	[nbase], esi
  2831 0000AB11 8305[F8DF0000]04    <1> 	add	dword [nbase], 4
  2832 0000AB18 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  2833 0000AB1A C3                  <1> 	retn
  2834                              <1> get_argp2:
  2835                              <1> 	; 21/07/2015
  2836                              <1> 	;mov	eax, 4
  2837 0000AB1B 8B15[F8DF0000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  2838 0000AB21 0105[F8DF0000]      <1> 	add	[nbase], eax
  2839 0000AB27 662905[FCDF0000]    <1> 	sub	[ncount], ax
  2840                              <1> 	;
  2841 0000AB2E 8B02                <1> 	mov	eax, [edx]
  2842 0000AB30 C3                  <1> 	retn
  2843                              <1> get_argp_err:
  2844 0000AB31 A3[D5DF0000]        <1> 	mov	[u.error], eax
  2845 0000AB36 E9A9F4FFFF          <1> 	jmp	error
  2846                              <1> get_argp3:
  2847 0000AB3B B103                <1> 	mov	cl, 3
  2848                              <1> get_argp4:
  2849 0000AB3D C1E008              <1> 	shl	eax, 8
  2850 0000AB40 665A                <1> 	pop	dx
  2851 0000AB42 88D0                <1> 	mov 	al, dl
  2852 0000AB44 E2F7                <1>         loop    get_argp4
  2853                              <1> 	;pop	esi
  2854 0000AB46 C3                  <1> 	retn	
  2855                              <1> 
  2856                              <1> sysfstat: 
  2857                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2858                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2859                              <1> 	;
  2860                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
  2861                              <1> 	; on open files instead of files given by name. It puts the
  2862                              <1> 	; buffer address on the stack, gets the i-number and
  2863                              <1> 	; checks to see if the file is open for reading or writing.
  2864                              <1> 	; If the file is open for writing (i-number is negative)
  2865                              <1> 	; the i-number is set positive and a branch into 'sysstat'
  2866                              <1> 	; is made.	
  2867                              <1> 	;
  2868                              <1> 	; Calling sequence:
  2869                              <1> 	;	sysfstat; buf
  2870                              <1> 	; Arguments:
  2871                              <1> 	;	buf - buffer address
  2872                              <1> 	;
  2873                              <1> 	; Inputs: *u.r0 - file descriptor
  2874                              <1> 	; Outputs: buffer is loaded with file information
  2875                              <1> 	; ...............................................................
  2876                              <1> 	;				
  2877                              <1> 	; Retro UNIX 8086 v1 modification:
  2878                              <1> 	;       'sysfstat' system call has two arguments; so,
  2879                              <1> 	;	* 1st argument, file descriptor is in BX register
  2880                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2881                              <1> 
  2882                              <1> 	; / set status of open file
  2883                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
  2884 0000AB47 51                  <1> 	push	ecx
  2885                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
  2886                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
  2887                              <1> 		; jsr r0,getf / get the files i-number
  2888                              <1> 	; BX = file descriptor (file number)
  2889 0000AB48 E8FF000000          <1> 	call	getf1
  2890 0000AB4D 6621C0              <1> 	and	ax, ax ; i-number of the file
  2891                              <1> 		; tst	r1 / is it 0?
  2892                              <1> 	;jz	error
  2893                              <1> 		; beq error3 / yes, error
  2894 0000AB50 750F                <1> 	jnz	short sysfstat1
  2895 0000AB52 C705[D5DF0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  2895 0000AB5A 0000                <1>
  2896 0000AB5C E983F4FFFF          <1> 	jmp	error
  2897                              <1> sysfstat1:
  2898 0000AB61 80FC80              <1> 	cmp	ah, 80h
  2899 0000AB64 7223                <1>         jb      short sysstat1
  2900                              <1> 		; bgt 1f / if i-number is negative (open for writing)
  2901 0000AB66 66F7D8              <1> 	neg	ax
  2902                              <1> 		; neg r1 / make it positive, then branch
  2903 0000AB69 EB1E                <1> 	jmp	short sysstat1
  2904                              <1> 		; br 1f / to 1f
  2905                              <1> sysstat:
  2906                              <1> 	; 18/10/2015
  2907                              <1> 	; 07/10/2015
  2908                              <1> 	; 02/09/2015
  2909                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2910                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2911                              <1> 	;
  2912                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
  2913                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
  2914                              <1> 	; long and information about the file placed in it.	
  2915                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
  2916                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
  2917                              <1> 	; is then loaded and the results are given in the UNIX
  2918                              <1> 	; Programmers Manual sysstat (II).	
  2919                              <1> 	;
  2920                              <1> 	; Calling sequence:
  2921                              <1> 	;	sysstat; name; buf
  2922                              <1> 	; Arguments:
  2923                              <1> 	;	name - points to the name of the file
  2924                              <1> 	;	buf - address of a 34 bytes buffer
  2925                              <1> 	; Inputs: -
  2926                              <1> 	; Outputs: buffer is loaded with file information
  2927                              <1> 	; ...............................................................
  2928                              <1> 	;				
  2929                              <1> 	; Retro UNIX 8086 v1 modification: 
  2930                              <1> 	;       'sysstat' system call has two arguments; so,
  2931                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  2932                              <1> 	;	to get sysstat system call arguments from the user;
  2933                              <1> 	;	* 1st argument, name is pointed to by BX register
  2934                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2935                              <1> 	;
  2936                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2937                              <1> 	;	      arguments which were in these registers;
  2938                              <1> 	;	      but, it returns by putting the 1st argument
  2939                              <1> 	;	      in 'u.namep' and the 2nd argument
  2940                              <1> 	;	      on top of stack. (1st argument is offset of the
  2941                              <1> 	;	      file/path name in the user's program segment.)		 	
  2942                              <1> 	
  2943                              <1> 	; / ; name of file; buffer - get files status
  2944                              <1> 		; jsr r0,arg2 / get the 2 arguments
  2945 0000AB6B 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  2946 0000AB71 51                  <1> 	push	ecx
  2947 0000AB72 E80C010000          <1> 	call	namei
  2948                              <1> 		; jsr r0,namei / get the i-number for the file
  2949                              <1> 	;jc	error
  2950                              <1> 		; br error3 / no such file, error
  2951 0000AB77 7310                <1> 	jnc	short sysstat1
  2952                              <1> 	; pop 	ecx
  2953                              <1> sysstat_err0:
  2954                              <1> 	; 'file not found !' error
  2955 0000AB79 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2955 0000AB81 0000                <1>
  2956 0000AB83 E95CF4FFFF          <1> 	jmp	error
  2957                              <1> 
  2958 0000AB88 00                  <1> statx: db 0
  2959                              <1> 
  2960                              <1> sysstat1: ; 1:
  2961 0000AB89 E8D90E0000          <1> 	call	iget
  2962                              <1> 		; jsr r0,iget / get the i-node into core
  2963                              <1> 	; 07/10/2015 (ax = [ii], inode number)
  2964                              <1> 	; 02/09/2015
  2965 0000AB8E 8F05[A0DF0000]      <1> 	pop	dword [u.base]
  2966                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  2967 0000AB94 E858000000          <1> 	call	sysstat_gpa ; get physical address
  2968 0000AB99 730A                <1> 	jnc 	short sysstat2
  2969                              <1> sysstat_err1:
  2970 0000AB9B A3[D5DF0000]        <1> 	mov	dword [u.error], eax ; error code
  2971 0000ABA0 E93FF4FFFF          <1> 	jmp	error
  2972                              <1> sysstat2:
  2973 0000ABA5 A0[05E00000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  2974 0000ABAA AA                  <1> 	stosb
  2975 0000ABAB FF05[A0DF0000]      <1> 	inc 	dword [u.base]
  2976 0000ABB1 6649                <1> 	dec 	cx
  2977 0000ABB3 7505                <1> 	jnz	short sysstat3
  2978 0000ABB5 E837000000          <1> 	call	sysstat_gpa
  2979                              <1> 	;jc	short sysstat_err1
  2980                              <1> sysstat3:
  2981 0000ABBA A0[06E00000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  2982 0000ABBF AA                  <1> 	stosb
  2983                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  2984 0000ABC0 FF05[A0DF0000]      <1> 	inc 	dword [u.base]
  2985                              <1> 	;dec 	word [u.pcount]
  2986 0000ABC6 6649                <1> 	dec	cx
  2987 0000ABC8 7505                <1> 	jnz	short sysstat4
  2988 0000ABCA E822000000          <1> 	call	sysstat_gpa
  2989                              <1> 	;jc	short sysstat_err1	
  2990                              <1> sysstat4:
  2991 0000ABCF BE[58DC0000]        <1> 	mov	esi, inode
  2992                              <1> 		; mov $inode,r2 / r2 points to i-node
  2993                              <1> sysstat5: ; 1:
  2994 0000ABD4 A4                  <1> 	movsb
  2995                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  2996 0000ABD5 FF05[A0DF0000]      <1> 	inc 	dword [u.base]
  2997                              <1> 	;dec 	word [u.pcount]
  2998 0000ABDB 6649                <1> 	dec	cx
  2999 0000ABDD 7505                <1> 	jnz	short sysstat6
  3000 0000ABDF E80D000000          <1> 	call	sysstat_gpa
  3001                              <1> 	;jc	short sysstat_err1
  3002                              <1> sysstat6:		
  3003 0000ABE4 81FE[78DC0000]      <1> 	cmp	esi, inode + 32
  3004                              <1> 		; cmp r2,$inode+32 / done?
  3005 0000ABEA 75E8                <1> 	jne	short sysstat5
  3006                              <1> 		; bne 1b / no, go back
  3007 0000ABEC E913F4FFFF          <1> 	jmp	sysret
  3008                              <1> 		; br sysret3 / return through sysret
  3009                              <1> 	;
  3010                              <1> sysstat_gpa: ; get physical address of file status buffer
  3011                              <1> 	; 02/09/2015
  3012 0000ABF1 8B1D[A0DF0000]      <1> 	mov 	ebx, [u.base]
  3013                              <1> 	; 07/10/2015
  3014 0000ABF7 E8A68BFFFF          <1> 	call	get_physical_addr ; get physical address
  3015                              <1> 	;jc	short sysstat_gpa1
  3016 0000ABFC 729D                <1> 	jc	short sysstat_err1
  3017                              <1> 	; 18/10/2015
  3018 0000ABFE 89C7                <1> 	mov	edi, eax ; physical address
  3019                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3020                              <1> ;sysstat_gpa1:
  3021 0000AC00 C3                  <1> 	retn
  3022                              <1> 
  3023                              <1> fclose:
  3024                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  3025                              <1> 	;            (32 bit offset pointer modification)
  3026                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  3027                              <1> 	;
  3028                              <1> 	; Given the file descriptor (index to the u.fp list)
  3029                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  3030                              <1> 	; If i-node is active (i-number > 0) the entry in 
  3031                              <1> 	; u.fp list is cleared. If all the processes that opened
  3032                              <1> 	; that file close it, then fsp etry is freed and the file
  3033                              <1> 	; is closed. If not a return is taken. 
  3034                              <1> 	; If the file has been deleted while open, 'anyi' is called
  3035                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  3036                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  3037                              <1> 	; a check is made to see if the file is special.	
  3038                              <1> 	;
  3039                              <1> 	; INPUTS ->
  3040                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  3041                              <1> 	;    u.fp - list of entries in the fsp table
  3042                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  3043                              <1> 	; OUTPUTS ->
  3044                              <1> 	;    r1 - contains the same file descriptor
  3045                              <1> 	;    r2 - contains i-number
  3046                              <1> 	;
  3047                              <1> 	; ((AX = R1))
  3048                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
  3049                              <1> 	;
  3050                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  3051                              <1> 	;              if i-number of the file is 0. (error)  	
  3052                              <1> 	;
  3053 0000AC01 0FB7D0              <1> 	movzx	edx, ax ; **
  3054 0000AC04 6650                <1> 	push	ax ; ***
  3055                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
  3056                              <1> 			     ; / the index to u.fp list)
  3057 0000AC06 E83F000000          <1> 	call	getf
  3058                              <1> 		; jsr r0,getf / r1 contains i-number, 
  3059                              <1> 			    ; / cdev has device =, u.fofp 
  3060                              <1> 			    ; / points to 3rd word of fsp entry
  3061 0000AC0B 6683F801            <1> 	cmp	ax, 1 ; r1
  3062                              <1> 		; tst r1 / is i-number 0?
  3063 0000AC0F 7236                <1> 	jb	short fclose_2
  3064                              <1> 		; beq 1f / yes, i-node not active so return
  3065                              <1> 		; tst (r0)+ / no, jump over error return
  3066 0000AC11 89D3                <1> 	mov	ebx, edx ; **
  3067 0000AC13 6689C2              <1> 	mov 	dx, ax ; *
  3068                              <1> 		; mov r1,r2 / move i-number to r2 ;*
  3069                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
  3070                              <1> 			    ; / which is index to u.fp ; **
  3071 0000AC16 C683[86DF0000]00    <1> 	mov	byte [ebx+u.fp], 0
  3072                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3073 0000AC1D 8B1D[90DF0000]      <1> 	mov	ebx, [u.fofp]
  3074                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3075                              <1> fclose_0:
  3076 0000AC23 FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
  3077                              <1> 		; decb 2(r1) / decrement the number of processes 
  3078                              <1> 			   ; / that have opened the file
  3079 0000AC26 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
  3080                              <1> 		; bge 1f / if all processes haven't closed the file, return
  3081                              <1> 	;
  3082 0000AC28 6652                <1> 	push	dx ;*
  3083                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3084 0000AC2A 6631C0              <1> 	xor	ax, ax ; 0
  3085 0000AC2D 668943FC            <1> 	mov	[ebx-4], ax ; 0
  3086                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3087 0000AC31 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
  3088                              <1> 		; tstb	3(r1) / has this file been deleted
  3089 0000AC34 20C0                <1> 	and	al, al
  3090 0000AC36 7408                <1> 	jz	short fclose_1
  3091                              <1> 		; beq 2f / no, branch
  3092 0000AC38 6689D0              <1> 	mov	ax, dx ; *
  3093                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3094                              <1> 	; AX = inode number
  3095 0000AC3B E868040000          <1> 	call	anyi
  3096                              <1> 		; jsr r0,anyi / free all blocks related to i-number
  3097                              <1> 			    ; / check if file appears in fsp again
  3098                              <1> fclose_1: ; 2:
  3099 0000AC40 6658                <1> 	pop	ax ; *
  3100                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3101 0000AC42 E8260E0000          <1> 	call	iclose ; close if it is special file 
  3102                              <1> 		; jsr r0,iclose / check to see if its a special file
  3103                              <1> fclose_2: ; 1:
  3104 0000AC47 6658                <1> 	pop	ax ; ***
  3105                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3106 0000AC49 C3                  <1> 	retn
  3107                              <1> 		; rts r0
  3108                              <1> 
  3109                              <1> getf:	; / get the device number and the i-number of an open file
  3110                              <1> 	; 13/05/2015
  3111                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3112                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3113                              <1> 	;
  3114 0000AC4A 89C3                <1> 	mov	ebx, eax
  3115                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3116 0000AC4C 83FB0A              <1> 	cmp	ebx, 10
  3117                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3118 0000AC4F 730A                <1>         jnb	short getf2 ; 13/05/2015
  3119                              <1> 	;jnb     error
  3120                              <1> 		; bhis error3 / u.fp is table of users open files, 
  3121                              <1> 			    ; / index in fsp table
  3122 0000AC51 8A9B[86DF0000]      <1> 	mov	bl, [ebx+u.fp]
  3123                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
  3124                              <1> 		                  ; / in fsp table
  3125 0000AC57 08DB                <1> 	or	bl, bl
  3126 0000AC59 7503                <1> 	jnz	short getf3
  3127                              <1> 	;jz	short getf4
  3128                              <1> 		; beq 1f / if its zero return
  3129                              <1> getf2:
  3130                              <1> 	; 'File not open !' error (ax=0)
  3131 0000AC5B 29C0                <1> 	sub	eax, eax
  3132 0000AC5D C3                  <1> 	retn
  3133                              <1> getf3:	
  3134                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
  3135                              <1> 	;
  3136                              <1> 	; 'fsp' table (10 bytes/entry)
  3137                              <1> 	; bit 15				   bit 0
  3138                              <1> 	; ---|-------------------------------------------
  3139                              <1> 	; r/w|		i-number of open file
  3140                              <1> 	; ---|-------------------------------------------
  3141                              <1> 	;		   device number
  3142                              <1> 	; -----------------------------------------------
  3143                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3144                              <1> 	; -----------------------------------------------
  3145                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3146                              <1> 	; ----------------------|------------------------
  3147                              <1> 	;  flag that says file 	| number of processes
  3148                              <1> 	;   has been deleted	| that have file open 
  3149                              <1> 	; ----------------------|------------------------
  3150                              <1> 	;
  3151 0000AC5E B80A000000          <1> 	mov	eax, 10
  3152 0000AC63 F6E3                <1> 	mul	bl
  3153 0000AC65 BB[52DD0000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
  3154 0000AC6A 01C3                <1> 	add	ebx, eax
  3155                              <1> 		; asl r1
  3156                              <1> 		; asl r1 / multiply by 8 to get index into 
  3157                              <1> 		       ; / fsp table entry
  3158                              <1> 		; asl r1
  3159                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
  3160                              <1> 			      ; / in the fsp entry
  3161 0000AC6C 891D[90DF0000]      <1> 	mov	[u.fofp], ebx
  3162                              <1> 		; mov r1,u.fofp / save address of 3rd word 
  3163                              <1> 			      ; / in fsp entry in u.fofp
  3164 0000AC72 4B                  <1> 	dec	ebx
  3165 0000AC73 4B                  <1> 	dec	ebx
  3166 0000AC74 668B03              <1> 	mov	ax, [ebx]
  3167                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3168 0000AC77 66A3[66DF0000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
  3169                              <1> 			     ;;dev number is in 1 byte
  3170                              <1> 		; mov -(r1),cdev / remove the device number  cdev
  3171 0000AC7D 4B                  <1> 	dec	ebx
  3172 0000AC7E 4B                  <1> 	dec	ebx
  3173 0000AC7F 668B03              <1> 	mov	ax, [ebx]
  3174                              <1> 		; mov -(r1),r1 / and the i-number  r1
  3175                              <1> getf4:	; 1:
  3176 0000AC82 C3                  <1> 	retn
  3177                              <1> 		; rts r0
  3178                              <1> 
  3179                              <1> namei:
  3180                              <1> 	; 04/12/2015 (14 byte file names)
  3181                              <1> 	; 18/10/2015 (nbase, ncount)
  3182                              <1> 	; 12/10/2015
  3183                              <1> 	; 21/08/2015
  3184                              <1> 	; 18/07/2015
  3185                              <1> 	; 02/07/2015
  3186                              <1> 	; 17/06/2015
  3187                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
  3188                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3189                              <1> 	;
  3190                              <1> 	; 'namei' takes a file path name and returns i-number of
  3191                              <1> 	; the file in the current directory or the root directory
  3192                              <1> 	; (if the first character of the pathname is '/').	
  3193                              <1> 	;
  3194                              <1> 	; INPUTS ->
  3195                              <1> 	;    u.namep - points to a file path name
  3196                              <1> 	;    u.cdir - i-number of users directory
  3197                              <1> 	;    u.cdev - device number on which user directory resides	
  3198                              <1> 	; OUTPUTS ->
  3199                              <1> 	;    r1 - i-number of file
  3200                              <1> 	;    cdev
  3201                              <1> 	;    u.dirbuf - points to directory entry where a match 
  3202                              <1> 	;               occurs in the search for file path name.
  3203                              <1> 	;	        If no match u.dirb points to the end of 
  3204                              <1> 	;               the directory and r1 = i-number of the current
  3205                              <1> 	;	        directory.	
  3206                              <1> 	; ((AX = R1))
  3207                              <1> 	;
  3208                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
  3209                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
  3210                              <1> 	;
  3211                              <1> 
  3212 0000AC83 66A1[84DF0000]      <1> 	mov	ax, [u.cdir]
  3213                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3214                              <1> 			      ; / in r1
  3215 0000AC89 668B15[CADF0000]    <1> 	mov	dx, [u.cdrv]
  3216 0000AC90 668915[66DF0000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
  3217                              <1> 				    ; device/drive number is in 1 byte, 
  3218                              <1> 				    ; not in 1 word!
  3219                              <1> 		; mov u.cdev,cdev / device number for users directory 
  3220                              <1> 				; / into cdev
  3221                              <1> 	; 12/10/2015
  3222                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3223                              <1>       	 ; convert virtual (pathname) addr to physical address
  3224 0000AC97 E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
  3225                              <1> 		; esi = physical address of [u.namep]
  3226                              <1> 		; ecx = byte count in the page
  3227 0000AC9C 803E2F              <1> 	cmp	byte [esi], '/'
  3228                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3229 0000AC9F 751E                <1> 	jne	short namei_1
  3230                              <1> 		; bne 1f
  3231 0000ACA1 FF05[98DF0000]      <1> 	inc	dword [u.namep]
  3232                              <1> 		; inc u.namep / go to next char
  3233 0000ACA7 6649                <1> 	dec	cx ; remain byte count in the page
  3234 0000ACA9 7506                <1> 	jnz	short namei_0
  3235                              <1> 	; 12/10/2015
  3236 0000ACAB E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  3237                              <1> 		; esi = physical address (page start + offset)
  3238                              <1> 		; ecx = byte count in the page
  3239 0000ACB0 4E                  <1> 	dec	esi
  3240                              <1> namei_0:
  3241 0000ACB1 46                  <1> 	inc 	esi  ; go to next char
  3242 0000ACB2 66A1[70DF0000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
  3243                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3244 0000ACB8 C605[66DF0000]00    <1> 	mov	byte [cdev], 0
  3245                              <1> 		; clr cdev / clear device number
  3246                              <1> namei_1: ; 1:
  3247 0000ACBF F606FF              <1> 	test	byte [esi], 0FFh
  3248 0000ACC2 74BE                <1> 	jz	short getf4
  3249                              <1> 	;jz      nig
  3250                              <1> 		; tstb *u.namep / is the character in file name a nul
  3251                              <1> 		; beq nig / yes, end of file name reached; 
  3252                              <1> 			; / branch to "nig"
  3253                              <1> namei_2: ; 1:
  3254                              <1> 	; 18/10/2015
  3255 0000ACC4 8935[F8DF0000]      <1> 	mov 	[nbase], esi
  3256 0000ACCA 66890D[FCDF0000]    <1> 	mov 	[ncount], cx
  3257                              <1> 	;
  3258                              <1> 	;mov	dx, 2
  3259 0000ACD1 B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
  3260 0000ACD3 E89C0D0000          <1> 	call	access
  3261                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
  3262                              <1> 	; 'access' will not return here if user has not "r" permission !
  3263 0000ACD8 66F705[58DC0000]00- <1> 	test 	word [i.flgs], 4000h
  3263 0000ACE0 40                  <1>
  3264                              <1> 		; bit $40000,i.flgs / directory i-node?
  3265 0000ACE1 746A                <1>         jz      short namei_err
  3266                              <1> 		; beq error3 / no, got an error
  3267                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3268 0000ACE3 31C0                <1> 	xor	eax, eax
  3269 0000ACE5 A3[9CDF0000]        <1> 	mov	[u.off], eax ; 0
  3270 0000ACEA 66A1[09E00000]      <1> 	mov	ax, [i.size]
  3271 0000ACF0 A3[94DF0000]        <1> 	mov	[u.dirp], eax
  3272                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
  3273                              <1> 		; clr u.off / u.off is file offset used by user
  3274 0000ACF5 C705[90DF0000]-     <1> 	mov	dword [u.fofp], u.off
  3274 0000ACFB [9CDF0000]          <1>
  3275                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
  3276                              <1> 				  ; / the offset portion of fsp entry
  3277                              <1> namei_3: ; 2:
  3278 0000ACFF C705[A0DF0000]-     <1> 	mov	dword [u.base], u.dirbuf
  3278 0000AD05 [B2DF0000]          <1>
  3279                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  3280                              <1> 				    ; / copied from a directory
  3281 0000AD09 C705[A4DF0000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  3281 0000AD11 0000                <1>
  3282                              <1>  		; mov $10.,u.count / u.count is byte count 
  3283                              <1> 				 ; / for reads and writes
  3284 0000AD13 66A1[05E00000]      <1> 	mov 	ax, [ii]
  3285                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  3286 0000AD19 FE05[E7DF0000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  3287 0000AD1F E80F090000          <1>     	call	readi
  3288                              <1> 		; jsr r0,readi / read 10. bytes of file 
  3289                              <1> 		      ; with i-number (r1); i.e. read a directory entry
  3290 0000AD24 8B0D[A8DF0000]      <1> 	mov 	ecx, [u.nread]
  3291 0000AD2A 09C9                <1> 	or 	ecx, ecx
  3292                              <1> 		; tst u.nread
  3293 0000AD2C 741B                <1> 	jz	short nib
  3294                              <1> 		; ble nib / gives error return
  3295                              <1> 	;
  3296 0000AD2E 668B1D[B2DF0000]    <1> 	mov 	bx, [u.dirbuf]
  3297 0000AD35 6621DB              <1> 	and 	bx, bx       
  3298                              <1> 		; tst u.dirbuf /
  3299 0000AD38 7522                <1> 	jnz	short namei_4
  3300                              <1> 		; bne 3f / branch when active directory entry 
  3301                              <1> 		       ; / (i-node word in entry non zero)
  3302 0000AD3A A1[9CDF0000]        <1> 	mov	eax, [u.off]
  3303 0000AD3F 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  3304 0000AD42 A3[94DF0000]        <1> 	mov	[u.dirp], eax
  3305                              <1> 		; mov u.off,u.dirp
  3306                              <1> 		; sub $10.,u.dirp
  3307 0000AD47 EBB6                <1> 	jmp	short namei_3
  3308                              <1> 		; br 2b
  3309                              <1> 
  3310                              <1> 	; 18/07/2013
  3311                              <1> nib: 
  3312 0000AD49 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  3313 0000AD4B F9                  <1> 	stc
  3314                              <1> nig:
  3315 0000AD4C C3                  <1> 	retn
  3316                              <1> 
  3317                              <1> namei_err:
  3318                              <1> 	; 16/06/2015
  3319 0000AD4D C705[D5DF0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  3319 0000AD55 0000                <1>
  3320 0000AD57 E988F2FFFF          <1> 	jmp	error
  3321                              <1> 
  3322                              <1> namei_4: ; 3:
  3323                              <1> 	; 18/10/2015
  3324                              <1> 	; 12/10/2015
  3325                              <1> 	; 21/08/2015
  3326                              <1> 	; 18/07/2015
  3327 0000AD5C 8B2D[98DF0000]      <1> 	mov	ebp, [u.namep]
  3328                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  3329 0000AD62 BF[B4DF0000]        <1> 	mov 	edi, u.dirbuf + 2
  3330                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
  3331                              <1> 	; 18/10/2015
  3332 0000AD67 8B35[F8DF0000]      <1> 	mov	esi, [nbase]	
  3333 0000AD6D 668B0D[FCDF0000]    <1> 	mov	cx, [ncount]
  3334                              <1> 	;
  3335 0000AD74 6621C9              <1> 	and	cx, cx
  3336 0000AD77 7505                <1> 	jnz	short namei_5	
  3337                              <1> 	;
  3338 0000AD79 E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3339                              <1> 		; esi = physical address (page start + offset)
  3340                              <1> 		; ecx = byte count in the page
  3341                              <1> namei_5: ; 3:
  3342 0000AD7E 45                  <1> 	inc	ebp ; 18/07/2015
  3343 0000AD7F AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
  3344                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
  3345 0000AD80 08C0                <1> 	or 	al, al
  3346 0000AD82 741D                <1> 	jz 	short namei_7
  3347                              <1> 		; beq 3f / if char is nul, then the last char in string
  3348                              <1> 			; / has been moved
  3349 0000AD84 3C2F                <1> 	cmp	al, '/'
  3350                              <1> 		; cmp r4,$'/ / is char a </>
  3351 0000AD86 7419                <1> 	je 	short namei_7
  3352                              <1> 		; beq 3f	
  3353                              <1> 	; 12/10/2015
  3354 0000AD88 6649                <1> 	dec	cx ; remain byte count in the page
  3355 0000AD8A 7505                <1> 	jnz	short namei_6
  3356 0000AD8C E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3357                              <1> 		; esi = physical address (page start + offset)
  3358                              <1> 		; ecx = byte count in the page
  3359                              <1> namei_6:
  3360 0000AD91 81FF[C2DF0000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3361                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
  3362                              <1> 				     ; / all 8 bytes of file name
  3363 0000AD97 74E5                <1> 	je	short namei_5
  3364                              <1> 		; beq 3b
  3365 0000AD99 AE                  <1> 	scasb	
  3366                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  3367                              <1> 			      ; / char read from directory
  3368 0000AD9A 74E2                <1> 	je 	short namei_5
  3369                              <1> 		; beq 3b / branch if chars match
  3370                              <1> 
  3371 0000AD9C E95EFFFFFF          <1>         jmp    namei_3 ; 2b
  3372                              <1> 		; br 2b / file names do not match go to next directory entry
  3373                              <1> namei_7: ; 3:
  3374 0000ADA1 81FF[C2DF0000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3375                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
  3376 0000ADA7 740A                <1> 	je	short namei_8
  3377                              <1> 		; beq 3f
  3378 0000ADA9 8A27                <1> 	mov 	ah, [edi]
  3379                              <1> 	;inc 	edi 
  3380 0000ADAB 20E4                <1> 	and 	ah, ah
  3381                              <1> 		; tstb (r3)+ /
  3382 0000ADAD 0F854CFFFFFF        <1>         jnz     namei_3
  3383                              <1> 		; bne 2b
  3384                              <1> namei_8: ; 3
  3385 0000ADB3 892D[98DF0000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
  3386                              <1> 		; mov r2,u.namep / u.namep points to char 
  3387                              <1> 			       ; / following a / or nul
  3388                              <1> 	;mov	bx, [u.dirbuf]
  3389                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
  3390                              <1> 				; / entry to r1
  3391 0000ADB9 20C0                <1> 	and 	al, al
  3392                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
  3393                              <1> 		      ;  / if r4 = </> then go to next directory
  3394                              <1> 	; mov	ax, bx
  3395 0000ADBB 66A1[B2DF0000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
  3396 0000ADC1 0F85FDFEFFFF        <1>         jnz     namei_2 
  3397                              <1> 		; bne 1b
  3398                              <1> 	; AX = i-number of the file
  3399                              <1> ;;nig:
  3400 0000ADC7 C3                  <1> 	retn
  3401                              <1> 		; tst (r0)+ / gives non-error return
  3402                              <1> ;;nib:
  3403                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
  3404                              <1> 		       ; ax = 0 -> file not found 
  3405                              <1> ;;	stc	; 27/05/2013
  3406                              <1> ;;	retn
  3407                              <1> 		; rts r0
  3408                              <1> 
  3409                              <1> trans_addr_nmbp:
  3410                              <1> 	; 18/10/2015
  3411                              <1> 	; 12/10/2015
  3412 0000ADC8 8B2D[98DF0000]      <1> 	mov 	ebp, [u.namep]
  3413                              <1> trans_addr_nm: 
  3414                              <1> 	; Convert virtual (pathname) address to physical address
  3415                              <1> 	; (Retro UNIX 386 v1 feature only !)
  3416                              <1> 	; 18/10/2015
  3417                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  3418                              <1> 	; 02/07/2015
  3419                              <1> 	; 17/06/2015
  3420                              <1> 	; 16/06/2015
  3421                              <1> 	;
  3422                              <1> 	; INPUTS: 
  3423                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  3424                              <1> 	;	[u.pgdir] = user's page directory
  3425                              <1> 	; OUTPUT:
  3426                              <1> 	;       esi = physical address of the pathname
  3427                              <1> 	;	ecx = remain byte count in the page
  3428                              <1> 	;
  3429                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
  3430                              <1> 	;
  3431 0000ADCE 833D[DDDF0000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  3432 0000ADD5 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  3433                              <1> 				     ; it is already physical address
  3434 0000ADD7 50                  <1>    	push	eax	
  3435 0000ADD8 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  3436 0000ADDA E8C389FFFF          <1>        	call	get_physical_addr ; get physical address
  3437 0000ADDF 7204                <1> 	jc	short tr_addr_nm_err
  3438                              <1> 	; 18/10/2015
  3439                              <1> 	; eax = physical address 
  3440                              <1> 	; cx = remain byte count in page (1-4096) 
  3441                              <1> 		; 12/10/2015 (cx = [u.pncount])
  3442 0000ADE1 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  3443 0000ADE3 58                  <1> 	pop	eax 
  3444 0000ADE4 C3                  <1> 	retn
  3445                              <1> 
  3446                              <1> tr_addr_nm_err:
  3447 0000ADE5 A3[D5DF0000]        <1> 	mov	[u.error], eax
  3448                              <1> 	;pop 	eax
  3449 0000ADEA E9F5F1FFFF          <1> 	jmp	error
  3450                              <1> 
  3451                              <1> trans_addr_nmk:
  3452                              <1> 	; 12/10/2015
  3453                              <1> 	; 02/07/2015
  3454 0000ADEF 8B35[98DF0000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  3455 0000ADF5 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  3456 0000ADF9 C3                  <1> 	retn
  3457                              <1> 
  3458                              <1> syschdir:
  3459                              <1> 	; / makes the directory specified in the argument
  3460                              <1> 	; / the current directory
  3461                              <1> 	;
  3462                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3463                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3464                              <1> 	;
  3465                              <1> 	; 'syschdir' makes the directory specified in its argument
  3466                              <1> 	; the current working directory.
  3467                              <1> 	;
  3468                              <1> 	; Calling sequence:
  3469                              <1> 	;	syschdir; name
  3470                              <1> 	; Arguments:
  3471                              <1> 	;	name - address of the path name of a directory
  3472                              <1> 	;	       terminated by nul byte.	
  3473                              <1> 	; Inputs: -
  3474                              <1> 	; Outputs: -
  3475                              <1> 	; ...............................................................
  3476                              <1> 	;				
  3477                              <1> 	; Retro UNIX 8086 v1 modification:
  3478                              <1> 	;	 The user/application program puts address of 
  3479                              <1> 	;	 the path name in BX register as 'syschdir' 
  3480                              <1> 	; 	 system call argument.
  3481                              <1> 
  3482 0000ADFA 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  3483                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  3484 0000AE00 E87EFEFFFF          <1> 	call	namei
  3485                              <1> 		; jsr r0,namei / find its i-number
  3486                              <1> 	;jc	error
  3487                              <1> 		; br error3
  3488 0000AE05 730F                <1> 	jnc	short syschdir0
  3489                              <1> 	; 'directory not found !' error
  3490 0000AE07 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  3490 0000AE0F 0000                <1>
  3491 0000AE11 E9CEF1FFFF          <1> 	jmp	error
  3492                              <1> syschdir0:
  3493 0000AE16 E8590C0000          <1> 	call	access
  3494                              <1> 		; jsr r0,access; 2 / get i-node into core
  3495 0000AE1B 66F705[58DC0000]00- <1> 	test	word [i.flgs], 4000h
  3495 0000AE23 40                  <1>
  3496                              <1> 		; bit $40000,i.flgs / is it a directory?
  3497                              <1> 	;jz	error 
  3498                              <1> 		; beq error3 / no error
  3499 0000AE24 750F                <1> 	jnz	short syschdir1
  3500 0000AE26 C705[D5DF0000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  3500 0000AE2E 0000                <1>
  3501 0000AE30 E9AFF1FFFF          <1> 	jmp	error
  3502                              <1> syschdir1:
  3503 0000AE35 66A3[84DF0000]      <1> 	mov	[u.cdir], ax
  3504                              <1> 		; mov r1,u.cdir / move i-number to users 
  3505                              <1> 			      ; / current directory
  3506 0000AE3B 66A1[66DF0000]      <1> 	mov	ax, [cdev]
  3507 0000AE41 66A3[CADF0000]      <1> 	mov	[u.cdrv], ax
  3508                              <1> 		; mov cdev,u.cdev / move its device to users 
  3509                              <1> 			        ; / current device
  3510 0000AE47 E9B8F1FFFF          <1> 	jmp	sysret
  3511                              <1> 		; br sysret3
  3512                              <1> 	
  3513                              <1> syschmod: ; < change mode of file >
  3514                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3515                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3516                              <1> 	;
  3517                              <1> 	; 'syschmod' changes mode of the file whose name is given as
  3518                              <1> 	; null terminated string pointed to by 'name' has it's mode 
  3519                              <1> 	; changed to 'mode'.
  3520                              <1> 	;
  3521                              <1> 	; Calling sequence:
  3522                              <1> 	;	syschmod; name; mode
  3523                              <1> 	; Arguments:
  3524                              <1> 	;	name - address of the file name
  3525                              <1> 	;	       terminated by null byte.
  3526                              <1> 	;	mode - (new) mode/flags < attributes >
  3527                              <1> 	;	
  3528                              <1> 	; Inputs: -
  3529                              <1> 	; Outputs: -
  3530                              <1> 	; ...............................................................
  3531                              <1> 	;				
  3532                              <1> 	; Retro UNIX 8086 v1 modification: 
  3533                              <1> 	;       'syschmod' system call has two arguments; so,
  3534                              <1> 	;	* 1st argument, name is pointed to by BX register
  3535                              <1> 	;	* 2nd argument, mode is in CX register
  3536                              <1> 	;
  3537                              <1> 	; Mode bits (Flags):
  3538                              <1> 	;	bit 0 - write permission for non-owner (1)
  3539                              <1> 	;	bit 1 - read permission for non-owner (2)
  3540                              <1> 	;	bit 2 - write permission for owner (4)
  3541                              <1> 	;	bit 3 - read permission for owner (8)
  3542                              <1> 	;	bit 4 - executable flag (16) 	
  3543                              <1> 	;	bit 5 - set user ID on execution flag (32) 
  3544                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
  3545                              <1> 	;	bit 12 - large file flag (4096)
  3546                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
  3547                              <1> 	;	bit 14 - directory flag (16384)
  3548                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
  3549                              <1> 
  3550                              <1> 	; / name; mode
  3551 0000AE4C E814000000          <1> 	call	isown
  3552                              <1> 		;jsr r0,isown / get the i-node and check user status
  3553 0000AE51 66F705[58DC0000]00- <1> 	test	word [i.flgs], 4000h
  3553 0000AE59 40                  <1>
  3554                              <1> 		; bit	$40000,i.flgs / directory?
  3555 0000AE5A 7402                <1> 	jz	short syschmod1
  3556                              <1> 		; beq 2f / no
  3557                              <1> 	; AL = (new) mode
  3558 0000AE5C 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
  3559                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
  3560                              <1> 			   ; / executable modes
  3561                              <1> syschmod1: ; 2:
  3562 0000AE5E A2[58DC0000]        <1> 	mov	[i.flgs], al	
  3563                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
  3564 0000AE63 EB42                <1> 	jmp	short isown1
  3565                              <1> 		; br 1f
  3566                              <1> 
  3567                              <1> isown:
  3568                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3569                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3570                              <1> 	;
  3571                              <1> 	; 'isown' is given a file name (the 1st argument).
  3572                              <1> 	;  It find the i-number of that file via 'namei' 
  3573                              <1> 	;  then gets the i-node into core via 'iget'.
  3574                              <1> 	;  It then tests to see if the user is super user. 
  3575                              <1> 	;  If not, it cheks to see if the user is owner of 
  3576                              <1> 	;  the file. If he is not an error occurs.
  3577                              <1> 	;  If user is the owner 'setimod' is called to indicate
  3578                              <1> 	;  the inode has been modificed and the 2nd argument of
  3579                              <1> 	;  the call is put in r2.
  3580                              <1> 	;
  3581                              <1> 	; INPUTS ->
  3582                              <1> 	;    arguments of syschmod and syschown calls
  3583                              <1> 	; OUTPUTS ->
  3584                              <1> 	;    u.uid - id of user
  3585                              <1> 	;    imod - set to a 1
  3586                              <1> 	;    r2 - contains second argument of the system call				 	
  3587                              <1> 	;
  3588                              <1> 	;   ((AX=R2) output as 2nd argument)
  3589                              <1> 	;
  3590                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  3591                              <1> 	;
  3592                              <1> 		; jsr r0,arg2 / u.namep points to file name
  3593                              <1> 	;; ! 2nd argument on top of stack !
  3594                              <1> 	;; 22/06/2015 - 32 bit modifications
  3595                              <1> 	;; 07/07/2013
  3596 0000AE65 891D[98DF0000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  3597 0000AE6B 51                  <1> 	push 	ecx ;; 2nd argument
  3598                              <1> 	;;
  3599 0000AE6C E812FEFFFF          <1> 	call	namei
  3600                              <1> 		; jsr r0,namei / get its i-number
  3601                              <1>        ; Retro UNIX 8086 v1 modification !
  3602                              <1>        ; ax = 0 -> file not found 
  3603                              <1> 	;and	ax, ax
  3604                              <1> 	;jz	error
  3605                              <1> 	;jc	error ; 27/05/2013
  3606                              <1> 		; br error3
  3607 0000AE71 730F                <1> 	jnc	short isown0
  3608                              <1> 	; 'file not found !' error
  3609 0000AE73 C705[D5DF0000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3609 0000AE7B 0000                <1>
  3610 0000AE7D E962F1FFFF          <1> 	jmp	error
  3611                              <1> isown0:
  3612 0000AE82 E8E00B0000          <1> 	call	iget
  3613                              <1> 		; jsr r0,iget / get i-node into core
  3614 0000AE87 A0[CCDF0000]        <1> 	mov	al, [u.uid] ; 02/08/2013
  3615 0000AE8C 08C0                <1> 	or	al, al
  3616                              <1> 		; tstb u.uid / super user?
  3617 0000AE8E 7417                <1> 	jz	short isown1
  3618                              <1> 		; beq 1f / yes, branch
  3619 0000AE90 3A05[5BDC0000]      <1> 	cmp	al, [i.uid]
  3620                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
  3621                              <1> 				 ; / the file
  3622                              <1> 	;jne	error
  3623                              <1> 		; beq 1f / yes
  3624                              <1> 		; jmp error3 / no, error
  3625 0000AE96 740F                <1> 	je	short isown1
  3626                              <1> 
  3627 0000AE98 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
  3627 0000AEA0 0000                <1>
  3628                              <1> 			;  'permission denied !' error
  3629 0000AEA2 E93DF1FFFF          <1> 	jmp	error
  3630                              <1> isown1: ; 1:
  3631 0000AEA7 E8C40B0000          <1> 	call	setimod
  3632                              <1> 		; jsr r0,setimod / indicates 
  3633                              <1> 		;	       ; / i-node has been modified
  3634 0000AEAC 58                  <1> 	pop	eax ; 2nd argument
  3635                              <1> 		; mov (sp)+,r2 / mode is put in r2 
  3636                              <1> 		       ; / (u.off put on stack with 2nd arg)
  3637 0000AEAD C3                  <1> 	retn
  3638                              <1> 		; rts r0
  3639                              <1> 
  3640                              <1> ;;arg:  ; < get system call arguments >
  3641                              <1> 	; 'arg' extracts an argument for a routine whose call is 
  3642                              <1> 	; of form:
  3643                              <1> 	;	sys 'routine' ; arg1
  3644                              <1> 	;		or
  3645                              <1> 	;	sys 'routine' ; arg1 ; arg2
  3646                              <1> 	;		or
  3647                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
  3648                              <1> 	;	
  3649                              <1> 	; INPUTS ->
  3650                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
  3651                              <1> 	;	This pointers's value is actually the value of
  3652                              <1> 	;	update pc at the the trap to sysent (unkni) is
  3653                              <1> 	;	made to process the sys instruction
  3654                              <1> 	;    r0 - contains the return address for the routine
  3655                              <1> 	;	that called arg. The data in the word pointer 
  3656                              <1> 	;	to by the return address is used as address
  3657                              <1> 	;	in which the extracted argument is stored   		
  3658                              <1> 	;    	
  3659                              <1> 	; OUTPUTS ->
  3660                              <1> 	;    'address' - contains the extracted argument 
  3661                              <1> 	;    u.sp+18 - is incremented by 2 
  3662                              <1> 	;    r1 - contains the extracted argument
  3663                              <1> 	;    r0 - points to the next instruction to be
  3664                              <1> 	;	 executed in the calling routine.
  3665                              <1> 	;
  3666                              <1>   
  3667                              <1> 	; mov u.sp,r1
  3668                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
  3669                              <1> 			; / into argument of arg2
  3670                              <1> 	; add $2,18.(r1) / point pc on stack 
  3671                              <1> 			      ; / to next system argument
  3672                              <1> 	; rts r0
  3673                              <1> 
  3674                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
  3675                              <1> 	; 'arg2' takes first argument in system call
  3676                              <1> 	;  (pointer to name of the file) and puts it in location
  3677                              <1> 	;  u.namep; takes second argument and puts it in u.off
  3678                              <1> 	;  and on top of the stack
  3679                              <1> 	;	
  3680                              <1> 	; INPUTS ->
  3681                              <1> 	;    u.sp, r0
  3682                              <1> 	;    	
  3683                              <1> 	; OUTPUTS ->
  3684                              <1> 	;    u.namep
  3685                              <1> 	;    u.off 
  3686                              <1> 	;    u.off pushed on stack
  3687                              <1> 	;    r1
  3688                              <1> 	;
  3689                              <1> 
  3690                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
  3691                              <1> 				; / first arg in sys call
  3692                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
  3693                              <1> 				; / second arg in sys call
  3694                              <1> 	; mov r0,r1 / r0 points to calling routine
  3695                              <1> 	; mov (sp),r0 / put operation code back in r0
  3696                              <1> 	; mov u.off,(sp) / put pointer to second argument 
  3697                              <1> 			; / on stack
  3698                              <1> 	; jmp (r1) / return to calling routine
  3699                              <1> 
  3700                              <1> syschown: ; < change owner of file >
  3701                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3702                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3703                              <1> 	;
  3704                              <1> 	; 'syschown' changes the owner of the file whose name is given
  3705                              <1> 	; as null terminated string pointed to by 'name' has it's owner
  3706                              <1> 	; changed to 'owner'
  3707                              <1> 	;
  3708                              <1> 	; Calling sequence:
  3709                              <1> 	;	syschown; name; owner
  3710                              <1> 	; Arguments:
  3711                              <1> 	;	name - address of the file name
  3712                              <1> 	;	       terminated by null byte.
  3713                              <1> 	;	owner - (new) owner (number/ID)
  3714                              <1> 	;	
  3715                              <1> 	; Inputs: -
  3716                              <1> 	; Outputs: -
  3717                              <1> 	; ...............................................................
  3718                              <1> 	;				
  3719                              <1> 	; Retro UNIX 8086 v1 modification: 
  3720                              <1> 	;       'syschown' system call has two arguments; so,
  3721                              <1> 	;	* 1st argument, name is pointed to by BX register
  3722                              <1> 	;	* 2nd argument, owner number is in CX register
  3723                              <1> 	;
  3724                              <1> 	; / name; owner
  3725 0000AEAE E8B2FFFFFF          <1> 	call	isown
  3726                              <1> 		; jsr r0,isown / get the i-node and check user status
  3727 0000AEB3 803D[CCDF0000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
  3728                              <1> 		; tstb u.uid / super user
  3729 0000AEBA 7418                <1> 	jz	short syschown1
  3730                              <1> 		; beq 2f / yes, 2f
  3731 0000AEBC F605[58DC0000]20    <1>         test    byte [i.flgs], 20h ; 32
  3732                              <1> 		; bit $40,i.flgs / no, set userid on execution?
  3733                              <1> 	;jnz	error
  3734                              <1> 		; bne 3f / yes error, could create Trojan Horses
  3735 0000AEC3 740F                <1> 	jz	short syschown1
  3736                              <1> 	; 'permission denied !'
  3737 0000AEC5 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  3737 0000AECD 0000                <1>
  3738 0000AECF E910F1FFFF          <1> 	jmp	error
  3739                              <1> syschown1: ; 2:
  3740                              <1> 	; AL = owner (number/ID)
  3741 0000AED4 A2[5BDC0000]        <1> 	mov	[i.uid], al ; 23/06/2015
  3742                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
  3743                              <1> 			       ; / in the i-node
  3744 0000AED9 E926F1FFFF          <1> 	jmp	sysret
  3745                              <1> 	; 1: 
  3746                              <1> 		; jmp sysret4
  3747                              <1> 	; 3:
  3748                              <1> 		; jmp	error
  3749                              <1> 
  3750                              <1> systime: ; / get time of year
  3751                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3752                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  3753                              <1> 	;
  3754                              <1> 	; 20/06/2013
  3755                              <1> 	; 'systime' gets the time of the year.
  3756                              <1> 	; The present time is put on the stack.
  3757                              <1> 	;
  3758                              <1> 	; Calling sequence:
  3759                              <1> 	;	systime
  3760                              <1> 	; Arguments: -
  3761                              <1> 	;	
  3762                              <1> 	; Inputs: -
  3763                              <1> 	; Outputs: sp+2, sp+4 - present time
  3764                              <1> 	; ...............................................................
  3765                              <1> 	;	
  3766                              <1> 	; Retro UNIX 8086 v1 modification: 
  3767                              <1> 	;       'systime' system call will return to the user
  3768                              <1> 	;	with unix time (epoch) in DX:AX register pair
  3769                              <1> 	;
  3770                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
  3771                              <1> 	;	system call for PC compatibility !!		 	
  3772                              <1> 
  3773 0000AEDE E8930B0000          <1> 	call 	epoch
  3774 0000AEE3 A3[80DF0000]        <1> 	mov 	[u.r0], eax
  3775                              <1> 		; mov s.time,4(sp)
  3776                              <1> 		; mov s.time+2,2(sp) / put the present time 
  3777                              <1> 				   ; / on the stack
  3778                              <1> 		; br sysret4
  3779 0000AEE8 E917F1FFFF          <1> 	jmp	sysret 
  3780                              <1> 
  3781                              <1> sysstime: ; / set time
  3782                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3783                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3784                              <1> 	;
  3785                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
  3786                              <1> 	;
  3787                              <1> 	; Calling sequence:
  3788                              <1> 	;	sysstime
  3789                              <1> 	; Arguments: -
  3790                              <1> 	;	
  3791                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
  3792                              <1> 	; Outputs: -
  3793                              <1> 	; ...............................................................
  3794                              <1> 	;	
  3795                              <1> 	; Retro UNIX 8086 v1 modification: 
  3796                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
  3797                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
  3798                              <1> 	; 
  3799                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  3800                              <1> 	;	to get sysstime system call arguments from the user;
  3801                              <1> 	;	* 1st argument, lowword of unix time is in BX register
  3802                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
  3803                              <1> 	;
  3804                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
  3805                              <1> 	;	system call for PC compatibility !!	
  3806                              <1> 
  3807 0000AEED 803D[CCDF0000]00    <1> 	cmp	byte [u.uid], 0
  3808                              <1> 		; tstb u.uid / is user the super user
  3809                              <1> 	;ja	error
  3810                              <1> 		; bne error4 / no, error
  3811 0000AEF4 760F                <1> 	jna	short systime1
  3812                              <1> 	; 'permission denied !'
  3813 0000AEF6 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  3813 0000AEFE 0000                <1>
  3814 0000AF00 E9DFF0FFFF          <1> 	jmp	error
  3815                              <1> systime1:
  3816                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
  3817                              <1> 	; EBX = unix (epoch) time (from user)
  3818 0000AF05 89D8                <1> 	mov	eax, ebx
  3819 0000AF07 E86B0B0000          <1> 	call 	set_date_time
  3820                              <1> 		; mov 4(sp),s.time
  3821                              <1> 		; mov 2(sp),s.time+2 / set the system time
  3822 0000AF0C E9F3F0FFFF          <1> 	jmp	sysret
  3823                              <1> 		; br sysret4
  3824                              <1> 
  3825                              <1> sysbreak:
  3826                              <1> 	; 18/10/2015
  3827                              <1> 	; 07/10/2015
  3828                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3829                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  3830                              <1> 	;
  3831                              <1> 	; 'sysbreak' sets the programs break points. 
  3832                              <1> 	; It checks the current break point (u.break) to see if it is
  3833                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  3834                              <1> 	; even address (if it was odd) and the area between u.break
  3835                              <1> 	; and the stack is cleared. The new breakpoint is then put
  3836                              <1> 	; in u.break and control is passed to 'sysret'.
  3837                              <1> 	;
  3838                              <1> 	; Calling sequence:
  3839                              <1> 	;	sysbreak; addr
  3840                              <1> 	; Arguments: -
  3841                              <1> 	;	
  3842                              <1> 	; Inputs: u.break - current breakpoint
  3843                              <1> 	; Outputs: u.break - new breakpoint 
  3844                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  3845                              <1> 	; ...............................................................
  3846                              <1> 	;	
  3847                              <1> 	; Retro UNIX 8086 v1 modification:
  3848                              <1> 	;	The user/application program puts breakpoint address
  3849                              <1> 	;       in BX register as 'sysbreak' system call argument.
  3850                              <1> 	; 	(argument transfer method 1)
  3851                              <1> 	;
  3852                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  3853                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  3854                              <1> 	;  NOTE:
  3855                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  3856                              <1> 	;	'u.break' address) of user's memory for original unix's
  3857                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  3858                              <1> 
  3859                              <1> 		; mov u.break,r1 / move users break point to r1
  3860                              <1> 		; cmp r1,$core / is it the same or lower than core?
  3861                              <1> 		; blos 1f / yes, 1f
  3862                              <1> 	; 23/06/2015
  3863 0000AF11 8B2D[ACDF0000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  3864                              <1> 	;and	ebp, ebp
  3865                              <1> 	;jz	short sysbreak_3 
  3866                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  3867                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  3868 0000AF17 8B15[78DF0000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  3869 0000AF1D 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  3870                              <1> 	; 07/10/2015
  3871 0000AF20 891D[ACDF0000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  3872                              <1> 	;
  3873 0000AF26 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  3874                              <1> 			   ; with top of user's stack (virtual!)
  3875 0000AF28 7327                <1> 	jnb	short sysbreak_3
  3876                              <1> 		; cmp r1,sp / is it the same or higher 
  3877                              <1> 			  ; / than the stack?
  3878                              <1> 		; bhis 1f / yes, 1f
  3879 0000AF2A 89DE                <1> 	mov	esi, ebx
  3880 0000AF2C 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  3881 0000AF2E 7621                <1> 	jna	short sysbreak_3 
  3882                              <1> 	;push	ebx
  3883                              <1> sysbreak_1:
  3884 0000AF30 89EB                <1> 	mov	ebx, ebp  
  3885 0000AF32 E86B88FFFF          <1> 	call	get_physical_addr ; get physical address
  3886 0000AF37 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
  3887                              <1> 	; 18/10/2015
  3888 0000AF3D 89C7                <1> 	mov	edi, eax 
  3889 0000AF3F 29C0                <1> 	sub	eax, eax ; 0
  3890                              <1> 		 ; ECX = remain byte count in page (1-4096)
  3891 0000AF41 39CE                <1> 	cmp	esi, ecx
  3892 0000AF43 7302                <1> 	jnb	short sysbreak_2
  3893 0000AF45 89F1                <1> 	mov	ecx, esi
  3894                              <1> sysbreak_2:
  3895 0000AF47 29CE                <1> 	sub	esi, ecx
  3896 0000AF49 01CD                <1> 	add	ebp, ecx
  3897 0000AF4B F3AA                <1> 	rep 	stosb
  3898 0000AF4D 09F6                <1> 	or	esi, esi
  3899 0000AF4F 75DF                <1> 	jnz	short sysbreak_1
  3900                              <1> 	;
  3901                              <1> 		; bit $1,r1 / is it an odd address
  3902                              <1> 		; beq 2f / no, its even
  3903                              <1> 		; clrb (r1)+ / yes, make it even
  3904                              <1> 	; 2: / clear area between the break point and the stack
  3905                              <1> 		; cmp r1,sp / is it higher or same than the stack
  3906                              <1> 		; bhis 1f / yes, quit
  3907                              <1> 		; clr (r1)+ / clear word
  3908                              <1> 		; br 2b / go back
  3909                              <1> 	;pop	ebx
  3910                              <1> sysbreak_3: ; 1:
  3911                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  3912                              <1> 		; jsr r0,arg; u.break / put the "address" 
  3913                              <1> 			; / in u.break (set new break point)
  3914                              <1> 		; br sysret4 / br sysret
  3915 0000AF51 E9AEF0FFFF          <1> 	jmp	sysret
  3916                              <1> 
  3917                              <1> 
  3918                              <1> maknod: 
  3919                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3920                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3921                              <1> 	;
  3922                              <1> 	; 'maknod' creates an i-node and makes a directory entry
  3923                              <1> 	; for this i-node in the current directory.
  3924                              <1> 	;
  3925                              <1> 	; INPUTS ->
  3926                              <1> 	;    r1 - contains mode
  3927                              <1> 	;    ii - current directory's i-number	
  3928                              <1> 	;    	
  3929                              <1> 	; OUTPUTS ->
  3930                              <1> 	;    u.dirbuf - contains i-number of free i-node 
  3931                              <1> 	;    i.flgs - flags in new i-node 
  3932                              <1> 	;    i.uid - filled with u.uid
  3933                              <1> 	;    i.nlks - 1 is put in the number of links
  3934                              <1> 	;    i.ctim - creation time				
  3935                              <1> 	;    i.ctim+2 - modification time
  3936                              <1> 	;    imod - set via call to setimod
  3937                              <1> 	;	
  3938                              <1> 	; ((AX = R1)) input
  3939                              <1> 	;
  3940                              <1> 	; (Retro UNIX Prototype : 
  3941                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
  3942                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  3943                              <1> 
  3944                              <1> 	; / r1 contains the mode
  3945 0000AF56 80CC80              <1> 	or 	ah, 80h  ; 10000000b
  3946                              <1> 		; bis	$100000,r1 / allocate flag set
  3947 0000AF59 6650                <1> 	push	ax
  3948                              <1> 		; mov r1,-(sp) / put mode on stack
  3949                              <1> 	; 31/07/2013
  3950 0000AF5B 66A1[05E00000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
  3951                              <1> 		; mov ii,r1 / move current i-number to r1
  3952 0000AF61 B201                <1> 	mov	dl, 1 ; owner flag mask
  3953 0000AF63 E80C0B0000          <1> 	call	access	
  3954                              <1> 		; jsr r0,access; 1 / get its i-node into core
  3955 0000AF68 6650                <1> 	push	ax
  3956                              <1> 		; mov r1,-(sp) / put i-number on stack
  3957 0000AF6A 66B82800            <1> 	mov	ax, 40
  3958                              <1> 		; mov $40.,r1 / r1 = 40
  3959                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
  3960 0000AF6E 6640                <1> 	inc	ax
  3961                              <1> 		; inc r1 / r1 = r1 + 1
  3962 0000AF70 E8030B0000          <1> 	call	imap
  3963                              <1> 		; jsr r0,imap / get byte address and bit position in 
  3964                              <1> 			    ; /	inode map in r2 & m
  3965                              <1>           ; DX (MQ) has a 1 in the calculated bit position
  3966                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
  3967                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
  3968                              <1> 	;	       Inode count must be checked here
  3969                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
  3970 0000AF75 8413                <1> 	test	[ebx], dl
  3971                              <1> 		; bitb mq,(r2) / is the i-node active
  3972 0000AF77 75F5                <1> 	jnz	short maknod1
  3973                              <1> 		; bne 1b / yes, try the next one
  3974 0000AF79 0813                <1> 	or	[ebx], dl
  3975                              <1> 		; bisb mq,(r2) / no, make it active 
  3976                              <1> 			     ; / (put a 1 in the bit map)
  3977 0000AF7B E8E70A0000          <1> 	call	iget
  3978                              <1> 		; jsr r0,iget / get i-node into core
  3979 0000AF80 66F705[58DC0000]00- <1> 	test	word [i.flgs], 8000h 
  3979 0000AF88 80                  <1>
  3980                              <1> 		; tst i.flgs / is i-node already allocated
  3981 0000AF89 75E3                <1> 	jnz	short maknod1	
  3982                              <1> 		; blt 1b / yes, look for another one
  3983 0000AF8B 66A3[B2DF0000]      <1> 	mov	[u.dirbuf], ax
  3984                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  3985 0000AF91 6658                <1> 	pop	ax
  3986                              <1> 		; mov (sp)+,r1 / get current i-number back
  3987 0000AF93 E8CF0A0000          <1> 	call	iget
  3988                              <1> 		; jsr r0,iget / get i-node in core
  3989 0000AF98 E88AF9FFFF          <1> 	call	mkdir
  3990                              <1> 		; jsr r0,mkdir / make a directory entry 
  3991                              <1> 			     ; / in current directory
  3992 0000AF9D 66A1[B2DF0000]      <1> 	mov	ax, [u.dirbuf]
  3993                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  3994 0000AFA3 E8BF0A0000          <1> 	call	iget
  3995                              <1> 		; jsr r0,iget / get it into core
  3996                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
  3997 0000AFA8 B908000000          <1> 	mov	ecx, 8 
  3998 0000AFAD 31C0                <1> 	xor	eax, eax ; 0
  3999 0000AFAF BF[58DC0000]        <1> 	mov	edi, inode 
  4000 0000AFB4 F3AB                <1> 	rep	stosd
  4001                              <1> 	;
  4002 0000AFB6 668F05[58DC0000]    <1> 	pop	word [i.flgs]
  4003                              <1> 		; mov (sp)+,i.flgs / fill flags
  4004 0000AFBD 8A0D[CCDF0000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
  4005 0000AFC3 880D[5BDC0000]      <1> 	mov 	[i.uid], cl
  4006                              <1> 		; movb u.uid,i.uid / user id	
  4007 0000AFC9 C605[5ADC0000]01    <1> 	mov     byte [i.nlks], 1
  4008                              <1> 		; movb $1,i.nlks / 1 link
  4009                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
  4010                              <1> 	;mov	eax, [s.time]
  4011                              <1> 	;mov 	[i.ctim], eax
  4012                              <1> 	 	; mov s.time,i.ctim / time created
  4013                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
  4014                              <1> 	; Retro UNIX 8086 v1 modification !
  4015                              <1> 	; i.ctime=0, i.ctime+2=0 and
  4016                              <1>         ; 'setimod' will set ctime of file via 'epoch'
  4017 0000AFD0 E89B0A0000          <1> 	call setimod
  4018                              <1> 		; jsr r0,setimod / set modified flag
  4019 0000AFD5 C3                  <1> 	retn
  4020                              <1> 		; rts r0 / return
  4021                              <1> 
  4022                              <1> sysseek: ; / moves read write pointer in an fsp entry
  4023                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4024                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4025                              <1> 	;
  4026                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  4027                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  4028                              <1> 	; The file descriptor refers to a file open for reading or
  4029                              <1> 	; writing. The read (or write) pointer is set as follows:
  4030                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  4031                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  4032                              <1> 	;	  current location plus offset.
  4033                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  4034                              <1> 	;	  size of file plus offset.
  4035                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  4036                              <1> 	;
  4037                              <1> 	; Calling sequence:
  4038                              <1> 	;	sysseek; offset; ptrname
  4039                              <1> 	; Arguments:
  4040                              <1> 	;	offset - number of bytes desired to move 
  4041                              <1> 	;		 the r/w pointer
  4042                              <1> 	;	ptrname - a switch indicated above
  4043                              <1> 	;
  4044                              <1> 	; Inputs: r0 - file descriptor 
  4045                              <1> 	; Outputs: -
  4046                              <1> 	; ...............................................................
  4047                              <1> 	;	
  4048                              <1> 	; Retro UNIX 8086 v1 modification: 
  4049                              <1> 	;       'sysseek' system call has three arguments; so,
  4050                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  4051                              <1> 	;	* 2nd argument, offset is in CX register
  4052                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  4053                              <1> 	;	
  4054                              <1> 
  4055 0000AFD6 E823000000          <1> 	call	seektell
  4056                              <1> 	; AX = u.count
  4057                              <1> 	; BX = *u.fofp
  4058                              <1> 		; jsr r0,seektell / get proper value in u.count
  4059                              <1> 		; add u.base,u.count / add u.base to it
  4060 0000AFDB 0305[A0DF0000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  4061 0000AFE1 8903                <1> 	mov	[ebx], eax
  4062                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  4063 0000AFE3 E91CF0FFFF          <1> 	jmp	sysret
  4064                              <1> 		; br sysret4
  4065                              <1> 
  4066                              <1> systell: ; / get the r/w pointer
  4067                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4068                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4069                              <1> 	;
  4070                              <1> 	; Retro UNIX 8086 v1 modification:
  4071                              <1> 	; ! 'systell' does not work in original UNIX v1,
  4072                              <1> 	; 	    it returns with error !
  4073                              <1> 	; Inputs: r0 - file descriptor 
  4074                              <1> 	; Outputs: r0 - file r/w pointer
  4075                              <1> 
  4076                              <1> 	;xor	ecx, ecx ; 0
  4077 0000AFE8 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  4078                              <1> 	;call 	seektell
  4079 0000AFED E812000000          <1> 	call 	seektell0 ; 05/08/2013
  4080                              <1> 	;mov	ebx, [u.fofp]
  4081 0000AFF2 8B03                <1> 	mov	eax, [ebx]
  4082 0000AFF4 A3[80DF0000]        <1> 	mov	[u.r0], eax
  4083 0000AFF9 E906F0FFFF          <1> 	jmp	sysret
  4084                              <1> 
  4085                              <1> ; Original unix v1 'systell' system call:
  4086                              <1> 		; jsr r0,seektell
  4087                              <1> 		; br error4
  4088                              <1> 
  4089                              <1> seektell:
  4090                              <1> 	; 03/01/2016
  4091                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4092                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4093                              <1> 	;
  4094                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  4095                              <1> 	; call in u.base and u.count. It then gets the i-number of
  4096                              <1> 	; the file from the file descriptor in u.r0 and by calling
  4097                              <1> 	; getf. The i-node is brought into core and then u.count
  4098                              <1> 	; is checked to see it is a 0, 1, or 2.
  4099                              <1> 	; If it is 0 - u.count stays the same
  4100                              <1> 	;          1 - u.count = offset (u.fofp)
  4101                              <1> 	;	   2 - u.count = i.size (size of file)
  4102                              <1> 	; 	 		
  4103                              <1> 	; !! Retro UNIX 8086 v1 modification:
  4104                              <1> 	;	Argument 1, file descriptor is in BX;
  4105                              <1> 	;	Argument 2, offset is in CX;
  4106                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  4107                              <1> 	;
  4108                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
  4109                              <1> 	; call 	arg
  4110                              <1> 	;
  4111                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
  4112                              <1> 	;
  4113 0000AFFE 890D[A0DF0000]      <1> 	mov 	[u.base], ecx ; offset
  4114                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  4115                              <1> seektell0:
  4116 0000B004 8915[A4DF0000]      <1> 	mov 	[u.count], edx
  4117                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
  4118                              <1> 	; mov	ax, bx
  4119                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
  4120                              <1> 			     ; / (index in u.fp list)
  4121                              <1> 	; call	getf
  4122                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
  4123                              <1> 	; BX = file descriptor (file number)
  4124 0000B00A E83DFCFFFF          <1> 	call	getf1
  4125 0000B00F 6609C0              <1> 	or	ax, ax ; i-number of the file
  4126                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
  4127                              <1> 		             ; / put it on the stack
  4128                              <1> 	;jz	error
  4129                              <1> 		; beq error4 / if i-number is 0, not active so error
  4130 0000B012 750F                <1> 	jnz	short seektell1
  4131 0000B014 C705[D5DF0000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  4131 0000B01C 0000                <1>
  4132 0000B01E E9C1EFFFFF          <1> 	jmp	error
  4133                              <1> seektell1:
  4134                              <1> 	;push	eax
  4135 0000B023 80FC80              <1> 	cmp	ah, 80h
  4136 0000B026 7203                <1> 	jb	short seektell2
  4137                              <1> 		; bgt .+4 / if its positive jump
  4138 0000B028 66F7D8              <1> 	neg	ax
  4139                              <1> 		; neg r1 / if not make it positive
  4140                              <1> seektell2:
  4141 0000B02B E8370A0000          <1> 	call	iget
  4142                              <1> 		; jsr r0,iget / get its i-node into core
  4143 0000B030 8B1D[90DF0000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  4144 0000B036 803D[A4DF0000]01    <1> 	cmp	byte [u.count], 1
  4145                              <1> 		; cmp u.count,$1 / is ptr name =1
  4146 0000B03D 7705                <1> 	ja	short seektell3
  4147                              <1> 		; blt 2f / no its zero
  4148 0000B03F 740A                <1> 	je	short seektell_4
  4149                              <1> 		; beq 1f / yes its 1
  4150 0000B041 31C0                <1> 	xor	eax, eax
  4151                              <1> 	;jmp	short seektell_5
  4152 0000B043 C3                  <1> 	retn
  4153                              <1> seektell3:
  4154                              <1> 	; 03/01/2016
  4155                              <1> 	;movzx	eax, word [i.size]
  4156 0000B044 66A1[09E00000]      <1>         mov   	ax, [i.size]
  4157                              <1>                 ; mov i.size,u.count /  put number of bytes 
  4158                              <1>                                    ; / in file in u.count
  4159                              <1> 	;jmp	short seektell_5
  4160                              <1> 		; br 2f
  4161 0000B04A C3                  <1> 	retn
  4162                              <1> seektell_4: ; 1: / ptrname =1
  4163                              <1> 	;mov	ebx, [u.fofp]
  4164 0000B04B 8B03                <1> 	mov	eax, [ebx]
  4165                              <1> 		; mov *u.fofp,u.count / put offset in u.count
  4166                              <1> ;seektell_5: ; 2: / ptrname =0
  4167                              <1> 	;mov	[u.count], eax
  4168                              <1> 	;pop	eax 
  4169                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
  4170 0000B04D C3                  <1> 	retn
  4171                              <1> 		; rts r0
  4172                              <1> 
  4173                              <1> sysintr: ; / set interrupt handling
  4174                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4175                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4176                              <1> 	;
  4177                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  4178                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  4179                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  4180                              <1> 	; If one does the interrupt character in the tty buffer is
  4181                              <1> 	; cleared and 'sysret'is called. If one does not exits
  4182                              <1> 	; 'sysret' is just called.	
  4183                              <1> 	;
  4184                              <1> 	; Calling sequence:
  4185                              <1> 	;	sysintr; arg
  4186                              <1> 	; Argument:
  4187                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  4188                              <1> 	;	    - if 1, intterupts cause their normal result
  4189                              <1> 	;		 i.e force an exit.
  4190                              <1> 	;	    - if arg is a location within the program,
  4191                              <1> 	;		control is passed to that location when
  4192                              <1> 	;		an interrupt occurs.	
  4193                              <1> 	; Inputs: -
  4194                              <1> 	; Outputs: -
  4195                              <1> 	; ...............................................................
  4196                              <1> 	;	
  4197                              <1> 	; Retro UNIX 8086 v1 modification: 
  4198                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  4199                              <1> 	;	then branches into sysquit.
  4200                              <1> 	;
  4201 0000B04E 66891D[C4DF0000]    <1> 	mov	[u.intr], bx
  4202                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  4203                              <1> 		; br 1f / go into quit routine
  4204 0000B055 E9AAEFFFFF          <1> 	jmp	sysret
  4205                              <1> 
  4206                              <1> sysquit:
  4207                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4208                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4209                              <1> 	;
  4210                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  4211                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  4212                              <1> 	; tty exists. If one does the interrupt character in the tty
  4213                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  4214                              <1> 	; 'sysret' is just called.	
  4215                              <1> 	;
  4216                              <1> 	; Calling sequence:
  4217                              <1> 	;	sysquit; arg
  4218                              <1> 	; Argument:
  4219                              <1> 	;	arg - if 0, this call diables quit signals from the
  4220                              <1> 	;		typewriter (ASCII FS)
  4221                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  4222                              <1> 	;		cease and a core image to be produced.
  4223                              <1> 	;		 i.e force an exit.
  4224                              <1> 	;	    - if arg is an addres in the program,
  4225                              <1> 	;		a quit causes control to sent to that
  4226                              <1> 	;		location.	
  4227                              <1> 	; Inputs: -
  4228                              <1> 	; Outputs: -
  4229                              <1> 	; ...............................................................
  4230                              <1> 	;	
  4231                              <1> 	; Retro UNIX 8086 v1 modification: 
  4232                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  4233                              <1> 	;	then branches into 'sysret'.
  4234                              <1> 	;
  4235 0000B05A 66891D[C6DF0000]    <1> 	mov	[u.quit], bx
  4236 0000B061 E99EEFFFFF          <1> 	jmp	sysret
  4237                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  4238                              <1> 	;1:
  4239                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  4240                              <1> 			      ; / to r1
  4241                              <1> 		; beq sysret4 / return to user
  4242                              <1> 		; clrb 6(r1) / clear the interrupt character 
  4243                              <1> 			   ; / in the tty buffer
  4244                              <1> 		; br sysret4 / return to user
  4245                              <1> 
  4246                              <1> syssetuid: ; / set process id
  4247                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4248                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4249                              <1> 	;
  4250                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
  4251                              <1> 	; to the process id in (u.r0). Both the effective user and 
  4252                              <1> 	; u.uid and the real user u.ruid are set to this. 
  4253                              <1> 	; Only the super user can make this call.	
  4254                              <1> 	;
  4255                              <1> 	; Calling sequence:
  4256                              <1> 	;	syssetuid
  4257                              <1> 	; Arguments: -
  4258                              <1> 	;
  4259                              <1> 	; Inputs: (u.r0) - contains the process id.
  4260                              <1> 	; Outputs: -
  4261                              <1> 	; ...............................................................
  4262                              <1> 	;	
  4263                              <1> 	; Retro UNIX 8086 v1 modification: 
  4264                              <1> 	;       BL contains the (new) user ID of the current process
  4265                              <1> 
  4266                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
  4267 0000B066 3A1D[CDDF0000]      <1> 	cmp	bl, [u.ruid] 
  4268                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
  4269                              <1> 			       ; / id number
  4270 0000B06C 741E                <1> 	je	short setuid1
  4271                              <1> 		; beq 1f / yes
  4272 0000B06E 803D[CCDF0000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  4273                              <1> 		; tstb u.uid / no, is current user the super user?
  4274                              <1> 	;ja	error
  4275                              <1> 		; bne error4 / no, error
  4276 0000B075 760F                <1> 	jna	short setuid0
  4277 0000B077 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  4277 0000B07F 0000                <1>
  4278                              <1> 				;  'permission denied !' error
  4279 0000B081 E95EEFFFFF          <1> 	jmp	error
  4280                              <1> setuid0:
  4281 0000B086 881D[CDDF0000]      <1> 	mov	[u.ruid], bl
  4282                              <1> setuid1: ; 1:
  4283 0000B08C 881D[CCDF0000]      <1> 	mov	[u.uid], bl ; 02/08/2013
  4284                              <1> 		; movb r1,u.uid / put process id in u.uid
  4285                              <1> 		; movb r1,u.ruid / put process id in u.ruid
  4286 0000B092 E96DEFFFFF          <1> 	jmp	sysret
  4287                              <1> 		; br sysret4 / system return
  4288                              <1> 
  4289                              <1> sysgetuid: ; < get user id >
  4290                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4291                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4292                              <1> 	;
  4293                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
  4294                              <1> 	; The real user ID identifies the person who is logged in,
  4295                              <1> 	; in contradistinction to the effective user ID, which
  4296                              <1> 	; determines his access permission at each moment. It is thus
  4297                              <1> 	; useful to programs which operate using the 'set user ID'
  4298                              <1> 	; mode, to find out who invoked them.	
  4299                              <1> 	;
  4300                              <1> 	; Calling sequence:
  4301                              <1> 	;	syssetuid
  4302                              <1> 	; Arguments: -
  4303                              <1> 	;
  4304                              <1> 	; Inputs: -
  4305                              <1> 	; Outputs: (u.r0) - contains the real user's id.
  4306                              <1> 	; ...............................................................
  4307                              <1> 	;	
  4308                              <1> 	; Retro UNIX 8086 v1 modification: 
  4309                              <1> 	;       AL contains the real user ID at return.
  4310                              <1> 	;
  4311 0000B097 0FB605[CDDF0000]    <1> 	movzx 	eax, byte [u.ruid]
  4312 0000B09E A3[80DF0000]        <1> 	mov	[u.r0], eax
  4313                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  4314 0000B0A3 E95CEFFFFF          <1> 	jmp	sysret
  4315                              <1> 		; br sysret4 / systerm return, sysret
  4316                              <1> 
  4317                              <1> anyi: 
  4318                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4319                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  4320                              <1> 	;
  4321                              <1> 	; 'anyi' is called if a file deleted while open.
  4322                              <1> 	; "anyi" checks to see if someone else has opened this file.
  4323                              <1> 	;
  4324                              <1> 	; INPUTS ->
  4325                              <1> 	;    r1 - contains an i-number
  4326                              <1> 	;    fsp - start of table containing open files
  4327                              <1> 	;
  4328                              <1> 	; OUTPUTS ->
  4329                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  4330                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  4331                              <1> 	;    if file not found - bit in i-node map is cleared
  4332                              <1> 	;    			 (i-node is freed)
  4333                              <1> 	;               all blocks related to i-node are freed
  4334                              <1> 	;	        all flags in i-node are cleared
  4335                              <1> 	; ((AX = R1)) input
  4336                              <1> 	;
  4337                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  4338                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  4339                              <1> 	;
  4340                              <1> 		; / r1 contains an i-number
  4341 0000B0A8 BB[58DD0000]        <1> 	mov	ebx, fsp
  4342                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  4343                              <1> anyi_1: ; 1:
  4344 0000B0AD 663B03              <1> 	cmp	ax, [ebx]
  4345                              <1> 		; cmp r1,(r2) / do i-numbers match?
  4346 0000B0B0 7433                <1> 	je	short anyi_3
  4347                              <1> 		; beq 1f / yes, 1f
  4348 0000B0B2 66F7D8              <1> 	neg	ax
  4349                              <1> 		; neg r1 / no complement r1
  4350 0000B0B5 663B03              <1> 	cmp	ax, [ebx]
  4351                              <1> 		; cmp r1,(r2) / do they match now?
  4352 0000B0B8 742B                <1> 	je	short anyi_3
  4353                              <1> 		; beq 1f / yes, transfer
  4354                              <1> 		; / i-numbers do not match
  4355 0000B0BA 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
  4356                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
  4357                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
  4358 0000B0BD 81FB[4CDF0000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
  4359                              <1> 		; cmp r2,$fsp+[nfiles*8] 
  4360                              <1> 				; / are we at last entry in the table
  4361 0000B0C3 72E8                <1> 	jb	short anyi_1
  4362                              <1> 		; blt 1b / no, check next entries i-number
  4363                              <1> 	;cmp	ax, 32768
  4364 0000B0C5 80FC80              <1> 	cmp	ah, 80h ; negative number check
  4365                              <1> 		; tst r1 / yes, no match
  4366                              <1> 		; bge .+4
  4367 0000B0C8 7203                <1> 	jb	short anyi_2
  4368 0000B0CA 66F7D8              <1> 	neg	ax
  4369                              <1> 		; neg r1 / make i-number positive
  4370                              <1> anyi_2:	
  4371 0000B0CD E8A6090000          <1> 	call	imap
  4372                              <1> 		; jsr r0,imap / get address of allocation bit 
  4373                              <1> 			    ; / in the i-map in r2
  4374                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
  4375                              <1>         ;; eBX (R2) has address of the byte with allocation bit
  4376                              <1>  	; not	dx
  4377 0000B0D2 F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
  4378                              <1>         ;and	[ebx], dx
  4379 0000B0D4 2013                <1> 	and 	[ebx], dl 
  4380                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  4381 0000B0D6 E893090000          <1> 	call	itrunc
  4382                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  4383 0000B0DB 66C705[58DC0000]00- <1>  	mov 	word [i.flgs], 0
  4383 0000B0E3 00                  <1>
  4384                              <1> 		; clr i.flgs / clear all flags in the i-node
  4385 0000B0E4 C3                  <1> 	retn
  4386                              <1> 		;rts	r0 / return
  4387                              <1> anyi_3: ; 1: / i-numbers match
  4388 0000B0E5 FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
  4389                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
  4390                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
  4391 0000B0E8 C3                  <1> 	retn
  4392                              <1> 		; rts r0
  4393                              <1> 
  4394                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u7.s
  4395                              <1> ; Last Modification: 14/11/2015
  4396                              <1> 
  4397                              <1> sysmount: ; / mount file system; args special; name
  4398                              <1> 	; 14/11/2015
  4399                              <1> 	; 24/10/2015
  4400                              <1> 	; 13/10/2015
  4401                              <1> 	; 10/07/2015
  4402                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4403                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4404                              <1> 	;
  4405                              <1> 	; 'sysmount' anounces to the system that a removable 
  4406                              <1> 	; file system has been mounted on a special file.
  4407                              <1> 	; The device number of the special file is obtained via
  4408                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
  4409                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
  4410                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
  4411                              <1> 	; to read file system into core, i.e. the first block on the
  4412                              <1> 	; mountable file system is read in. This block is super block
  4413                              <1> 	; for the file system. This call is super user restricted.	
  4414                              <1> 	;
  4415                              <1> 	; Calling sequence:
  4416                              <1> 	;	sysmount; special; name
  4417                              <1> 	; Arguments:
  4418                              <1> 	;	special - pointer to name of special file (device)
  4419                              <1> 	;	name -  pointer to name of the root directory of the
  4420                              <1> 	;		newly mounted file system. 'name' should 
  4421                              <1> 	;		always be a directory.
  4422                              <1> 	; Inputs: - 
  4423                              <1> 	; Outputs: -
  4424                              <1> 	; ...............................................................
  4425                              <1> 	;				
  4426                              <1> 	; Retro UNIX 8086 v1 modification: 
  4427                              <1> 	;       'sysmount' system call has two arguments; so,
  4428                              <1> 	;	* 1st argument, special is pointed to by BX register
  4429                              <1> 	;	* 2nd argument, name is in CX register
  4430                              <1> 	;
  4431                              <1> 	;	NOTE: Device numbers, names and related procedures are 
  4432                              <1> 	;	       already modified for IBM PC compatibility and 
  4433                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
  4434                              <1> 	
  4435                              <1> 	;call	arg2
  4436                              <1> 		; jsr r0,arg2 / get arguments special and name
  4437 0000B0E9 891D[98DF0000]      <1> 	mov	[u.namep], ebx
  4438 0000B0EF 51                  <1> 	push	ecx ; directory name
  4439 0000B0F0 66833D[6CDF0000]00  <1> 	cmp	word [mnti], 0
  4440                              <1> 		; tst mnti / is the i-number of the cross device file
  4441                              <1> 			 ; / zero?
  4442                              <1> 	;ja	error
  4443                              <1>         	; bne errora / no, error
  4444 0000B0F8 0F87E9000000        <1> 	ja	sysmnt_err0
  4445                              <1> 	;
  4446 0000B0FE E8CC000000          <1> 	call	getspl
  4447                              <1> 		; jsr r0,getspl / get special files device number in r1
  4448                              <1> 	; 13/10/2015
  4449 0000B103 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
  4450 0000B106 F683[BAC90000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
  4451 0000B10D 750F                <1> 	jnz	short sysmnt_1
  4452                              <1> sysmnt_err1:
  4453 0000B10F C705[D5DF0000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  4453 0000B117 0000                <1>
  4454 0000B119 E9C6EEFFFF          <1> 	jmp	error
  4455                              <1> sysmnt_1:
  4456 0000B11E 8F05[98DF0000]      <1> 	pop	dword [u.namep]
  4457                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
  4458                              <1> 				  ; / on the device
  4459                              <1> 	; 14/11/2015
  4460 0000B124 53                  <1> 	push	ebx ; 13/10/2015
  4461                              <1> 		; mov r1,-(sp) / save the device number
  4462                              <1>         ;
  4463 0000B125 E859FBFFFF          <1> 	call	namei
  4464                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4465                              <1> 		       ; ax = 0 -> file not found 	
  4466                              <1> 	;jz	error
  4467                              <1> 	;jc	error
  4468                              <1> 		; jsr r0,namei / get the i-number of the file
  4469                              <1>                	; br errora
  4470 0000B12A 730F                <1> 	jnc	short sysmnt_2
  4471                              <1> sysmnt_err2:
  4472 0000B12C C705[D5DF0000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  4472 0000B134 0000                <1>
  4473 0000B136 E9A9EEFFFF          <1> 	jmp	error
  4474                              <1> sysmnt_2:	
  4475 0000B13B 66A3[6CDF0000]      <1> 	mov	[mnti], ax
  4476                              <1>         	; mov r1,mnti / put it in mnti
  4477                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
  4478                              <1> sysmnt_3: ;1:
  4479                              <1>         ;cmp	byte [ebx+1], 0
  4480                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
  4481                              <1> 			   ; / dismountable device set?
  4482                              <1>         ;jna	short sysmnt_4		
  4483                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
  4484                              <1> 	;call	idle 	; (wait for hardware interrupt)
  4485                              <1> 	;jmp	short sysmnt_3
  4486                              <1> sysmnt_4:   
  4487 0000B141 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  4488 0000B142 A2[69DF0000]        <1> 	mov	[mdev], al
  4489                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
  4490 0000B147 8803                <1> 	mov	[ebx], al
  4491                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
  4492                              <1> 			      ; / of the I/O queue entry
  4493                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
  4494                              <1>         	; mov (sp)+,cdev / put device number in cdev
  4495 0000B149 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
  4496                              <1> 		; bis $2000,sb1 / set the read bit
  4497                              <1> 	; Retro UNIX 386 v1 modification : 
  4498                              <1> 	;	32 bit block number at buffer header offset 4
  4499 0000B14E C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
  4500 0000B155 E81F090000          <1> 	call 	diskio
  4501 0000B15A 731C                <1> 	jnc	short sysmnt_5
  4502 0000B15C 31C0                <1> 	xor 	eax, eax
  4503 0000B15E 66A3[6CDF0000]      <1> 	mov	[mnti], ax ; 0
  4504 0000B164 A2[69DF0000]        <1> 	mov	[mdev], al ; 0
  4505                              <1> 	;mov	[cdev], al ; 0
  4506                              <1> sysmnt_invd:
  4507                              <1> 	; 14/11/2015
  4508 0000B169 FEC8                <1> 	dec 	al
  4509 0000B16B 8903                <1> 	mov	[ebx], eax ; 000000FFh
  4510 0000B16D FEC0                <1> 	inc	al
  4511 0000B16F 48                  <1> 	dec	eax
  4512 0000B170 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  4513 0000B173 E96CEEFFFF          <1> 	jmp	error
  4514                              <1> sysmnt_5:
  4515                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
  4516                              <1> 	; (Following check is needed to prevent mounting an
  4517                              <1> 	; in valid valid file system (in valid super block).
  4518                              <1> 	; 
  4519 0000B178 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  4520 0000B17B C0E002              <1> 	shl	al, 2 ; 4*index
  4521 0000B17E 8B88[9EC90000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  4522 0000B184 C1E103              <1> 	shl 	ecx, 3
  4523 0000B187 0FB715[39EA0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
  4524 0000B18E 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
  4525                              <1> 			 ; (in sectors), if they are not equal
  4526                              <1> 			 ; the disk to be mounted is an...	
  4527 0000B190 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
  4528                              <1> 			 ; (which has not got a valid super block)
  4529                              <1> 	;
  4530 0000B192 C6430100            <1> 	mov	byte [ebx+1], 0
  4531                              <1> 	       	; jsr r0,ppoke / read in entire file system
  4532                              <1> ;sysmnt_6: ;1:
  4533                              <1> 	;;cmp	byte [sb1+1], 0
  4534                              <1> 		; tstb   sb1+1 / done reading?
  4535                              <1>    	;;jna	sysret
  4536                              <1> 	;;call	idle ; (wait for hardware interrupt)
  4537                              <1> 	;;jmp	short sysmnt_6
  4538                              <1> 		;bne 1b / no, wait
  4539                              <1>         	;br sysreta / yes
  4540 0000B196 E969EEFFFF          <1> 	jmp	sysret
  4541                              <1> 
  4542                              <1> sysumount: ; / special dismount file system
  4543                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4544                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4545                              <1> 	;
  4546                              <1> 	; 04/11/2013
  4547                              <1> 	; 09/07/2013
  4548                              <1> 	; 'sysumount' anounces to the system that the special file, 
  4549                              <1> 	; indicated as an argument is no longer contain a removable
  4550                              <1> 	; file system. 'getspl' gets the device number of the special
  4551                              <1> 	; file. If no file system was mounted on that device an error
  4552                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
  4553                              <1> 	; to 'sysret'.
  4554                              <1> 	;
  4555                              <1> 	; Calling sequence:
  4556                              <1> 	;	sysmount; special
  4557                              <1> 	; Arguments:
  4558                              <1> 	;	special - special file to dismount (device)
  4559                              <1> 	;
  4560                              <1> 	; Inputs: - 
  4561                              <1> 	; Outputs: -
  4562                              <1> 	; ...............................................................
  4563                              <1> 	;				
  4564                              <1> 	; Retro UNIX 8086 v1 modification: 
  4565                              <1> 	;       'sysumount' system call has one argument; so,
  4566                              <1> 	;	* Single argument, special is pointed to by BX register
  4567                              <1> 	;
  4568                              <1> 	
  4569                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
  4570                              <1> 	;call	arg
  4571                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
  4572 0000B19B 891D[98DF0000]      <1>         mov	[u.namep], ebx
  4573 0000B1A1 E829000000          <1> 	call	getspl
  4574                              <1> 		; jsr r0,getspl / get the device number in r1
  4575 0000B1A6 3A05[69DF0000]      <1> 	cmp	al, [mdev]
  4576                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  4577 0000B1AC 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  4578                              <1> 	;jne	error
  4579                              <1>         	; bne errora / no error
  4580 0000B1AE 30C0                <1> 	xor	al, al ; ah = 0
  4581                              <1> sysumnt_0: ;1:
  4582 0000B1B0 3805[36EA0000]      <1>      	cmp 	[sb1+1], al ; 0
  4583                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
  4584                              <1> 			   ; / (inhibit bit set)?
  4585 0000B1B6 7607                <1> 	jna	short sysumnt_1		
  4586                              <1> 		; bne 1b / yes, wait
  4587 0000B1B8 E8BD080000          <1> 	call	idle ; (wait for hardware interrupt)
  4588 0000B1BD EBF1                <1> 	jmp	short sysumnt_0
  4589                              <1> sysumnt_1:        
  4590 0000B1BF A2[69DF0000]        <1> 	mov	[mdev], al
  4591                              <1> 	     	; clr mntd / no, clear these
  4592 0000B1C4 66A3[6CDF0000]      <1>    	mov	[mnti], ax
  4593                              <1>         	; clr mnti
  4594 0000B1CA E935EEFFFF          <1>         jmp	sysret
  4595                              <1> 		; br sysreta / return
  4596                              <1> 
  4597                              <1> getspl: ; / get device number from a special file name
  4598 0000B1CF E8AFFAFFFF          <1> 	call	namei
  4599                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4600                              <1> 		       ; ax = 0 -> file not found 	
  4601 0000B1D4 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
  4602                              <1> 	;jz	error
  4603                              <1> 	;jc	error
  4604                              <1> 		; jsr r0,namei / get the i-number of the special file
  4605                              <1>                 ; br errora / no such file
  4606 0000B1DA 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
  4607                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
  4608                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
  4609 0000B1DE 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  4610                              <1> 	;jc	error
  4611                              <1> 		; ble errora / less than 0?  yes, error
  4612 0000B1E0 6683F805            <1>         cmp	ax, 5 ;
  4613                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
  4614 0000B1E4 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
  4615                              <1> 	;ja	error
  4616                              <1>         	; bgt errora / yes, error
  4617                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
  4618                              <1> iopen_retn:
  4619 0000B1E6 C3                  <1> 	retn
  4620                              <1> 		; rts    r0 / return with device number in r1
  4621                              <1> sysmnt_err0:
  4622 0000B1E7 C705[D5DF0000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  4622 0000B1EF 0000                <1>
  4623 0000B1F1 E9EEEDFFFF          <1> 	jmp	error
  4624                              <1> 
  4625                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
  4626                              <1> ; Last Modification: 09/12/2015
  4627                              <1> 
  4628                              <1> syssleep:
  4629                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  4630                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  4631                              <1> 	;
  4632                              <1> 	; Retro UNIX 8086 v1 feature only
  4633                              <1> 	; (INPUT -> none)
  4634                              <1> 	;
  4635 0000B1F6 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4636 0000B1FD 8AA3[D7DC0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  4637 0000B203 E873080000          <1> 	call	sleep
  4638 0000B208 E9F7EDFFFF          <1> 	jmp	sysret
  4639                              <1> 
  4640                              <1> vp_clr:
  4641                              <1> 	; Reset/Clear Video Page
  4642                              <1> 	;
  4643                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  4644                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  4645                              <1> 	;
  4646                              <1> 	; Retro UNIX 8086 v1 feature only !
  4647                              <1> 	;
  4648                              <1> 	; INPUTS -> 
  4649                              <1> 	;   BL = video page number	 
  4650                              <1> 	;
  4651                              <1> 	; OUTPUT ->
  4652                              <1> 	;   none
  4653                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  4654                              <1> 	;
  4655                              <1> 	; 04/12/2013
  4656 0000B20D 28C0                <1> 	sub	al, al
  4657                              <1> 	; al = 0 (clear video page)
  4658                              <1> 	; bl = video page
  4659 0000B20F B407                <1> 	mov	ah, 07h
  4660                              <1> 	; ah = 7 (attribute/color)
  4661 0000B211 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  4662 0000B214 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  4663 0000B218 E8F863FFFF          <1> 	call	_scroll_up
  4664                              <1> 	; bl = video page
  4665 0000B21D 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  4666 0000B220 E92E66FFFF          <1> 	jmp 	_set_cpos
  4667                              <1> 
  4668                              <1> sysmsg:
  4669                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  4670                              <1> 	; 01/07/2015 - 11/11/2015 (Retro UNIX 386 v1)
  4671                              <1> 	; Print user-application message on user's console tty
  4672                              <1> 	;
  4673                              <1> 	; Input -> EBX = Message address
  4674                              <1> 	;	   ECX = Message length (max. 255)
  4675                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  4676                              <1> 	;
  4677 0000B225 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  4678 0000B22B 0F87D3EDFFFF        <1> 	ja	sysret ; nothing to do with big message size
  4679 0000B231 08C9                <1> 	or	cl, cl
  4680 0000B233 0F84CBEDFFFF        <1> 	jz	sysret
  4681 0000B239 20D2                <1> 	and	dl, dl
  4682 0000B23B 7502                <1> 	jnz	short sysmsg0
  4683 0000B23D B207                <1> 	mov	dl, 07h ; default color
  4684                              <1> 		; (black background, light gray character) 
  4685                              <1> sysmsg0:
  4686 0000B23F 891D[A0DF0000]      <1> 	mov	[u.base], ebx
  4687 0000B245 8815[09CF0000]      <1> 	mov	[ccolor], dl ; color attributes
  4688 0000B24B 89E5                <1> 	mov	ebp, esp
  4689 0000B24D 31DB                <1> 	xor	ebx, ebx ; 0
  4690 0000B24F 891D[A8DF0000]      <1> 	mov	[u.nread], ebx ; 0
  4691                              <1> 	;
  4692 0000B255 381D[E7DF0000]      <1> 	cmp	[u.kcall], bl ; 0
  4693 0000B25B 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  4694                              <1> 	;
  4695 0000B25D 890D[A4DF0000]      <1> 	mov	[u.count], ecx
  4696 0000B263 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ
  4697 0000B264 29CC                <1> 	sub	esp, ecx
  4698 0000B266 89E7                <1> 	mov	edi, esp
  4699 0000B268 89E6                <1> 	mov	esi, esp
  4700 0000B26A 66891D[E5DF0000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  4701                              <1> 	; 11/11/2015
  4702 0000B271 8A25[B0DF0000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  4703                              <1> 	; 0 = none
  4704 0000B277 FECC                <1> 	dec	ah
  4705 0000B279 790C                <1> 	jns	short sysmsg1 
  4706 0000B27B 8A1D[CFDF0000]      <1> 	mov	bl, [u.uno] ; process number	
  4707 0000B281 8AA3[D7DC0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  4708                              <1> sysmsg1:
  4709 0000B287 8825[D4DF0000]      <1> 	mov	[u.ttyn], ah
  4710                              <1> sysmsg2:
  4711 0000B28D E875070000          <1> 	call	cpass
  4712 0000B292 7416                <1> 	jz	short sysmsg5
  4713 0000B294 AA                  <1> 	stosb
  4714 0000B295 20C0                <1> 	and	al, al
  4715 0000B297 75F4                <1> 	jnz	short sysmsg2
  4716                              <1> sysmsg3:
  4717 0000B299 80FC07              <1> 	cmp	ah, 7 ; tty number
  4718 0000B29C 7711                <1> 	ja	short sysmsg6 ; serial port
  4719 0000B29E E83E000000          <1> 	call	print_cmsg
  4720                              <1> sysmsg4:
  4721 0000B2A3 89EC                <1> 	mov	esp, ebp	
  4722 0000B2A5 E95AEDFFFF          <1> 	jmp	sysret
  4723                              <1> sysmsg5:
  4724 0000B2AA C60700              <1> 	mov	byte [edi], 0
  4725 0000B2AD EBEA                <1> 	jmp	short sysmsg3
  4726                              <1> sysmsg6:
  4727 0000B2AF 8A06                <1> 	mov	al, [esi]
  4728 0000B2B1 E8BD070000          <1> 	call	sndc
  4729 0000B2B6 72EB                <1> 	jc	short sysmsg4
  4730 0000B2B8 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  4731 0000B2BB 76E6                <1> 	jna	short sysmsg4
  4732 0000B2BD 46                  <1> 	inc 	esi
  4733 0000B2BE 8A25[D4DF0000]      <1> 	mov	ah, [u.ttyn]
  4734 0000B2C4 EBE9                <1> 	jmp	short sysmsg6
  4735                              <1> 
  4736                              <1> sysmsgk: ; Temporary (01/07/2015)
  4737                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  4738                              <1> 	; (ECX -character count- will not be considered)
  4739 0000B2C6 8B35[A0DF0000]      <1> 	mov	esi, [u.base]
  4740 0000B2CC 8A25[08CF0000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  4741 0000B2D2 8825[D4DF0000]      <1> 	mov	[u.ttyn], ah
  4742 0000B2D8 C605[E7DF0000]00    <1> 	mov	byte [u.kcall], 0
  4743 0000B2DF EBB8                <1> 	jmp	short sysmsg3
  4744                              <1> 	
  4745                              <1> print_cmsg: 
  4746                              <1> 	; 01/07/2015 (Retro UNIX 386 v1 feature only !)
  4747                              <1> 	;
  4748                              <1> 	; print message (on user's console tty) 
  4749                              <1> 	;	with requested color
  4750                              <1> 	;
  4751                              <1> 	; INPUTS:
  4752                              <1> 	;	esi = message address
  4753                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  4754                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  4755                              <1> 	;
  4756 0000B2E1 AC                  <1> 	lodsb
  4757                              <1> pcmsg1:
  4758 0000B2E2 56                  <1> 	push 	esi
  4759 0000B2E3 0FB61D[D4DF0000]    <1>         movzx   ebx, byte [u.ttyn]
  4760 0000B2EA 8A25[09CF0000]      <1> 	mov	ah, [ccolor]
  4761 0000B2F0 E8CA64FFFF          <1> 	call 	WRITE_TTY
  4762 0000B2F5 5E                  <1> 	pop	esi
  4763 0000B2F6 AC                  <1> 	lodsb
  4764 0000B2F7 20C0                <1> 	and 	al, al  ; 0
  4765 0000B2F9 75E7                <1> 	jnz 	short pcmsg1
  4766 0000B2FB C3                  <1> 	retn
  4767                              <1> 
  4768                              <1> sysgeterr:
  4769                              <1> 	; 09/12/2015
  4770                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  4771                              <1> 	; Get last error number or page fault count
  4772                              <1> 	; (for debugging)
  4773                              <1> 	;
  4774                              <1> 	; Input -> EBX = return type
  4775                              <1> 	;	   0 = last error code (which is in 'u.error')	
  4776                              <1> 	;	   FFFFFFFFh = page fault count for running process
  4777                              <1> 	;	   FFFFFFFEh = total page fault count
  4778                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  4779                              <1> 	;
  4780                              <1> 	; Output -> EAX = last error number or page fault count
  4781                              <1> 	;	   (depending on EBX input)
  4782                              <1> 	; 	
  4783 0000B2FC 21DB                <1> 	and 	ebx, ebx
  4784 0000B2FE 750B                <1> 	jnz	short glerr_2
  4785                              <1> glerr_0:
  4786 0000B300 A1[D5DF0000]        <1> 	mov	eax, [u.error]
  4787                              <1> glerr_1:
  4788 0000B305 A3[80DF0000]        <1> 	mov	[u.r0], eax
  4789 0000B30A C3                  <1>  	retn
  4790                              <1> glerr_2:
  4791 0000B30B 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  4792 0000B30C 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  4793 0000B30E 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  4794 0000B30F 75EF                <1> 	jnz	short glerr_0
  4795 0000B311 A1[5CEC0000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  4796 0000B316 EBED                <1>         jmp     short glerr_1
  4797                              <1> glerr_3:
  4798 0000B318 A1[E9DF0000]        <1> 	mov 	eax, [u.pfcount]
  4799 0000B31D EBE6                <1> 	jmp	short glerr_1
  4800                              <1> 
  4801                              <1> load_and_run_file:
  4802                              <1> 	; 06/05/2016
  4803                              <1> 	; 03/05/2016
  4804                              <1> 	; 02/05/2016
  4805                              <1> 	; 24/04/2016
  4806                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  4807                              <1> 	; 23/10/2015 (Retro UNIX 386 v1, 'sysexec')
  4808                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4809                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  4810                              <1> 	; EAX = First Cluster number
  4811                              <1> 	; EDX = File Size
  4812                              <1> 	; ESI = Argument list address
  4813                              <1> 	; [argc] = argument count
  4814                              <1> 	; [u.nread] = argument list length
  4815                              <1> 	; [esp] = return address to the caller (*)
  4816                              <1> 	;
  4817 0000B31F 8935[00E00000]      <1> 	mov	[argv], esi
  4818 0000B325 8915[09E00000]      <1> 	mov	[i.size], edx
  4819 0000B32B A3[05E00000]        <1> 	mov	[ii], eax
  4820                              <1> 
  4821                              <1> 	; 06/05/2016
  4822                              <1> 	; Set 'sysexit' return order to MainProg
  4823                              <1> 	;
  4824 0000B330 58                  <1> 	pop	eax ; * 'loc_load_and_run_file_8:' address
  4825 0000B331 8B25[74CE0000]      <1> 	mov	esp, [tss.esp0]
  4826                              <1> 	;
  4827                              <1> 	; 'loc_load_run_file_8' address has 
  4828                              <1> 	; 'jmp loc_file_rw_restore_retn' instruction
  4829                              <1> 	; 'loc_file_rw_restore_retn:' will return to
  4830                              <1> 	; [mainprog_return_addr] 
  4831                              <1> 	; just after 'call command_interpreter'
  4832                              <1> 	;
  4833 0000B337 68[FD3E0000]        <1> 	push	_end_of_mainprog ; we must not return to here !
  4834 0000B33C FF35[50DC0000]      <1> 	push	dword [mainprog_return_addr]
  4835 0000B342 89E5                <1> 	mov	ebp, esp ; **
  4836                              <1> 	;	
  4837 0000B344 9C                  <1> 	pushfd  ; EFLAGS      ; IRETD
  4838 0000B345 6A08                <1> 	push	KCODE ; cs    ; IRETD
  4839 0000B347 50                  <1> 	push	eax ; * (eip) ; IRETD
  4840 0000B348 8925[78DF0000]      <1> 	mov	[u.sp], esp
  4841 0000B34E 1E                  <1> 	push	ds
  4842 0000B34F 06                  <1> 	push	es
  4843 0000B350 0FA0                <1> 	push	fs
  4844 0000B352 0FA8                <1> 	push	gs	
  4845 0000B354 60                  <1> 	pushad
  4846 0000B355 68[04A00000]        <1> 	push	sysret
  4847 0000B35A 8925[7CDF0000]      <1> 	mov	[u.usp], esp
  4848                              <1> 	;
  4849 0000B360 E818060000          <1> 	call	wswap ; Save MainProg (process 1) 'u' structure
  4850                              <1> 		      ; and registers for return (from program)	
  4851 0000B365 89EC                <1> 	mov	esp, ebp ; **
  4852 0000B367 50                  <1> 	push	eax  ; * 'loc_load_and_run_file_8:' address
  4853                              <1> 	;
  4854                              <1> 	;;; 02/05/2016
  4855                              <1> 	;;; Create a new process (parent: MainProg)	
  4856 0000B368 31F6                <1> 	xor 	esi, esi
  4857                              <1> cnpm_1: ; search p.stat table for unused process number
  4858 0000B36A 46                  <1> 	inc	esi
  4859 0000B36B 80BE[07DD0000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE
  4860                              <1> 				; is process active, unused, dead
  4861 0000B372 760B                <1> 	jna	short cnpm_2	; it's unused so branch
  4862 0000B374 6683FE10            <1> 	cmp	si, nproc 	; all processes checked
  4863 0000B378 72F0                <1> 	jb	short cnpm_1    ; no, branch back
  4864 0000B37A E9F38BFFFF          <1> 	jmp	panic 
  4865                              <1> cnpm_2:
  4866 0000B37F A1[D9DF0000]        <1> 	mov	eax, [u.pgdir] ; page directory of MainProg
  4867 0000B384 A3[DDDF0000]        <1> 	mov	[u.ppgdir], eax ; parent's page directory
  4868 0000B389 E8817DFFFF          <1> 	call	allocate_page
  4869 0000B38E 0F82DE8BFFFF        <1> 	jc	panic
  4870                              <1> 	; EAX = UPAGE (user structure page) address
  4871 0000B394 A3[D0DF0000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  4872 0000B399 89F7                <1> 	mov	edi, esi
  4873 0000B39B 66C1E702            <1> 	shl	di, 2
  4874 0000B39F 8987[14DD0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  4875 0000B3A5 E8DF7DFFFF          <1> 	call	clear_page ; 03/05/2016
  4876                              <1> 	;movzx	eax, byte [p.ttyc] ; console tty (for MainProg)
  4877 0000B3AA 6629C0              <1> 	sub	ax, ax ; 0
  4878 0000B3AD 668986[D7DC0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  4879                              <1> 				   ; ah - reset child's wait channel	
  4880 0000B3B4 89F0                <1> 	mov	eax, esi
  4881 0000B3B6 A2[CFDF0000]        <1> 	mov	[u.uno], al ; child process number
  4882 0000B3BB FE86[07DD0000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN
  4883 0000B3C1 66D1E6              <1> 	shl	si, 1 ; multiply si by 2 to get index into p.pid table
  4884 0000B3C4 66FF05[6EDF0000]    <1> 	inc	word [mpid] ; increment m.pid; get a new process name
  4885 0000B3CB 66A1[6EDF0000]      <1> 	mov	ax, [mpid]
  4886 0000B3D1 668986[76DC0000]    <1> 	mov	[esi+p.pid-2], ax ; put new process name 
  4887                              <1> 				  ; in child process' name slot
  4888                              <1> 	;mov	ax, [p.pid]  ; get process name of MainProg
  4889 0000B3D8 66B80100            <1> 	mov	ax, 1
  4890 0000B3DC 668986[96DC0000]    <1> 	mov	[esi+p.ppid-2], ax ; put parent process name 
  4891                              <1> 			           ; in parent process slot for child
  4892 0000B3E3 6648                <1> 	dec	ax ; 0
  4893 0000B3E5 66A3[B0DF0000]      <1> 	mov 	[u.ttyp], ax ; 0
  4894                              <1> 	;;;
  4895 0000B3EB A1[05E00000]        <1> 	mov 	eax,  [ii]
  4896                              <1> 	; Retro UNIX 386 v1, 'sysexec' (u2.s)
  4897 0000B3F0 E877060000          <1> 	call	iopen
  4898 0000B3F5 EB0A                <1> 	jmp	short sysexec_7 ; 02/05/2016
  4899                              <1> 
  4900                              <1> sysexec_6:
  4901                              <1> 	;;02/05/2016
  4902                              <1> 	; 23/04/2016
  4903                              <1> 	; 18/10/2015 ('sysexec_6')
  4904                              <1> 	; 23/06/2015
  4905                              <1> 	;;mov	eax, [u.pgdir] ; parent's page directory
  4906                              <1> 	;;cmp 	eax, [k_page_dir] ; TRDOS MainProg ? 
  4907                              <1> 	;;je	short sysexec_7
  4908 0000B3F7 A1[D9DF0000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  4909 0000B3FC E8477EFFFF          <1> 	call	deallocate_page_dir
  4910                              <1> sysexec_7:
  4911 0000B401 E8777DFFFF          <1> 	call	make_page_dir
  4912 0000B406 0F82668BFFFF        <1> 	jc	panic  ; allocation error 
  4913                              <1> 		       ; after a deallocation would be nonsence !?
  4914                              <1> 	; 24/07/2015
  4915                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  4916                              <1> 	;     of the user's page directory
  4917                              <1> 	;     (It is needed for interrupts!)
  4918                              <1> 	; 18/10/2015
  4919 0000B40C 8B15[D8CE0000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  4920 0000B412 8B02                <1> 	mov	eax, [edx] ; physical address of
  4921                              <1> 			   ; kernel's first page table (1st 4 MB)
  4922                              <1> 			   ; (PDE 0 of kernel's page directory)
  4923 0000B414 8B15[D9DF0000]      <1> 	mov 	edx, [u.pgdir]
  4924 0000B41A 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  4925                              <1> 	;
  4926                              <1> 	; 20/07/2015
  4927 0000B41C BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  4928                              <1> 	; 18/10/2015
  4929 0000B421 BE[F0DF0000]        <1> 	mov	esi, pcore ; physical start address
  4930                              <1> sysexec_8:	
  4931 0000B426 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  4932 0000B42B E86B7DFFFF          <1> 	call	make_page_table
  4933 0000B430 0F823C8BFFFF        <1> 	jc	panic
  4934                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  4935 0000B436 E86E7DFFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  4936 0000B43B 0F82318BFFFF        <1> 	jc	panic
  4937                              <1> 	;
  4938 0000B441 8906                <1> 	mov	[esi], eax ; 24/06/2015
  4939                              <1> 	; ebx = virtual address (24/07/2015)
  4940 0000B443 E88482FFFF          <1> 	call 	add_to_swap_queue
  4941                              <1> 	; 18/10/2015
  4942 0000B448 81FE[F4DF0000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  4943 0000B44E 740C                <1> 	je	short sysexec_9 ; yes
  4944 0000B450 BE[F4DF0000]        <1> 	mov	esi, ecore  ; physical address of the last page 
  4945                              <1> 	; 20/07/2015
  4946 0000B455 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  4947                              <1> 	; ebx = virtual end address + segment base address - 4K
  4948 0000B45A EBCA                <1>         jmp     short sysexec_8
  4949                              <1> sysexec_9:
  4950                              <1> 	; 24/04/2016
  4951                              <1> 	; 18/10/2015
  4952                              <1> 	; 26/08/2015
  4953                              <1> 	; 25/06/2015
  4954                              <1> 	; move arguments from kernel stack to [ecore]
  4955                              <1> 	; (argument list/line will be copied from kernel stack
  4956                              <1> 	; frame to the last (stack) page of user's core memory)
  4957                              <1> 	; 18/10/2015
  4958 0000B45C 8B3D[F4DF0000]      <1> 	mov	edi, [ecore]
  4959 0000B462 81C700100000        <1> 	add	edi, PAGE_SIZE
  4960 0000B468 0FB705[FEDF0000]    <1> 	movzx	eax, word [argc]
  4961 0000B46F 09C0                <1> 	or	eax, eax
  4962 0000B471 7509                <1> 	jnz	short sysexec_10
  4963 0000B473 89FB                <1> 	mov 	ebx, edi
  4964 0000B475 83EB04              <1> 	sub	ebx, 4 
  4965 0000B478 8903                <1> 	mov	[ebx], eax ; 0
  4966 0000B47A EB44                <1> 	jmp 	short sysexec_13
  4967                              <1> sysexec_10:
  4968 0000B47C 8B0D[A8DF0000]      <1> 	mov	ecx, [u.nread]
  4969                              <1> 	;mov	esi, TextBuffer
  4970 0000B482 8B35[00E00000]      <1> 	mov	esi, [argv] ; 24/04/2016 (TRDOS 386  = TRDOS v2.0)
  4971 0000B488 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  4972 0000B48A 89C2                <1> 	mov	edx, eax
  4973 0000B48C FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  4974 0000B48E C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  4975 0000B491 89FB                <1> 	mov	ebx, edi
  4976 0000B493 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  4977 0000B496 29D3                <1> 	sub 	ebx, edx
  4978 0000B498 89FA                <1> 	mov	edx, edi
  4979 0000B49A F3A4                <1> 	rep	movsb
  4980 0000B49C 89D6                <1> 	mov 	esi, edx
  4981 0000B49E 89DF                <1> 	mov 	edi, ebx
  4982 0000B4A0 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  4983 0000B4A5 2B15[F4DF0000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  4984 0000B4AB AB                  <1> 	stosd	; eax = argument count	
  4985                              <1> sysexec_11:
  4986 0000B4AC 89F0                <1> 	mov	eax, esi
  4987 0000B4AE 01D0                <1> 	add	eax, edx
  4988 0000B4B0 AB                  <1> 	stosd  ; eax = virtual address
  4989 0000B4B1 FE0D[FEDF0000]      <1> 	dec	byte [argc]
  4990 0000B4B7 7407                <1> 	jz	short sysexec_13
  4991                              <1> sysexec_12:
  4992 0000B4B9 AC                  <1> 	lodsb
  4993 0000B4BA 20C0                <1> 	and	al, al
  4994 0000B4BC 75FB                <1> 	jnz	short sysexec_12
  4995 0000B4BE EBEC                <1> 	jmp	short sysexec_11
  4996                              <1> sysexec_13:
  4997                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  4998                              <1> 	; 23/06/2015 - 19/10/2015 (Retro UNIX 386 v1, 'sysexec_13')
  4999                              <1> 	;
  5000                              <1> 	; moving arguments to [ecore] is OK here..
  5001                              <1> 	;
  5002                              <1> 	; ebx = beginning addres of argument list pointers
  5003                              <1> 		;	in user's stack
  5004 0000B4C0 2B1D[F4DF0000]      <1> 	sub 	ebx, [ecore]
  5005 0000B4C6 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  5006                              <1> 			; end of core - 4096 (last page)
  5007                              <1> 			; (virtual address)
  5008 0000B4CC 891D[00E00000]      <1> 	mov	[argv], ebx
  5009 0000B4D2 891D[ACDF0000]      <1> 	mov	[u.break], ebx ; available user memory
  5010                              <1> 	;
  5011 0000B4D8 29C0                <1> 	sub	eax, eax
  5012 0000B4DA C705[A4DF0000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  5012 0000B4E2 0000                <1>
  5013 0000B4E4 C705[90DF0000]-     <1> 	mov	dword [u.fofp], u.off
  5013 0000B4EA [9CDF0000]          <1>
  5014 0000B4EE A3[9CDF0000]        <1> 	mov	[u.off], eax ; 0
  5015 0000B4F3 A3[A0DF0000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  5016 0000B4F8 A1[05E00000]        <1> 	mov	eax, [ii] ; Fist Cluster of the Program (PRG) file
  5017                              <1> 	; EAX = First cluster of the executable file
  5018 0000B4FD E831010000          <1> 	call	readi
  5019                              <1> 
  5020 0000B502 8B0D[ACDF0000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  5021 0000B508 890D[A4DF0000]      <1> 	mov	[u.count], ecx ; save for overrun check
  5022                              <1> 	;
  5023 0000B50E 8B0D[A8DF0000]      <1> 	mov	ecx, [u.nread]
  5024 0000B514 890D[ACDF0000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  5025 0000B51A 80F920              <1> 	cmp	cl, 32
  5026 0000B51D 7540                <1>         jne     short sysexec_15
  5027                              <1> 	;:
  5028                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  5029 0000B51F 8B35[F0DF0000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  5030                              <1> 		             ; (phys. start addr. of the exec. file)
  5031 0000B525 AD                  <1> 	lodsd
  5032 0000B526 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  5033 0000B52A 7533                <1> 	jne	short sysexec_15
  5034 0000B52C AD                  <1> 	lodsd
  5035 0000B52D 89C1                <1> 	mov	ecx, eax ; text (code) section size
  5036 0000B52F AD                  <1> 	lodsd
  5037 0000B530 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  5038 0000B532 89CB                <1> 	mov	ebx, ecx
  5039 0000B534 AD                  <1> 	lodsd	
  5040 0000B535 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  5041 0000B537 3B1D[A4DF0000]      <1> 	cmp	ebx, [u.count]
  5042 0000B53D 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  5043                              <1> 	;
  5044                              <1> 	; add bss section size to [u.break]
  5045 0000B53F 0105[ACDF0000]      <1> 	add 	[u.break], eax
  5046                              <1> 	;
  5047 0000B545 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  5048                              <1> 	;cmp	ecx, [u.count]
  5049                              <1> 	;jnb	short sysexec_16
  5050 0000B548 890D[A4DF0000]      <1> 	mov	[u.count], ecx ; required read count
  5051 0000B54E EB29                <1> 	jmp	short sysexec_16
  5052                              <1> sysexec_14:
  5053                              <1> 	; insufficient (out of) memory
  5054 0000B550 C705[D5DF0000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  5054 0000B558 0000                <1>
  5055 0000B55A E985EAFFFF          <1> 	jmp	error
  5056                              <1> sysexec_15:
  5057 0000B55F 8B15[09E00000]      <1>         mov	edx, [i.size] ; file size
  5058 0000B565 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  5059 0000B567 7626                <1> 	jna	short sysexec_17 ; no need to next read
  5060 0000B569 01D1                <1> 	add	ecx, edx ; [i.size]
  5061 0000B56B 3B0D[A4DF0000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  5062 0000B571 77DD                <1> 	ja	short sysexec_14
  5063 0000B573 8915[A4DF0000]      <1> 	mov	[u.count], edx
  5064                              <1> sysexec_16:
  5065 0000B579 A1[05E00000]        <1> 	mov	eax, [ii] ; first cluster
  5066 0000B57E E8B0000000          <1> 	call	readi
  5067 0000B583 8B0D[A8DF0000]      <1> 	mov	ecx, [u.nread]
  5068 0000B589 010D[ACDF0000]      <1> 	add	[u.break], ecx
  5069                              <1> sysexec_17:
  5070 0000B58F A1[05E00000]        <1> 	mov	eax, [ii] ; first cluster
  5071 0000B594 E8D4040000          <1> 	call	iclose
  5072 0000B599 31C0                <1> 	xor     eax, eax
  5073 0000B59B FEC0                <1> 	inc	al
  5074 0000B59D 66A3[C4DF0000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  5075 0000B5A3 66A3[C6DF0000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  5076 0000B5A9 833D[DDDF0000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller MainProg (kernel) ?
  5077 0000B5B0 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  5078                              <1> 	; If the caller is kernel (MainProg), 'sysexec' will come here
  5079 0000B5B2 8B15[D8CE0000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  5080 0000B5B8 8915[DDDF0000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
  5081                              <1> sysexec_18:
  5082                              <1> 	; 02/05/2016
  5083                              <1> 	; 24/04/2016 (TRDOS 386 = TRDOS v2.0)
  5084                              <1> 	; 18/10/2015 (Retro UNIX 386 v1)
  5085                              <1> 	; 05/08/2015
  5086                              <1> 	; 29/07/2015
  5087 0000B5BE 8B2D[00E00000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  5088                              <1> 			    ; list pointers (argument count)
  5089 0000B5C4 FA                  <1> 	cli
  5090 0000B5C5 8B25[74CE0000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
  5091                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  5092                              <1> 			    ; for this process	 
  5093                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  5094                              <1> 	;xor	eax, eax ; 0
  5095 0000B5CB FEC8                <1> 	dec	al ; eax = 0
  5096 0000B5CD 66BA2300            <1> 	mov	dx, UDATA
  5097 0000B5D1 6652                <1> 	push	dx  ; user's stack segment
  5098 0000B5D3 55                  <1> 	push	ebp ; user's stack pointer
  5099                              <1> 		    ; (points to number of arguments)
  5100 0000B5D4 FB                  <1> 	sti
  5101 0000B5D5 9C                  <1> 	pushfd	; EFLAGS
  5102                              <1> 		; Set IF for enabling interrupts in user mode	
  5103                              <1> 	;or	dword [esp], 200h 
  5104                              <1> 	;
  5105                              <1> 	;mov	bx, UCODE
  5106                              <1> 	;push	bx ; user's code segment
  5107 0000B5D6 6A1B                <1> 	push	UCODE
  5108                              <1> 	;push	0
  5109 0000B5D8 50                  <1> 	push	eax ; EIP (=0) - start address -	
  5110 0000B5D9 8925[78DF0000]      <1> 	mov	[u.sp], esp ; 29/07/2015
  5111                              <1> 	; 05/08/2015
  5112                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  5113                              <1> 	; ('push dx' would cause to general protection fault, 
  5114                              <1> 	; after 'pop ds' etc.)
  5115                              <1> 	;
  5116                              <1> 	;; push dx ; ds (UDATA)
  5117                              <1> 	;; push dx ; es (UDATA)
  5118                              <1> 	;; push dx ; fs (UDATA)
  5119                              <1> 	;; push dx ; gs (UDATA)
  5120                              <1> 	;
  5121                              <1> 	; This is a trick to prevent general protection fault
  5122                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  5123 0000B5DF 8EC2                <1> 	mov 	es, dx ; UDATA
  5124 0000B5E1 06                  <1> 	push 	es ; ds (UDATA)
  5125 0000B5E2 06                  <1> 	push 	es ; es (UDATA)
  5126 0000B5E3 06                  <1> 	push 	es ; fs (UDATA)
  5127 0000B5E4 06                  <1> 	push	es ; gs (UDATA)
  5128 0000B5E5 66BA1000            <1> 	mov	dx, KDATA
  5129 0000B5E9 8EC2                <1> 	mov	es, dx
  5130                              <1> 	;
  5131                              <1> 	;; pushad simulation
  5132 0000B5EB 89E5                <1> 	mov	ebp, esp ; esp before pushad
  5133 0000B5ED 50                  <1> 	push	eax ; eax (0)
  5134 0000B5EE 50                  <1> 	push	eax ; ecx (0)
  5135 0000B5EF 50                  <1> 	push	eax ; edx (0)
  5136 0000B5F0 50                  <1> 	push	eax ; ebx (0)
  5137 0000B5F1 55                  <1> 	push	ebp ; esp before pushad
  5138 0000B5F2 50                  <1> 	push	eax ; ebp (0)
  5139 0000B5F3 50                  <1> 	push	eax ; esi (0)		
  5140 0000B5F4 50                  <1> 	push	eax ; edi (0)	
  5141                              <1> 	;
  5142 0000B5F5 A3[80DF0000]        <1> 	mov	[u.r0], eax ; eax = 0
  5143 0000B5FA 8925[7CDF0000]      <1> 	mov	[u.usp], esp
  5144                              <1> 
  5145                              <1> 	; 02/05/2016
  5146 0000B600 FE05[77DF0000]      <1> 	inc	byte [sysflg] ; 0FFh -> 0
  5147 0000B606 0FB61D[CFDF0000]    <1> 	movzx	ebx, byte [u.uno]	
  5148 0000B60D 6683BB[96DC0000]01  <1> 	cmp	word [ebx+p.ppid-2], 1 ; MainProg
  5149 0000B615 0F87ECE9FFFF        <1> 	ja	sysret0 ; 03/05/2016
  5150 0000B61B 68[04A00000]        <1> 	push	sysret ; * 
  5151 0000B620 8925[7CDF0000]      <1> 	mov	[u.usp], esp
  5152 0000B626 E852030000          <1> 	call	wswap ; save child process 'u' structure and
  5153                              <1> 		      ; registers
  5154 0000B62B 8305[7CDF0000]04    <1> 	add	dword [u.usp], 4 ; 03/05/2016 
  5155                              <1> sysexec_19: ; 02/05/2016
  5156 0000B632 C3                  <1> 	retn ; * 'sysret' ; byte [sysflg] -> 0FFh
  5157                              <1> 
  5158                              <1> readi:
  5159                              <1> 	; 01/05/2016
  5160                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5161                              <1> 	; 20/05/2015 - Retro UNIX 386 v1
  5162                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5163                              <1> 	;
  5164                              <1> 	; Reads from a file whose the first cluster number in EAX
  5165                              <1> 	; 
  5166                              <1> 	; INPUTS ->
  5167                              <1> 	;    EAX - First cluster number of the file
  5168                              <1> 	;    u.count - byte count user desires
  5169                              <1> 	;    u.base - points to user buffer
  5170                              <1> 	;    u.fofp - points to dword with current file offset
  5171                              <1> 	;    i.size - file size
  5172                              <1> 	; OUTPUTS ->
  5173                              <1> 	;    u.count - cleared
  5174                              <1> 	;    u.nread - accumulates total bytes passed back
  5175                              <1> 	;
  5176                              <1> 	; ((EAX)) input/output
  5177                              <1> 	; (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
  5178                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
  5179                              <1> 
  5180 0000B633 31D2                <1> 	xor	edx, edx ; 0
  5181 0000B635 8915[A8DF0000]      <1> 	mov 	[u.nread], edx ; 0
  5182 0000B63B 668915[E5DF0000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  5183 0000B642 3915[A4DF0000]      <1> 	cmp 	[u.count], edx ; 0
  5184 0000B648 7701                <1> 	ja 	short readi_1
  5185 0000B64A C3                  <1> 	retn
  5186                              <1> readi_1:
  5187                              <1> dskr:
  5188                              <1> 	; 01/05/2016
  5189                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5190                              <1> 	; 24/05/2015 - 12/10/2015 (Retro UNIX 386 v1)
  5191                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  5192                              <1> dskr_0:
  5193 0000B64B 8B15[09E00000]      <1>         mov	edx, [i.size]
  5194 0000B651 8B1D[90DF0000]      <1> 	mov	ebx, [u.fofp]
  5195 0000B657 2B13                <1> 	sub	edx, [ebx]
  5196 0000B659 7647                <1> 	jna	short dskr_4
  5197                              <1> 	;
  5198 0000B65B 50                  <1> 	push	eax ; 01/05/2016
  5199 0000B65C 3B15[A4DF0000]      <1> 	cmp     edx, [u.count] 
  5200 0000B662 7306                <1> 	jnb	short dskr_1
  5201 0000B664 8915[A4DF0000]      <1> 	mov	[u.count], edx
  5202                              <1> dskr_1:
  5203                              <1> 	; EAX = First Cluster
  5204                              <1> 	; [Current_Drv] = Physical drive number 
  5205 0000B66A E83B000000          <1> 	call	mget_r
  5206                              <1> 	; NOTE: in 'mget_r', relevant sector will be read in buffer
  5207                              <1> 	; if it not already in buffer !
  5208 0000B66F BB[15E00000]        <1> 	mov	ebx, readi_buffer
  5209 0000B674 803D[E7DF0000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  5210 0000B67B 770F                <1> 	ja	short dskr_3	  ; zf=0 -> the caller is 'namei'
  5211 0000B67D 66833D[E5DF0000]00  <1> 	cmp	word [u.pcount], 0
  5212 0000B685 7705                <1> 	ja	short dskr_3
  5213                              <1> dskr_2:
  5214                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  5215 0000B687 E89A010000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  5216                              <1> dskr_3:
  5217                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
  5218 0000B68C E8F3010000          <1> 	call	sioreg
  5219 0000B691 87F7                <1> 	xchg	esi, edi
  5220                              <1> 	; EDI = file (user data) offset
  5221                              <1> 	; ESI = sector (I/O) buffer offset
  5222                              <1> 	; ECX = byte count
  5223 0000B693 F3A4                <1> 	rep	movsb
  5224                              <1> 	; eax = remain bytes in buffer
  5225                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  5226 0000B695 09C0                <1> 	or	eax, eax
  5227 0000B697 75EE                <1> 	jnz	short dskr_2 ; (page end before system buffer end!)		
  5228 0000B699 58                  <1> 	pop	eax  ; (first cluster number)
  5229 0000B69A 390D[A4DF0000]      <1> 	cmp	[u.count], ecx ; 0
  5230 0000B6A0 77A9                <1> 	ja	short dskr_0
  5231                              <1> dskr_4:
  5232 0000B6A2 C605[E7DF0000]00    <1> 	mov	byte [u.kcall], 0
  5233 0000B6A9 C3                  <1> 	retn
  5234                              <1> 
  5235                              <1> mget_r:
  5236                              <1> 	; 29/04/2016
  5237                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5238                              <1> 	; 03/06/2015 (Retro UNIX 386 v1, 'mget', u.5s)
  5239                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5240                              <1> 	;
  5241                              <1> 	; Get existing or (allocate) a new disk block for file
  5242                              <1> 	; 
  5243                              <1> 	; INPUTS ->
  5244                              <1> 	;    u.fofp = file offset pointer
  5245                              <1> 	;    EAX = First Cluster
  5246                              <1> 	;    (u.off = file offset)
  5247                              <1> 	; OUTPUTS ->
  5248                              <1> 	;    EAX = logical sector number
  5249                              <1> 	;    ESI = Logical Dos Drive Description Table address	
  5250                              <1> 	;
  5251                              <1> 	; Modified registers: EDX, EBX, ECX, ESI, EDI, EBP  
  5252                              <1> 
  5253 0000B6AA 8B35[90DF0000]      <1> 	mov     esi, [u.fofp]
  5254 0000B6B0 8B1E                <1> 	mov	ebx, [esi] ; u.off
  5255                              <1> 
  5256 0000B6B2 29C9                <1> 	sub	ecx, ecx
  5257 0000B6B4 8A2D[A2CF0000]      <1> 	mov	ch, [Current_Drv]
  5258                              <1> 
  5259 0000B6BA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5260 0000B6BF 01CE                <1> 	add	esi, ecx
  5261                              <1> 
  5262 0000B6C1 380D[10DC0000]      <1> 	cmp	[readi.valid], cl ; 0
  5263 0000B6C7 764B                <1> 	jna	short mget_r_0
  5264                              <1> 	
  5265 0000B6C9 3A2D[11DC0000]      <1> 	cmp	ch, [readi.drv]
  5266 0000B6CF 7543                <1> 	jne	short mget_r_0
  5267                              <1> 
  5268 0000B6D1 3B05[24DC0000]      <1> 	cmp	eax, [readi.fclust]
  5269 0000B6D7 7567                <1> 	jne	short mget_r_3
  5270                              <1> 	
  5271 0000B6D9 668B0D[18DC0000]    <1> 	mov	cx, [readi.bpc]
  5272 0000B6E0 41                  <1> 	inc	ecx ; <= 65536
  5273 0000B6E1 29D2                <1> 	sub	edx, edx
  5274 0000B6E3 F7F1                <1> 	div	ecx
  5275                              <1> 
  5276 0000B6E5 8B3D[20DC0000]      <1> 	mov	edi, [readi.c_index] ; cluster index
  5277                              <1> 
  5278 0000B6EB 39F8                <1> 	cmp	eax, edi
  5279 0000B6ED 0F858B000000        <1>         jne     mget_r_5  ; (*)
  5280                              <1> 
  5281                              <1> 	; edx = byte offset in cluster (<= 65535)
  5282 0000B6F3 668915[1ADC0000]    <1> 	mov	[readi.offset], dx
  5283 0000B6FA 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5284 0000B6FE 8815[13DC0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5285                              <1> 	
  5286 0000B704 A1[1CDC0000]        <1> 	mov	eax, [readi.cluster]
  5287 0000B709 8B15[28DC0000]      <1> 	mov	edx, [readi.fs_index]
  5288 0000B70F E9AF000000          <1>         jmp     mget_r_8
  5289                              <1> 	
  5290                              <1> mget_r_0:
  5291 0000B714 882D[11DC0000]      <1> 	mov	[readi.drv], ch ; physical drive number
  5292 0000B71A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5293 0000B71E 7707                <1> 	ja	short  mget_r_1
  5294 0000B720 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  5295 0000B723 D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  5296 0000B725 EB03                <1> 	jmp	short mget_r_2	
  5297                              <1> mget_r_1:
  5298 0000B727 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]
  5299                              <1> mget_r_2:
  5300 0000B72A 880D[12DC0000]      <1> 	mov	[readi.spc], cl  ; sectors per cluster
  5301                              <1> 	; NOTE: readi bytes per sector value is always 512 ! 
  5302 0000B730 66C1E109            <1> 	shl	cx, 9 ; * 512
  5303 0000B734 6649                <1> 	dec	cx ; bytes per cluster - 1
  5304 0000B736 66890D[18DC0000]    <1> 	mov	[readi.bpc], cx
  5305 0000B73D 6629C9              <1> 	sub	cx, cx
  5306                              <1> mget_r_3:
  5307 0000B740 A3[24DC0000]        <1> 	mov	[readi.fclust], eax ; first cluster (or FDT address)
  5308 0000B745 880D[10DC0000]      <1> 	mov	[readi.valid], cl ; 0 
  5309 0000B74B 880D[13DC0000]      <1> 	mov	[readi.s_index], cl ; 0
  5310 0000B751 66890D[1ADC0000]    <1> 	mov	[readi.offset], cx ; 0
  5311 0000B758 890D[20DC0000]      <1> 	mov	[readi.c_index], ecx ; 0
  5312 0000B75E 890D[1CDC0000]      <1> 	mov	[readi.cluster], ecx ; 0
  5313 0000B764 890D[14DC0000]      <1> 	mov	[readi.sector], ecx ; 0
  5314                              <1> mget_r_4:	
  5315 0000B76A 89D8                <1> 	mov	eax, ebx ; file offset
  5316 0000B76C 668B0D[18DC0000]    <1> 	mov	cx, [readi.bpc]
  5317 0000B773 41                  <1> 	inc	ecx ; <= 65536
  5318 0000B774 29D2                <1> 	sub	edx, edx
  5319 0000B776 F7F1                <1> 	div	ecx
  5320 0000B778 8B3D[20DC0000]      <1> 	mov	edi, [readi.c_index] ; previous cluster index
  5321                              <1> mget_r_5:
  5322 0000B77E A3[20DC0000]        <1> 	mov	[readi.c_index], eax ; cluster index
  5323                              <1> 	; edx = byte offset in cluster (<= 65535)
  5324 0000B783 668915[1ADC0000]    <1> 	mov	[readi.offset], dx
  5325 0000B78A 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5326 0000B78E 8815[13DC0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5327                              <1> 
  5328 0000B794 89C1                <1> 	mov	ecx, eax ; current cluster index
  5329 0000B796 A1[24DC0000]        <1> 	mov	eax, [readi.fclust]
  5330 0000B79B 09C9                <1> 	or	ecx, ecx ; cluster index
  5331 0000B79D 741F                <1> 	jz	short mget_r_7
  5332                              <1> 
  5333 0000B79F 39CF                <1> 	cmp	edi, ecx
  5334 0000B7A1 7710                <1> 	ja	short mget_r_6 ; old cluster index is higher
  5335 0000B7A3 8B15[1CDC0000]      <1> 	mov	edx, [readi.cluster]
  5336 0000B7A9 21D2                <1> 	and	edx, edx
  5337 0000B7AB 7406                <1> 	jz	short mget_r_6
  5338                              <1> 	; valid 'readi' parameters (*)
  5339 0000B7AD 89D0                <1> 	mov	eax, edx
  5340 0000B7AF 29F9                <1> 	sub	ecx, edi
  5341 0000B7B1 7410                <1> 	jz	short mget_r_8
  5342                              <1> mget_r_6:
  5343                              <1> 	; EAX = Beginning cluster
  5344                              <1> 	; EDX = Sector index in disk/file section
  5345                              <1> 	;	(Only for SINGLIX file system!)
  5346                              <1> 	; ECX = Cluster sequence number after the beginning cluster
  5347                              <1> 	; ESI = Logical DOS Drive Description Table address
  5348 0000B7B3 E806E7FFFF          <1> 	call	get_cluster_by_index
  5349 0000B7B8 0F8226E8FFFF        <1> 	jc	error
  5350                              <1> 	; EAX = Cluster number		
  5351                              <1> mget_r_7:
  5352 0000B7BE A3[1CDC0000]        <1> 	mov	[readi.cluster], eax ; FDT number for Singlix File System
  5353                              <1> mget_r_8:
  5354 0000B7C3 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5355 0000B7C7 764E                <1> 	jna	short  mget_r_13
  5356                              <1> 
  5357 0000B7C9 83E802              <1> 	sub	eax, 2
  5358 0000B7CC 0FB615[12DC0000]    <1> 	movzx	edx, byte [readi.spc]
  5359 0000B7D3 F7E2                <1> 	mul	edx
  5360                              <1> 
  5361 0000B7D5 034668              <1> 	add	eax, [esi+LD_DATABegin]
  5362 0000B7D8 8A15[13DC0000]      <1> 	mov	dl, [readi.s_index]
  5363 0000B7DE 01D0                <1> 	add	eax, edx
  5364                              <1> msget_r_9:
  5365                              <1> 	; eax = logical sector number
  5366 0000B7E0 803D[10DC0000]00    <1> 	cmp	byte [readi.valid], 0
  5367 0000B7E7 7608                <1> 	jna	short mget_r_10
  5368 0000B7E9 3B05[14DC0000]      <1> 	cmp	eax, [readi.sector]
  5369 0000B7EF 7425                <1> 	je	short mget_r_12 ; sector is already in 'readi' buffer
  5370                              <1> mget_r_10:
  5371 0000B7F1 A3[14DC0000]        <1> 	mov	[readi.sector], eax
  5372 0000B7F6 BB[15E00000]        <1> 	mov	ebx, readi_buffer ; buffer address
  5373 0000B7FB B901000000          <1> 	mov	ecx, 1
  5374                              <1> 	; 29/04/2016
  5375                              <1> 	;xor	dl, dl
  5376                              <1> 
  5377                              <1> 	; EAX = Logical sector number
  5378                              <1> 	; ECX = Sector count
  5379                              <1> 	; EBX = Buffer address
  5380                              <1> 	; (EDX = 0)
  5381                              <1> 	; ESI = Logical DOS drive description table address	
  5382                              <1> 
  5383 0000B800 E886020000          <1> 	call	disk_read
  5384 0000B805 730A                <1> 	jnc	short mget_r_11
  5385                              <1> 
  5386 0000B807 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  5387 0000B80C E9D3E7FFFF          <1> 	jmp	error
  5388                              <1> mget_r_11:
  5389 0000B811 A1[14DC0000]        <1> 	mov	eax, [readi.sector]
  5390                              <1> mget_r_12:
  5391 0000B816 C3                  <1> 	retn
  5392                              <1> mget_r_13:
  5393                              <1> 	; EAX = FDT number
  5394                              <1> 	; EDX = Sector index from FDT sector (0,1,2,3,4...)
  5395 0000B817 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  5396 0000B818 8915[28DC0000]      <1> 	mov	[readi.fs_index], edx
  5397 0000B81E 01D0                <1> 	add	eax, edx
  5398 0000B820 EBBE                <1> 	jmp	short msget_r_9
  5399                              <1> 
  5400                              <1> trans_addr_r:
  5401                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  5402                              <1> 	; Translate virtual address to physical address 
  5403                              <1> 	; for reading from user's memory space
  5404                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5405                              <1> 
  5406 0000B822 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  5407 0000B824 EB04                <1> 	jmp 	short trans_addr_rw
  5408                              <1> 
  5409                              <1> trans_addr_w:
  5410                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5411                              <1> 	; Translate virtual address to physical address 
  5412                              <1> 	; for writing to user's memory space
  5413                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5414                              <1> 	
  5415 0000B826 29D2                <1> 	sub	edx, edx
  5416 0000B828 FEC2                <1> 	inc	dl ; 1 (write access sign)
  5417                              <1> trans_addr_rw:
  5418 0000B82A 50                  <1> 	push	eax
  5419 0000B82B 53                  <1> 	push	ebx
  5420 0000B82C 52                  <1> 	push 	edx ; r/w sign (in DL)
  5421                              <1> 	;
  5422 0000B82D 8B1D[A0DF0000]      <1> 	mov	ebx, [u.base]
  5423 0000B833 E86A7FFFFF          <1> 	call	get_physical_addr ; get physical address
  5424 0000B838 730A                <1> 	jnc	short passc_0
  5425 0000B83A A3[D5DF0000]        <1> 	mov	[u.error], eax
  5426                              <1> 	;pop	edx
  5427                              <1> 	;pop 	ebx
  5428                              <1> 	;pop	eax
  5429 0000B83F E9A0E7FFFF          <1> 	jmp	error
  5430                              <1> passc_0:
  5431 0000B844 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page
  5432 0000B847 5A                  <1> 	pop	edx
  5433 0000B848 751C                <1> 	jnz	short passc_1
  5434                              <1> 	
  5435 0000B84A 20D2                <1> 	and 	dl, dl
  5436 0000B84C 7418                <1> 	jz	short passc_1
  5437                              <1> 	; read only (duplicated) page -must be copied to a new page-
  5438                              <1> 	; EBX = linear address
  5439 0000B84E 51                  <1> 	push 	ecx
  5440 0000B84F E8637CFFFF          <1> 	call 	copy_page
  5441 0000B854 59                  <1> 	pop	ecx
  5442 0000B855 721E                <1> 	jc	short passc_2
  5443 0000B857 50                  <1> 	push	eax ; physical address of the new/allocated page
  5444 0000B858 E86F7EFFFF          <1> 	call	add_to_swap_queue	
  5445 0000B85D 58                  <1> 	pop	eax
  5446 0000B85E 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  5447                              <1> 	;mov 	ecx, PAGE_SIZE
  5448                              <1> 	;sub	ecx, ebx 
  5449 0000B864 01D8                <1> 	add	eax, ebx  
  5450                              <1> passc_1: 
  5451 0000B866 A3[E1DF0000]        <1> 	mov 	[u.pbase], eax ; physical address	
  5452 0000B86B 66890D[E5DF0000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  5453 0000B872 5B                  <1> 	pop	ebx
  5454 0000B873 58                  <1> 	pop	eax
  5455 0000B874 C3                  <1> 	retn
  5456                              <1> passc_2:
  5457 0000B875 C705[D5DF0000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
  5457 0000B87D 0000                <1>
  5458                              <1> 	;pop 	ebx
  5459                              <1> 	;pop	eax
  5460 0000B87F E960E7FFFF          <1> 	jmp	error
  5461                              <1> 
  5462                              <1> sioreg: 
  5463                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5464                              <1> 	; 19/05/2015 - 25/07/2015 (Retro UNIX 386 v1)
  5465                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
  5466                              <1> 	; INPUTS -> 
  5467                              <1> 	;     EBX = system buffer (data) address (r5)
  5468                              <1> 	;     [u.fofp] = pointer to file offset pointer
  5469                              <1> 	;     [u.base] = virtual address of the user buffer
  5470                              <1> 	;     [u.pbase] = physical address of the user buffer
  5471                              <1> 	;     [u.count] = byte count
  5472                              <1> 	;     [u.pcount] = byte count within page frame 			
  5473                              <1> 	; OUTPUTS -> 
  5474                              <1> 	;     ESI = user data offset (r1)
  5475                              <1> 	;     EDI = system (I/O) buffer offset (r2)
  5476                              <1> 	;     ECX = byte count (r3)
  5477                              <1> 	;     EAX = remain bytes after byte count within page frame
  5478                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
  5479                              <1>         ;
  5480                              <1> 	; ((Modified registers:  EDX))
  5481                              <1>  
  5482 0000B884 8B35[90DF0000]      <1>         mov     esi, [u.fofp]
  5483 0000B88A 8B3E                <1>         mov     edi, [esi]
  5484 0000B88C 89F9                <1> 	mov	ecx, edi
  5485 0000B88E 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  5486 0000B894 81E7FF010000        <1> 	and	edi, 1FFh
  5487 0000B89A 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  5488 0000B89C F7D9                <1> 	neg	ecx
  5489 0000B89E 3B0D[A4DF0000]      <1> 	cmp	ecx, [u.count]
  5490 0000B8A4 7606                <1> 	jna	short sioreg_0
  5491 0000B8A6 8B0D[A4DF0000]      <1> 	mov	ecx, [u.count]
  5492                              <1> sioreg_0:
  5493 0000B8AC 803D[E7DF0000]00    <1> 	cmp	byte [u.kcall], 0 
  5494 0000B8B3 7613                <1> 	jna	short sioreg_1
  5495                              <1> 	 ; the caller is 'mkdir' or 'namei'
  5496 0000B8B5 A1[A0DF0000]        <1> 	mov	eax, [u.base]
  5497 0000B8BA A3[E1DF0000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  5498 0000B8BF 66890D[E5DF0000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  5499 0000B8C6 EB0B                <1> 	jmp	short sioreg_2
  5500                              <1> sioreg_1:
  5501 0000B8C8 0FB715[E5DF0000]    <1> 	movzx	edx, word [u.pcount]
  5502 0000B8CF 39D1                <1> 	cmp	ecx, edx	
  5503 0000B8D1 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  5504                              <1> sioreg_2: ; 2:
  5505 0000B8D3 31C0                <1> 	xor 	eax, eax
  5506                              <1> sioreg_3:
  5507 0000B8D5 010D[A8DF0000]      <1> 	add 	[u.nread], ecx
  5508 0000B8DB 290D[A4DF0000]      <1> 	sub 	[u.count], ecx
  5509 0000B8E1 010D[A0DF0000]      <1> 	add 	[u.base], ecx
  5510 0000B8E7 010E                <1>         add 	[esi], ecx 
  5511 0000B8E9 8B35[E1DF0000]      <1> 	mov	esi, [u.pbase]
  5512 0000B8EF 66290D[E5DF0000]    <1> 	sub	[u.pcount], cx
  5513 0000B8F6 010D[E1DF0000]      <1> 	add	[u.pbase], ecx
  5514 0000B8FC C3                  <1>         retn
  5515                              <1> sioreg_4:
  5516                              <1> 	; transfer count > [u.pcount] 
  5517                              <1> 	; (ecx > edx)
  5518 0000B8FD 89C8                <1> 	mov	eax, ecx
  5519 0000B8FF 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  5520 0000B901 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  5521 0000B903 EBD0                <1> 	jmp	short sioreg_3
  5522                              <1> 
  5523                              <1> switch: ; Retro UNIX 386 v1
  5524                              <1> swap:
  5525                              <1> 	; 02/05/2016
  5526                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5527                              <1> 	; 10/05/2015 - 02/09/2015 (Retro UNIX 386 v1)
  5528                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5529                              <1> 	;
  5530                              <1> 	; 'swap' is routine that controls the swapping of processes
  5531                              <1> 	; in and out of core.
  5532                              <1> 	;
  5533                              <1> 	; Retro UNIX 386 v1 modification ->
  5534                              <1> 	;       swap (software task switch) is performed by changing
  5535                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  5536                              <1> 	;	as in Retro UNIX 8086 v1.
  5537                              <1> 	;
  5538                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5539                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5540                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5541                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5542                              <1> 	;	compatibles was using 1MB segmented memory 
  5543                              <1> 	;	in 8086/8088 times.
  5544                              <1> 	;
  5545                              <1> 	; INPUTS ->
  5546                              <1> 	;    runq table - contains processes to run.
  5547                              <1> 	;    p.link - contains next process in line to be run.
  5548                              <1> 	;    u.uno - process number of process in core	
  5549                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
  5550                              <1> 	; OUTPUTS ->
  5551                              <1> 	;    (original unix v1 -> present process to its disk block)
  5552                              <1> 	;    (original unix v1 -> new process into core -> 
  5553                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
  5554                              <1> 	;	   for new process)
  5555                              <1> 	;    u.quant = 3 (Time quantum for a process)
  5556                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
  5557                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
  5558                              <1> 	;	 for now, it will swap the process if there is not
  5559                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
  5560                              <1> 	;	 or will count down from 3 to 0 even if there is a
  5561                              <1> 	;        keyboard event locking due to repetitive key strokes.
  5562                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
  5563                              <1> 	;
  5564                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
  5565                              <1> 	;
  5566                              <1> swap_0:
  5567 0000B905 BE[72DF0000]        <1> 	mov	esi, runq
  5568                              <1> swap_1: ; 1: / search runq table for highest priority process
  5569 0000B90A 668B06              <1> 	mov	ax, [esi]
  5570 0000B90D 31DB                <1> 	xor	ebx, ebx ; 02/05/2016
  5571 0000B90F 6621C0              <1> 	and 	ax, ax ; are there any processes to run in the queue
  5572 0000B912 7506                <1> 	jnz	short swap_2 
  5573                              <1> 	; 02/05/2016
  5574                              <1> 	; 29/04/2016 (TRDOS 386 = TRDOS v2.0) 
  5575 0000B914 FEC0                <1> 	inc	al ; mov al, 1  ; process number of MainProg
  5576 0000B916 FEC3                <1> 	inc	bl ; mov bl, al ; 1
  5577 0000B918 EB16                <1> 	jmp	short swap_4
  5578                              <1> swap_2:
  5579 0000B91A 88C3                <1> 	mov	bl, al
  5580 0000B91C 38E0                <1> 	cmp	al, ah ; is there only 1 process in the queue to be run
  5581 0000B91E 740A                <1> 	je	short swap_3 ; yes
  5582 0000B920 8AA3[F7DC0000]      <1> 	mov	ah, [ebx+p.link-1] 
  5583 0000B926 8826                <1>        	mov	[esi], ah ; move next process in line into run queue
  5584 0000B928 EB06                <1> 	jmp	short swap_4
  5585                              <1> swap_3: 
  5586 0000B92A 6631D2              <1> 	xor	dx, dx
  5587 0000B92D 668916              <1> 	mov	[esi], dx ; zero the entry; no processes on the Q
  5588                              <1> swap_4: 
  5589 0000B930 8A25[CFDF0000]      <1> 	mov 	ah, [u.uno]
  5590 0000B936 38C4                <1> 	cmp	ah, al ;is this process the same as the process in core?
  5591 0000B938 743B                <1>        	je	short swap_8 ; yes, don't have to swap
  5592 0000B93A 08E4                <1> 	or	ah, ah  ; is the process # = 0
  5593 0000B93C 740D                <1>        	jz	short swap_6 ; 'sysexit'
  5594 0000B93E 8925[7CDF0000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  5595 0000B944 E834000000          <1> 	call	wswap   ; write out core to disk
  5596 0000B949 EB1C                <1> 	jmp 	short swap_7
  5597                              <1> swap_6:
  5598                              <1> 	; Deallocate memory pages belong to the process
  5599                              <1> 	; which is being terminated.
  5600                              <1> 	; (Retro UNIX 386 v1 modification !)
  5601                              <1> 	;
  5602 0000B94B 53                  <1> 	push	ebx
  5603 0000B94C A1[D9DF0000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  5604 0000B951 8B1D[DDDF0000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  5605 0000B957 E8EC78FFFF          <1> 	call	deallocate_page_dir
  5606 0000B95C A1[D0DF0000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  5607 0000B961 E88179FFFF          <1> 	call	deallocate_page
  5608 0000B966 5B                  <1> 	pop	ebx
  5609                              <1> swap_7: 
  5610 0000B967 C0E302              <1> 	shl	bl, 2 ; * 4 
  5611 0000B96A 8B83[14DD0000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  5612 0000B970 E831000000          <1> 	call	rswap ; read new process into core
  5613                              <1> swap_8: 
  5614                              <1> 	; Retro UNIX  8086 v1 modification !
  5615 0000B975 C605[C2DF0000]04    <1> 	mov	byte [u.quant], time_count 
  5616 0000B97C C3                  <1> 	retn
  5617                              <1> 
  5618                              <1> wswap:  ; < swap out, swap to disk >
  5619                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5620                              <1> 	; 09/05/2015 (Retro UNIX 386 v1)
  5621                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5622                              <1> 	; 'wswap' writes out the process that is in core onto its 
  5623                              <1> 	; appropriate disk area.
  5624                              <1> 	;
  5625                              <1> 	; Retro UNIX 386 v1 modification ->
  5626                              <1> 	;       User (u) structure content and the user's register content
  5627                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
  5628                              <1> 	;	saving 'u' structure and user registers for task switching).
  5629                              <1> 	;	u.usp - points to kernel stack address which contains
  5630                              <1> 	;		user's registers while entering system call.  
  5631                              <1> 	;	u.sp  - points to kernel stack address 
  5632                              <1> 	;		to return from system call -for IRET-.
  5633                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5634                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5635                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5636                              <1> 	;
  5637                              <1> 	; Retro UNIX 8086 v1 modification ->
  5638                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5639                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5640                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5641                              <1> 	;	compatibles was using 1MB segmented memory 
  5642                              <1> 	;	in 8086/8088 times.
  5643                              <1> 	;
  5644                              <1> 	; INPUTS ->
  5645                              <1> 	;    u.break - points to end of program
  5646                              <1> 	;    u.usp - stack pointer at the moment of swap
  5647                              <1> 	;    core - beginning of process program		
  5648                              <1> 	;    ecore - end of core 	
  5649                              <1> 	;    user - start of user parameter area		
  5650                              <1> 	;    u.uno - user process number	
  5651                              <1> 	;    p.dska - holds block number of process	
  5652                              <1> 	; OUTPUTS ->
  5653                              <1> 	;    swp I/O queue
  5654                              <1> 	;    p.break - negative word count of process 
  5655                              <1> 	;    r1 - process disk address	
  5656                              <1> 	;    r2 - negative word count
  5657                              <1> 	;
  5658                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5659                              <1> 	;
  5660                              <1> 	; INPUTS ->
  5661                              <1> 	;    u.uno - process number (to be swapped out)
  5662                              <1> 	; OUTPUTS ->
  5663                              <1> 	;    none
  5664                              <1> 	;
  5665                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
  5666                              <1> 	;
  5667 0000B97D 8B3D[D0DF0000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  5668 0000B983 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5669 0000B988 BE[78DF0000]        <1> 	mov	esi, user ; active user (u) structure	
  5670 0000B98D F3A5                <1> 	rep	movsd
  5671                              <1> 	;
  5672 0000B98F 8B35[7CDF0000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  5673                              <1> 			     ;      points to user registers)
  5674 0000B995 8B0D[78DF0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5675                              <1> 			     ; (for IRET)
  5676                              <1> 			     ; [u.sp] -> EIP (user)
  5677                              <1> 			     ; [u.sp+4]-> CS (user)
  5678                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5679                              <1> 			     ; [u.sp+12] -> ESP (user)
  5680                              <1> 			     ; [u.sp+16] -> SS (user)	
  5681 0000B99B 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  5682 0000B99D 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5683                              <1> 			     ; (for IRET) 	
  5684 0000B9A0 C1E902              <1> 	shr	ecx, 2	     		
  5685 0000B9A3 F3A5                <1> 	rep	movsd
  5686 0000B9A5 C3                  <1> 	retn
  5687                              <1> 
  5688                              <1> rswap:  ; < swap in, swap from disk >
  5689                              <1> 	; 03/05/2016
  5690                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5691                              <1> 	; 09/05/2015 - 15/09/2015 (Retro UNIX 386 v1)
  5692                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5693                              <1> 	; 'rswap' reads a process whose number is in r1, 
  5694                              <1> 	; from disk into core.
  5695                              <1> 	;
  5696                              <1> 	; Retro UNIX 386 v1 modification ->
  5697                              <1> 	;       User (u) structure content and the user's register content
  5698                              <1> 	;	will be restored from process's/user's UPAGE (a page for
  5699                              <1> 	;	saving 'u' structure and user registers for task switching).
  5700                              <1> 	;	u.usp - points to kernel stack address which contains
  5701                              <1> 	;		user's registers while entering system call.  
  5702                              <1> 	;	u.sp  - points to kernel stack address 
  5703                              <1> 	;		to return from system call -for IRET-.
  5704                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5705                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5706                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5707                              <1> 	;
  5708                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5709                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5710                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5711                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5712                              <1> 	;	compatibles was using 1MB segmented memory 
  5713                              <1> 	;	in 8086/8088 times.
  5714                              <1> 	;
  5715                              <1> 	; INPUTS ->
  5716                              <1> 	;    r1 - process number of process to be read in
  5717                              <1> 	;    p.break - negative of word count of process 
  5718                              <1> 	;    p.dska - disk address of the process		
  5719                              <1> 	;    u.emt - determines handling of emt's 	
  5720                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5721                              <1> 	; OUTPUTS ->
  5722                              <1> 	;    8 = (u.ilgins)
  5723                              <1> 	;    24 = (u.emt)
  5724                              <1> 	;    swp - bit 10 is set to indicate read 
  5725                              <1> 	;		(bit 15=0 when reading is done)	
  5726                              <1> 	;    swp+2 - disk block address
  5727                              <1> 	;    swp+4 - negative word count 	
  5728                              <1> 	;      ((swp+6 - address of user structure)) 
  5729                              <1> 	;
  5730                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5731                              <1> 	;
  5732                              <1> 	; INPUTS ->
  5733                              <1> 	;    AL	- new process number (to be swapped in)	 
  5734                              <1> 	; OUTPUTS ->
  5735                              <1> 	;    none
  5736                              <1> 	;
  5737                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
  5738                              <1> 	;
  5739                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
  5740 0000B9A6 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  5741 0000B9A8 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5742 0000B9AD BF[78DF0000]        <1> 	mov	edi, user ; active user (u) structure	
  5743 0000B9B2 F3A5                <1> 	rep	movsd
  5744 0000B9B4 58                  <1> 	pop	eax	; 'rswap' return address 
  5745                              <1> 	;cli
  5746 0000B9B5 8B3D[7CDF0000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  5747                              <1> 			     ;     points to user registers)
  5748 0000B9BB 8B0D[78DF0000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5749                              <1> 			     ; (for IRET)
  5750                              <1> 			     ; [u.sp] -> EIP (user)
  5751                              <1> 			     ; [u.sp+4]-> CS (user)
  5752                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5753                              <1> 			     ; [u.sp+12] -> ESP (user)
  5754                              <1> 			     ; [u.sp+16] -> SS (user)		
  5755 0000B9C1 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  5756 0000B9C3 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5757                              <1> 			     ; (for IRET) 	
  5758 0000B9C6 C1E902              <1> 	shr	ecx, 2	       		
  5759 0000B9C9 F3A5                <1> 	rep	movsd
  5760 0000B9CB 8B25[7CDF0000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
  5761                              <1> 	;sti
  5762 0000B9D1 50                  <1> 	push	eax	; 'rswap' return address
  5763 0000B9D2 C3                  <1> 	retn
  5764                              <1> 
  5765                              <1> putlu: 
  5766                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5767                              <1> 	; 10/05/2015 - 12/09/2015 (Retro UNIX 386 v1)
  5768                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  5769                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
  5770                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
  5771                              <1> 	; the last process on the queue to process in r1 by putting
  5772                              <1> 	; the process number in r1 into the last process's link.
  5773                              <1> 	;
  5774                              <1> 	; INPUTS ->
  5775                              <1> 	;    r1 - user process number
  5776                              <1> 	;    r2 - points to lowest priority queue 
  5777                              <1> 	;    p.dska - disk address of the process		
  5778                              <1> 	;    u.emt - determines handling of emt's 	
  5779                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5780                              <1> 	; OUTPUTS ->
  5781                              <1> 	;    r3 - process number of last process on the queue upon
  5782                              <1> 	;	  entering putlu
  5783                              <1> 	;    p.link-1 + r3 - process number in r1
  5784                              <1> 	;    r2 - points to lowest priority queue
  5785                              <1> 	;
  5786                              <1> 	; ((Modified registers: EDX, EBX)) 
  5787                              <1> 	;
  5788                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
  5789                              <1> 
  5790                              <1> 	; EBX = r2
  5791                              <1> 	; EAX = r1 (AL=r1b)
  5792                              <1> 
  5793 0000B9D3 BB[72DF0000]        <1> 	mov	ebx, runq
  5794 0000B9D8 0FB613              <1> 	movzx  	edx, byte [ebx]
  5795 0000B9DB 43                  <1> 	inc	ebx
  5796 0000B9DC 20D2                <1> 	and	dl, dl
  5797                              <1> 		; tstb (r2)+ / is queue empty?
  5798 0000B9DE 740A                <1>        	jz	short putlu_1
  5799                              <1> 		; beq 1f / yes, branch
  5800 0000B9E0 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
  5801                              <1> 		; movb (r2),r3 / no, save the "last user" process number
  5802                              <1> 			     ; / in r3
  5803 0000B9E2 8882[F7DC0000]      <1>        	mov	[edx+p.link-1], al
  5804                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
  5805                              <1> 			     ; / "last users" link
  5806 0000B9E8 EB03                <1> 	jmp	short putlu_2
  5807                              <1> 		; br 2f /
  5808                              <1> putlu_1: ; 1:
  5809 0000B9EA 8843FF              <1> 	mov	[ebx-1], al
  5810                              <1>        		; movb r1,-1(r2) / user is only user; 
  5811                              <1> 			    ; / put process no. at beginning and at end
  5812                              <1> putlu_2: ; 2: 
  5813 0000B9ED 8803                <1> 	mov	[ebx], al
  5814                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
  5815                              <1> 			     ; / on the queue
  5816 0000B9EF 88C2                <1> 	mov	dl, al
  5817 0000B9F1 88B2[F7DC0000]      <1>         mov     [edx+p.link-1], dh ; 0
  5818                              <1> 		; dec r2 / restore r2
  5819 0000B9F7 C3                  <1>         retn
  5820                              <1> 		; rts r0
  5821                              <1> sysver:
  5822                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5823 0000B9F8 C705[80DF0000]0002- <1> 	mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  5823 0000BA00 0000                <1>
  5824 0000BA02 E9FDE5FFFF          <1> 	jmp	sysret
  5825                              <1> 
  5826                              <1> cpass: ; / get next character from user area of core and put it in AL (r1)
  5827                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  5828                              <1> 	; 19/05/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5829                              <1> 	; 14/08/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  5830                              <1> 	; INPUTS -> 
  5831                              <1> 	;     [u.base] = virtual address in user area
  5832                              <1> 	;     [u.count] = byte count (max.)
  5833                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
  5834                              <1> 	; OUTPUTS -> 
  5835                              <1> 	;     AL = the character which is pointed by [u.base]
  5836                              <1> 	;     zf = 1 -> transfer count has been completed	
  5837                              <1>         ;
  5838                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
  5839                              <1> 	;
  5840 0000BA07 833D[A4DF0000]00    <1> 	cmp 	dword [u.count], 0  ; have all the characters been transferred
  5841                              <1> 			    	    ; i.e., u.count, # of chars. left
  5842 0000BA0E 763F                <1> 	jna	short cpass_3	    ; to be transferred = 0?) yes, branch
  5843 0000BA10 FF0D[A4DF0000]      <1> 	dec	dword [u.count]	    ; no, decrement u.count
  5844                              <1>         ; 19/05/2015 
  5845                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
  5846                              <1> 	;		      to physical address
  5847 0000BA16 66833D[E5DF0000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  5848                              <1> 			     ; 1-4095 --> use previous physical base address
  5849                              <1> 			     ; in [u.pbase]
  5850 0000BA1E 770E                <1> 	ja	short cpass_1
  5851 0000BA20 833D[DDDF0000]00    <1> 	cmp     dword [u.ppgdir], 0  ; is the caller os kernel
  5852 0000BA27 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ?  (MainProg)
  5853 0000BA29 E8F4FDFFFF          <1> 	call	trans_addr_r
  5854                              <1> cpass_1:
  5855 0000BA2E 66FF0D[E5DF0000]    <1> 	dec	word [u.pcount]
  5856                              <1> cpass_2: 
  5857 0000BA35 8B15[E1DF0000]      <1> 	mov	edx, [u.pbase]
  5858 0000BA3B 8A02                <1> 	mov	al, [edx]	; take the character pointed to 
  5859                              <1> 				; by u.base and put it in r1
  5860 0000BA3D FF05[A8DF0000]      <1> 	inc	dword [u.nread] ; increment no. of bytes transferred
  5861 0000BA43 FF05[A0DF0000]      <1> 	inc	dword [u.base]  ; increment the buffer address to point to the
  5862                              <1> 			        ; next byte
  5863 0000BA49 FF05[E1DF0000]      <1> 	inc	dword [u.pbase]
  5864                              <1> cpass_3:
  5865 0000BA4F C3                  <1> 	retn
  5866                              <1> cpass_k:
  5867                              <1> 	; 02/07/2015
  5868                              <1> 	; The caller is os kernel 
  5869                              <1> 	; (get sysexec arguments from kernel's memory space)
  5870 0000BA50 8B1D[A0DF0000]      <1> 	mov	ebx, [u.base]
  5871 0000BA56 66C705[E5DF0000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  5871 0000BA5E 10                  <1>
  5872 0000BA5F 891D[E1DF0000]      <1> 	mov	[u.pbase], ebx
  5873 0000BA65 EBCE                <1> 	jmp	short cpass_2
  5874                              <1> 	
  5875                              <1> ; temporary - 24/01/2016
  5876                              <1> 
  5877                              <1> iget:
  5878 0000BA67 C3                  <1> 	retn
  5879                              <1> poke:
  5880 0000BA68 C3                  <1> 	retn
  5881                              <1> tswap:
  5882 0000BA69 C3                  <1> 	retn
  5883                              <1> isintr:
  5884 0000BA6A C3                  <1> 	retn
  5885                              <1> writei:
  5886 0000BA6B C3                  <1> 	retn
  5887                              <1> iopen:
  5888 0000BA6C C3                  <1> 	retn
  5889                              <1> iclose:
  5890 0000BA6D C3                  <1> 	retn
  5891                              <1> itrunc:
  5892 0000BA6E C3                  <1> 	retn
  5893                              <1> clock:
  5894 0000BA6F C3                  <1> 	retn
  5895                              <1> setimod:
  5896 0000BA70 C3                  <1> 	retn
  5897                              <1> ottyp:
  5898 0000BA71 C3                  <1> 	retn
  5899                              <1> cttyp:
  5900 0000BA72 C3                  <1> 	retn
  5901                              <1> sndc:
  5902 0000BA73 C3                  <1> 	retn
  5903                              <1> access:
  5904 0000BA74 C3                  <1> 	retn
  5905                              <1> passc:
  5906 0000BA75 C3                  <1> 	retn
  5907                              <1> epoch:
  5908 0000BA76 C3                  <1> 	retn
  5909                              <1> set_date_time:
  5910 0000BA77 C3                  <1> 	retn
  5911                              <1> imap:
  5912 0000BA78 C3                  <1> 	retn
  5913                              <1> diskio:
  5914 0000BA79 C3                  <1> 	retn
  5915                              <1> idle:
  5916 0000BA7A C3                  <1> 	retn
  5917                              <1> sleep:
  5918 0000BA7B C3                  <1> 	retn
  1930                                  %include 'trdosk7.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DISK READ&WRITE : trdosk7.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 25/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; DISK_IO.ASM (20/07/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DISK_IO.ASM (c) 2009-2011 Erdogan TAN [ 04/07/2009 ] Last Update: 20/07/2011
    14                              <1> 
    15                              <1> disk_write:
    16                              <1> 	; 25/02/2016
    17                              <1> 	; 24/02/2016
    18                              <1> 	; 23/02/2016
    19 0000BA7C 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    20 0000BA80 777B                <1>         ja      short lba_write
    21                              <1> 
    22                              <1> chs_write:
    23                              <1> 	; 25/02/2016
    24                              <1> 	; 23/02/2016
    25 0000BA82 C605[95D80000]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    26 0000BA89 EB0D                <1> 	jmp	short chs_rw
    27                              <1> 
    28                              <1> disk_read:
    29                              <1> 	; 25/02/2016
    30                              <1> 	; 24/02/2016
    31                              <1> 	; 23/02/2016
    32                              <1> 	; 17/02/2016
    33                              <1> 	; 14/02/2016
    34                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
    35                              <1> 	; 17/10/2010
    36                              <1> 	; 18/04/2010
    37                              <1> 	;
    38                              <1> 	; INPUT -> EAX = Logical Block Address
    39                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
    40                              <1> 	;	   ECX = Sector Count	
    41                              <1> 	; 	   EBX = Destination Buffer
    42                              <1> 	; OUTPUT -> 
    43                              <1> 	;	   cf = 0 or cf = 1
    44                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
    45                              <1> 
    46 0000BA8B 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    47 0000BA8F 7775                <1>         ja      short lba_read
    48                              <1> 
    49                              <1> chs_read:
    50                              <1> 	; 25/02/2016
    51                              <1> 	; 24/02/2016
    52                              <1> 	; 23/02/2016
    53                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
    54                              <1> 	; 20/07/2011
    55                              <1> 	; 04/07/2009
    56                              <1> 	;
    57                              <1> 	; INPUT -> EAX = Logical Block Address
    58                              <1> 	;	   ECX = Number of sectors to read
    59                              <1> 	; 	   ESI = Logical Dos Disk Table Offset (DRV)
    60                              <1> 	; 	   EBX = Destination Buffer
    61                              <1> 	; OUTPUT -> 
    62                              <1> 	;	   cf = 0 or cf = 1
    63                              <1> 	; (Modified registers: EAX; EBX, ECX, EDX)
    64                              <1> 
    65                              <1> 	; 23/02/2016
    66 0000BA91 C605[95D80000]02    <1> 	mov	byte [disk_rw_op], 2 ; CHS read
    67                              <1> 
    68                              <1> chs_rw:
    69                              <1> 	;;movzx	edx, word [esi+LD_BPB+SecPerTrack]
    70                              <1> 	;movzx	edx, byte [esi+LD_BPB+SecPerTrack] ; <= 63
    71                              <1> 	;mov	[disk_rw_spt], dl
    72                              <1> 
    73                              <1> chs_read_next_sector:
    74 0000BA98 C605[96D80000]04    <1> 	mov	byte [retry_count], 4
    75                              <1>      
    76                              <1> chs_read_retry:
    77                              <1> 	;mov	[sector_count], ecx ; 23/02/2016
    78                              <1> 
    79 0000BA9F 50                  <1> 	push	eax			; Linear sector #
    80 0000BAA0 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    81                              <1>                 
    82 0000BAA1 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    83                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    84 0000BAA5 29D2                <1> 	sub	edx, edx
    85 0000BAA7 F7F1                <1> 	div	ecx
    86                              <1> 	; eax = track, dx (dl ) = sector (on track)
    87                              <1> 	;sub	cl, dl ; 24/02/2016 (spt - sec)
    88                              <1> 	;push	ecx ; *
    89 0000BAA9 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    90 0000BAAC 6641                <1> 	inc	cx			; To make it 1 based
    91 0000BAAE 6651                <1> 	push	cx
    92 0000BAB0 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    93 0000BAB4 6629D2              <1> 	sub	dx, dx
    94 0000BAB7 F7F1                <1> 	div	ecx			; Convert track to head & cyl
    95                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    96 0000BAB9 88D6                <1> 	mov	dh, dl
    97 0000BABB 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    98 0000BABD 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
    99                              <1> 
   100 0000BAC0 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   101 0000BAC2 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   102 0000BAC5 08E1                <1> 	or	cl, ah
   103                              <1> 
   104                              <1> 	; 24/02/2016
   105                              <1> 	;pop	eax ; * (spt - sec) (example: 63 - 0 = 63)
   106                              <1> 	;cmp	eax, [sector_count]
   107                              <1> 	;jb	short chs_write_sectors
   108                              <1> 	;je	short chs_read_sectors
   109                              <1> 	;; (# of sectors to read is more than remaining sectors on the track)
   110                              <1> 	;mov	al, [sector_count]
   111                              <1> ;chs_read_sectors: ; read or write !
   112 0000BAC7 B001                <1> 	mov	al, 1 ; 25/02/2016
   113 0000BAC9 8A25[95D80000]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   114                              <1> 	;
   115 0000BACF E8006EFFFF          <1> 	call	int13h			; BIOS Service func ( ah ) = 2
   116                              <1>                                         ; Read disk sectors
   117                              <1>                                         ; AL-sec num CH-track CL-sec
   118                              <1>                                         ; DH-head DL-drive ES:BX-buffer
   119                              <1>                                         ; CF-flag AH-stat AL-sec read
   120                              <1> 	                                ; If CF = 1 then (If AH > 0)
   121 0000BAD4 8825[97D80000]      <1> 	mov	[disk_rw_err], ah
   122                              <1> 	
   123 0000BADA 59                  <1> 	pop	ecx
   124 0000BADB 58                  <1> 	pop	eax
   125 0000BADC 7314                <1> 	jnc	short chs_read_ok
   126                              <1> 
   127 0000BADE 803D[97D80000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   128 0000BAE5 7408                <1> 	je	short chs_read_error_retn
   129                              <1>              
   130 0000BAE7 FE0D[96D80000]      <1> 	dec	byte [retry_count]
   131 0000BAED 75B0                <1> 	jnz	short chs_read_retry
   132                              <1> 
   133                              <1> chs_read_error_retn:
   134 0000BAEF F9                  <1> 	stc
   135                              <1> 	;retn
   136 0000BAF0 EB69                <1> 	jmp	short update_drv_error_byte
   137                              <1> 
   138                              <1> ;chs_write_sectors: ; read or write 
   139                              <1> 	;; (# of sectors to read is less than remaining sectors on the track)
   140                              <1> 	;mov	[sector_count], al
   141                              <1> 	;jmp	short chs_read_sectors
   142                              <1> 
   143                              <1> chs_read_ok:
   144                              <1> 	;; 23/02/2016
   145                              <1> 	;movzx	edx, byte [sector_count] ; sector count (<= spt)	
   146                              <1>         ;sub    ecx, edx  ; remaining sector count
   147                              <1> 	;jna	short update_drv_error_byte	
   148                              <1> 	;add	eax, edx ; next disk sector
   149                              <1> 	;shl	edx, 9 ; 512 * sector count
   150                              <1> 	;add	ebx, edx ; next buffer byte address 
   151                              <1>         ;jmp     chs_read_next_sector        
   152                              <1> 	; 25/02/2016
   153 0000BAF2 40                  <1> 	inc	eax ; next sector
   154 0000BAF3 81C300020000        <1> 	add	ebx, 512
   155 0000BAF9 E29D                <1> 	loop	chs_read_next_sector
   156 0000BAFB EB5E                <1> 	jmp	short update_drv_error_byte
   157                              <1> 
   158                              <1> lba_write:
   159                              <1> 	; 23/02/2016
   160 0000BAFD C605[95D80000]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   161 0000BB04 EB07                <1> 	jmp	short lba_rw
   162                              <1> 
   163                              <1> lba_read:
   164                              <1> 	; 23/02/2016
   165                              <1> 	; 17/02/2016
   166                              <1> 	; 14/02/2016
   167                              <1> 	; 13/02/2016
   168                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
   169                              <1> 	; 10/07/2015 (Retro UNIX 386 v1)
   170                              <1> 	;
   171                              <1> 	; INPUT -> EAX = Logical Block Address
   172                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
   173                              <1> 	;	   ECX = Sector Count	
   174                              <1> 	; 	   EBX = Destination Buffer
   175                              <1> 	; OUTPUT -> 
   176                              <1> 	;	   cf = 0 or cf = 1
   177                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
   178                              <1> 
   179                              <1> 	; LBA read/write (with private LBA function) 
   180                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   181                              <1> 
   182                              <1> 
   183                              <1> 	; 23/02/2016
   184 0000BB06 C605[95D80000]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   185                              <1> 
   186                              <1> lba_rw:
   187                              <1> 	; 17/02/2016
   188 0000BB0D 57                  <1> 	push	edi
   189                              <1> 
   190 0000BB0E 890D[98D80000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   191                              <1> 
   192 0000BB14 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
   193                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   194                              <1> 
   195                              <1> lba_read_next:
   196 0000BB17 81F900010000        <1> 	cmp	ecx, 256
   197 0000BB1D 7605                <1> 	jna	short lba_read_rsc
   198 0000BB1F B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   199                              <1> lba_read_rsc:
   200 0000BB24 290D[98D80000]      <1> 	sub	[sector_count], ecx ; remain sectors
   201                              <1> 
   202 0000BB2A 89CF                <1> 	mov	edi, ecx 
   203 0000BB2C 89C1                <1> 	mov	ecx, eax ; sector number/address
   204                              <1> 
   205 0000BB2E C605[96D80000]04    <1> 	mov	byte [retry_count], 4
   206                              <1> lba_read_retry:
   207 0000BB35 89F8                <1> 	mov	eax, edi
   208                              <1> 	;
   209                              <1> 	; ecx = sector number
   210                              <1> 	; al = sector count (0 - 255) /// (0 = 256)
   211                              <1> 	; dl = drive number
   212                              <1> 	; ebx = buffer offset
   213                              <1> 	;
   214                              <1> 	; Function 1Bh = LBA read, 1Ch = LBA write
   215                              <1> 	; 23/02/2016
   216 0000BB37 8A25[95D80000]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   217 0000BB3D E8926DFFFF          <1> 	call	int13h
   218                              <1> 	; al = ? (changed)
   219                              <1> 	; ah = error code
   220 0000BB42 8825[97D80000]      <1> 	mov	[disk_rw_err], ah
   221 0000BB48 7334                <1> 	jnc	short lba_read_ok
   222 0000BB4A 80FC80              <1> 	cmp	ah, 80h ; time out?
   223 0000BB4D 740A                <1>         je      short lba_read_stc_retn
   224 0000BB4F FE0D[96D80000]      <1> 	dec	byte [retry_count]
   225 0000BB55 7FDE                <1> 	jg	short lba_read_retry
   226 0000BB57 743A                <1> 	jz	short lba_read_reset
   227                              <1> 	; sf =  1
   228                              <1> 
   229                              <1> lba_read_stc_retn:
   230 0000BB59 F9                  <1> 	stc
   231                              <1> lba_read_retn:
   232 0000BB5A 5F                  <1> 	pop	edi
   233                              <1> 
   234                              <1> update_drv_error_byte:
   235 0000BB5B 9C                  <1> 	pushf
   236 0000BB5C 53                  <1> 	push	ebx
   237 0000BB5D 6651                <1> 	push	cx
   238                              <1> 	;or	ecx, ecx
   239                              <1> 	;jz	short udrv_errb0
   240 0000BB5F 8A0D[97D80000]      <1> 	mov	cl, [disk_rw_err]
   241                              <1> udrv_errb0:
   242 0000BB65 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   243 0000BB69 80FB02              <1> 	cmp	bl, 2
   244 0000BB6C 7203                <1>         jb      short udrv_errb1
   245 0000BB6E 80EB7E              <1> 	sub	bl, 7Eh
   246                              <1> 	;cmp	bl, 5
   247                              <1> 	;ja	short udrv_errb2	
   248                              <1> udrv_errb1:
   249 0000BB71 81C3[C1C90000]      <1>         add     ebx, drv.error ; 13/02/2016
   250 0000BB77 880B                <1> 	mov	[ebx], cl ; error code
   251                              <1> udrv_errb2:
   252 0000BB79 6659                <1> 	pop	cx
   253 0000BB7B 5B                  <1> 	pop	ebx
   254 0000BB7C 9D                  <1> 	popf
   255 0000BB7D C3                  <1> 	retn
   256                              <1> 
   257                              <1> lba_read_ok:
   258 0000BB7E 89C8                <1> 	mov	eax, ecx ; sector number
   259 0000BB80 01F8                <1> 	add	eax, edi ; sector number (next)
   260 0000BB82 C1E709              <1> 	shl	edi, 9 ; sector count * 512
   261 0000BB85 01FB                <1> 	add	ebx, edi ; next buffer offset
   262                              <1> 
   263 0000BB87 8B0D[98D80000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   264 0000BB8D 09C9                <1> 	or	ecx, ecx
   265 0000BB8F 7586                <1> 	jnz	short lba_read_next
   266 0000BB91 EBC7                <1> 	jmp	short lba_read_retn
   267                              <1> 
   268                              <1> lba_read_reset:
   269 0000BB93 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   270 0000BB95 E83A6DFFFF          <1>         call	int13h
   271                              <1> 	; al = ? (changed)
   272                              <1> 	; ah = error code
   273 0000BB9A 7399                <1> 	jnc	short lba_read_retry
   274 0000BB9C EBBC                <1> 	jmp	short lba_read_retn
  1931                                  %include 'trdosk8.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk8.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; XXXXXXXX.ASM (XX/XX/2011)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; u0.s (20/11/2015)
    15                              <1> ; ****************************************************************************
    16                              <1> 
    17                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
    18                              <1> int34h:  ; #IOCTL# (I/O port access support for ring 3)
    19 0000BB9E CF                  <1> 	iretd
    20                              <1> 
    21                              <1> INT4Ah:
    22                              <1> 	; 24/01/2016
    23                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
    24 0000BB9F C3                  <1> 	retn
    25                              <1> 
    26                              <1> ; u0.s
    27                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
    28                              <1> ; Last Modification: 20/11/2015
    29                              <1> 
    30                              <1> com2_int:
    31                              <1> 	; 07/11/2015 
    32                              <1> 	; 24/10/2015
    33                              <1> 	; 23/10/2015
    34                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
    35                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
    36                              <1> 	; < serial port 2 interrupt handler >
    37                              <1> 	;
    38 0000BBA0 890424              <1> 	mov 	[esp], eax ; overwrite call return address
    39                              <1> 	;push	eax
    40 0000BBA3 66B80900            <1> 	mov	ax, 9
    41 0000BBA7 EB07                <1> 	jmp	short comm_int
    42                              <1> com1_int:
    43                              <1> 	; 07/11/2015
    44                              <1> 	; 24/10/2015
    45 0000BBA9 890424              <1> 	mov 	[esp], eax ; overwrite call return address
    46                              <1> 	; 23/10/2015
    47                              <1> 	;push	eax
    48 0000BBAC 66B80800            <1> 	mov	ax, 8
    49                              <1> comm_int:
    50                              <1> 	; 20/11/2015
    51                              <1> 	; 18/11/2015
    52                              <1> 	; 17/11/2015
    53                              <1> 	; 16/11/2015
    54                              <1> 	; 09/11/2015
    55                              <1> 	; 08/11/2015
    56                              <1> 	; 07/11/2015
    57                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
    58                              <1> 	; 01/11/2015
    59                              <1> 	; 26/10/2015
    60                              <1> 	; 23/10/2015
    61 0000BBB0 53                  <1> 	push	ebx
    62 0000BBB1 56                  <1> 	push	esi
    63 0000BBB2 57                  <1> 	push	edi
    64 0000BBB3 1E                  <1> 	push 	ds
    65 0000BBB4 06                  <1> 	push 	es
    66                              <1> 	; 18/11/2015
    67 0000BBB5 0F20DB              <1> 	mov	ebx, cr3
    68 0000BBB8 53                  <1> 	push	ebx ; ****
    69                              <1> 	;
    70 0000BBB9 51                  <1> 	push	ecx ; ***
    71 0000BBBA 52                  <1> 	push	edx ; **
    72                              <1> 	;
    73 0000BBBB BB10000000          <1> 	mov	ebx, KDATA
    74 0000BBC0 8EDB                <1> 	mov	ds, bx
    75 0000BBC2 8EC3                <1> 	mov	es, bx
    76                              <1> 	;
    77 0000BBC4 8B0D[D8CE0000]      <1> 	mov	ecx, [k_page_dir]
    78 0000BBCA 0F22D9              <1> 	mov	cr3, ecx
    79                              <1> 	; 20/11/2015
    80                              <1> 	; Interrupt identification register
    81 0000BBCD 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
    82                              <1> 	;
    83 0000BBD1 3C08                <1> 	cmp 	al, 8 
    84 0000BBD3 7702                <1> 	ja 	short com_i0
    85                              <1> 	;
    86                              <1> 	; 20/11/2015
    87                              <1> 	; 17/11/2015
    88                              <1> 	; 16/11/2015
    89                              <1> 	; 15/11/2015
    90                              <1> 	; 24/10/2015
    91                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
    92                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
    93                              <1> 	; < serial port 1 interrupt handler >
    94                              <1> 	;
    95 0000BBD5 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
    96                              <1> com_i0:
    97                              <1> 	;push	eax ; *
    98                              <1> 	; 07/11/2015
    99 0000BBD7 A2[48CF0000]        <1> 	mov 	byte [ccomport], al
   100                              <1> 	; 09/11/2015
   101 0000BBDC 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
   102                              <1> 	; 17/11/2015
   103                              <1>  	; reset request for response status
   104 0000BBDF 88A3[3ECF0000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   105                              <1> 	;
   106                              <1> 	; 20/11/2015
   107 0000BBE5 EC                  <1> 	in	al, dx		; read interrupt id. register
   108 0000BBE6 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   109 0000BBE8 2404                <1> 	and	al, 4		; received data available?	
   110 0000BBEA 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   111                              <1> 	;
   112                              <1> 	; 20/11/2015
   113 0000BBEC 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   114 0000BBEF EC                  <1> 	in	al, dx     	; read character
   115                              <1> 	;JMP	$+2	   	; I/O DELAY
   116                              <1> 	; 08/11/2015
   117                              <1> 	; 07/11/2015
   118 0000BBF0 89DE                <1> 	mov	esi, ebx 
   119 0000BBF2 89DF                <1> 	mov	edi, ebx
   120 0000BBF4 81C6[42CF0000]      <1> 	add 	esi, rchar - 8 ; points to last received char
   121 0000BBFA 81C7[44CF0000]      <1> 	add	edi, schar - 8 ; points to last sent char
   122 0000BC00 8806                <1> 	mov	[esi], al ; received char (current char)
   123                              <1> 	; query
   124 0000BC02 20C0                <1> 	and	al, al
   125 0000BC04 7527                <1> 	jnz	short com_i2
   126                              <1>    	; response
   127                              <1> 	; 17/11/2015
   128                              <1> 	; set request for response status
   129 0000BC06 FE83[3ECF0000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   130                              <1> 	;
   131 0000BC0C 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   132 0000BC10 EC                  <1> 	in	al, dx	   	; read line status register 
   133 0000BC11 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   134 0000BC13 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   135 0000BC15 7445                <1> 	jz	short com_eoi 	; no
   136 0000BC17 B0FF                <1> 	mov 	al, 0FFh   	; response			
   137 0000BC19 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   138 0000BC1D EE                  <1> 	out	dx, al	   	; send on serial port
   139                              <1> 	; 17/11/2015
   140 0000BC1E 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   141 0000BC21 7502                <1> 	jne 	short com_i1    ; no
   142 0000BC23 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
   143                              <1> com_i1:
   144                              <1> 	; 17/11/2015
   145                              <1> 	; reset request for response status (again)
   146 0000BC25 FE8B[3ECF0000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   147 0000BC2B EB2F                <1> 	jmp	short com_eoi
   148                              <1> com_i2:	
   149                              <1> 	; 08/11/2015
   150 0000BC2D 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   151 0000BC2F 7417                <1> 	je	short com_i3	; (check for response signal)
   152                              <1> 	; 07/11/2015
   153 0000BC31 3C04                <1> 	cmp	al, 04h	; EOT
   154 0000BC33 751C                <1> 	jne	short com_i4	
   155                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
   156                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
   157                              <1> 	; 08/11/2015
   158                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
   159 0000BC35 861D[08CF0000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   160 0000BC3B E85783FFFF          <1> 	call 	ctrlbrk
   161 0000BC40 861D[08CF0000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   162                              <1> 	;mov	al, 04h ; EOT
   163                              <1> 	; 08/11/2015
   164 0000BC46 EB09                <1> 	jmp	short com_i4	
   165                              <1> com_i3:
   166                              <1> 	; 08/11/2015
   167                              <1> 	; If 0FFh has been received just after a query
   168                              <1> 	; (schar, ZERO), it is a response signal.
   169                              <1> 	; 17/11/2015
   170 0000BC48 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   171 0000BC4B 7704                <1> 	ja	short com_i4 ; no
   172                              <1> 	; reset query status (schar)
   173 0000BC4D 8807                <1> 	mov	[edi], al ; 0FFh
   174 0000BC4F FEC0                <1> 	inc	al ; 0
   175                              <1> com_i4:
   176                              <1> 	; 27/07/2014
   177                              <1> 	; 09/07/2014
   178 0000BC51 D0E3                <1> 	shl	bl, 1	
   179 0000BC53 81C3[0ACF0000]      <1> 	add	ebx, ttychr
   180                              <1> 	; 23/07/2014 (always overwrite)
   181                              <1> 	;;cmp	word [ebx], 0
   182                              <1> 	;;ja	short com_eoi
   183                              <1> 	;
   184 0000BC59 668903              <1> 	mov	[ebx], ax   ; Save ascii code
   185                              <1> 			    ; scan code = 0
   186                              <1> com_eoi:
   187                              <1> 	;mov	al, 20h
   188                              <1> 	;out	20h, al	   ; end of interrupt
   189                              <1> 	;
   190                              <1> 	; 07/11/2015
   191                              <1>       	;pop	eax ; *
   192 0000BC5C A0[48CF0000]        <1> 	mov	al, byte [ccomport] ; current COM port
   193                              <1> 	 ; al = tty number (8 or 9)
   194 0000BC61 E85E010000          <1>         call	wakeup
   195                              <1> com_iret:
   196                              <1> 	; 23/10/2015
   197 0000BC66 5A                  <1> 	pop	edx ; **
   198 0000BC67 59                  <1> 	pop	ecx ; ***
   199                              <1> 	; 18/11/2015
   200                              <1> 	;pop	eax ; ****
   201                              <1> 	;mov	cr3, eax
   202                              <1> 	;jmp	iiret
   203 0000BC68 E9F64DFFFF          <1> 	jmp	iiretp
   204                              <1> 
   205                              <1> ;iiretp: ; 01/09/2015
   206                              <1> ;	; 28/08/2015
   207                              <1> ;	pop	eax ; (*) page directory
   208                              <1> ;	mov	cr3, eax
   209                              <1> ;iiret:
   210                              <1> ;	; 22/08/2014
   211                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
   212                              <1> ;	out	20h, al	; 8259 PORT
   213                              <1> ;	;
   214                              <1> ;	pop	es
   215                              <1> ;	pop	ds
   216                              <1> ;	pop	edi
   217                              <1> ;	pop	esi
   218                              <1> ;	pop	ebx ; 29/08/2014
   219                              <1> ;	pop 	eax
   220                              <1> ;	iretd
   221                              <1> 
   222                              <1> sp_init:
   223                              <1> 	; 07/11/2015
   224                              <1> 	; 29/10/2015
   225                              <1> 	; 26/10/2015
   226                              <1> 	; 23/10/2015
   227                              <1> 	; 29/06/2015
   228                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
   229                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
   230                              <1> 	; Initialization of Serial Port Communication Parameters
   231                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   232                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   233                              <1> 	;
   234                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   235                              <1> 	;
   236                              <1> 	; INPUT:  (29/06/2015)
   237                              <1> 	;	AL = 0 for COM1
   238                              <1> 	;	     1 for COM2
   239                              <1> 	;	AH = Communication parameters	
   240                              <1> 	;
   241                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   242                              <1> 	;	Bit	4	3	2	1	0
   243                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   244                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   245                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   246                              <1> 	;		11 = even
   247                              <1> 	;  Baud rate setting bits: (29/06/2015)
   248                              <1> 	;		Retro UNIX 386 v1 feature only !
   249                              <1> 	;	Bit	7    6    5  | Baud rate
   250                              <1> 	;		------------------------
   251                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   252                              <1> 	;		0    0    1  | 9600 (12)
   253                              <1> 	;		0    1    0  | 19200 (6) 
   254                              <1> 	;		0    1	  1  | 38400 (3) 
   255                              <1> 	;		1    0	  0  | 14400 (8)
   256                              <1> 	;		1    0	  1  | 28800 (4)
   257                              <1> 	;		1    1    0  | 57600 (2)
   258                              <1> 	;		1    1    1  | 115200 (1) 	
   259                              <1> 	
   260                              <1> 	; References:	
   261                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
   262                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   263                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
   264                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
   265                              <1> 	;
   266                              <1> 	; Set communication parameters for COM1 (= 03h)	
   267                              <1> 	;
   268 0000BC6D BB[44CF0000]        <1> 	mov	ebx, com1p		; COM1 parameters  
   269 0000BC72 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   270                              <1> 	 ; 29/10/2015
   271 0000BC76 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   272 0000BC7A E86F000000          <1> 	call	sp_i3	; call A4	
   273 0000BC7F A880                <1> 	test	al, 80h
   274 0000BC81 7410                <1> 	jz	short sp_i0 ; OK..
   275                              <1> 		; Error !
   276                              <1> 	;mov	dx, 3F8h
   277 0000BC83 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   278 0000BC86 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   279 0000BC8A E85F000000          <1> 	call	sp_i3	; call A4	
   280 0000BC8F A880                <1> 	test	al, 80h
   281 0000BC91 7508                <1> 	jnz	short sp_i1
   282                              <1> sp_i0:
   283                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
   284                              <1>         ; (INT 14h initialization code disables interrupts.)
   285                              <1> 	;
   286 0000BC93 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   287 0000BC96 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   288                              <1> sp_i1:
   289 0000BC9B 43                  <1> 	inc	ebx
   290 0000BC9C 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   291                              <1> 	 ; 29/10/2015
   292 0000BCA0 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   293 0000BCA4 E845000000          <1> 	call	sp_i3	; call A4	
   294 0000BCA9 A880                <1> 	test	al, 80h
   295 0000BCAB 7410                <1> 	jz	short sp_i2 ; OK..
   296                              <1> 		; Error !
   297                              <1> 	;mov	dx, 2F8h
   298 0000BCAD 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   299 0000BCB0 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   300 0000BCB4 E835000000          <1> 	call	sp_i3	; call A4	
   301 0000BCB9 A880                <1> 	test	al, 80h
   302 0000BCBB 7530                <1> 	jnz	short sp_i7
   303                              <1> sp_i2:
   304 0000BCBD C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   305                              <1> sp_i6:
   306                              <1> 	;; COM2 - enabling IRQ 3
   307                              <1> 	; 07/11/2015
   308                              <1> 	; 26/10/2015
   309 0000BCC0 9C                  <1> 	pushf
   310 0000BCC1 FA                  <1> 	cli
   311                              <1> 	;
   312 0000BCC2 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   313 0000BCC6 EC                  <1> 	in	al, dx 	   		; read register
   314 0000BCC7 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   315 0000BCC9 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   316 0000BCCB EE                  <1> 	out	dx, al     		; write back to register
   317 0000BCCC EB00                <1> 	JMP	$+2	   		; I/O DELAY
   318 0000BCCE 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   319 0000BCD2 EC                  <1> 	in	al, dx     		; read register
   320 0000BCD3 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   321                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   322 0000BCD5 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   323 0000BCD7 EE                  <1> 	out	dx, al 	   		; write back to register
   324 0000BCD8 EB00                <1> 	JMP	$+2        		; I/O DELAY
   325 0000BCDA E421                <1> 	in	al, 21h    		; read interrupt mask register
   326 0000BCDC EB00                <1> 	JMP	$+2	   		; I/O DELAY
   327 0000BCDE 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   328 0000BCE0 E621                <1> 	out	21h, al    		; write back to register
   329                              <1> 	;
   330                              <1> 	; 23/10/2015
   331 0000BCE2 B8[A0BB0000]        <1> 	mov 	eax, com2_int
   332 0000BCE7 A3[BFBD0000]        <1> 	mov	[com2_irq3], eax
   333                              <1> 	; 26/10/2015
   334 0000BCEC 9D                  <1> 	popf	
   335                              <1> sp_i7:
   336 0000BCED C3                  <1> 	retn
   337                              <1> 
   338                              <1> sp_i3:
   339                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   340                              <1> 	; 28/10/2015
   341 0000BCEE FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   342 0000BCF0 B000                <1> 	mov	al, 0
   343 0000BCF2 EE                  <1> 	out	dx, al			; disable serial port interrupt
   344 0000BCF3 EB00                <1> 	JMP	$+2			; I/O DELAY
   345 0000BCF5 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   346 0000BCF8 B080                <1> 	mov	al, 80h			
   347 0000BCFA EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   348                              <1> 	;-----	SET BAUD RATE DIVISOR
   349                              <1> 	; 26/10/2015
   350 0000BCFB 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   351                              <1> 					; of the divisor value
   352 0000BCFE 88C8                <1> 	mov	al, cl	; 1
   353 0000BD00 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   354                              <1> 					; 2 = 57600 baud
   355                              <1> 					; 3 = 38400 baud
   356                              <1> 					; 6 = 19200 baud
   357                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
   358 0000BD01 EB00                <1> 	JMP	$+2			; I/O DELAY
   359 0000BD03 28C0                <1> 	sub	al, al
   360 0000BD05 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   361                              <1> 					; of the divisor value
   362 0000BD07 EE                  <1> 	out	dx, al ; 0
   363 0000BD08 EB00                <1> 	JMP	$+2			; I/O DELAY
   364                              <1> 	;	
   365 0000BD0A 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   366                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
   367 0000BD0C 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   368 0000BD0F EE                  <1> 	out	dx, al			
   369 0000BD10 EB00                <1> 	JMP	$+2			; I/O DELAY
   370                              <1> 	; 29/10/2015
   371 0000BD12 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   372 0000BD14 30C0                <1> 	xor	al, al			; 0
   373 0000BD16 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   374 0000BD17 EB00                <1> 	JMP	$+2	
   375                              <1> sp_i4:
   376                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
   377                              <1> 	; 29/06/2015 (line status after modem status)
   378 0000BD19 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   379                              <1> sp_i4s:
   380 0000BD1C EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   381 0000BD1D EB00                <1> 	JMP	$+2			; I/O DELAY
   382 0000BD1F 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   383 0000BD21 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   384                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   385 0000BD23 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   386                              <1> 	; AL = Line status, AH = Modem status
   387 0000BD24 C3                  <1> 	retn
   388                              <1> 
   389                              <1> sp_status:
   390                              <1> 	; 29/06/2015
   391                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
   392                              <1> 	; Get serial port status
   393 0000BD25 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   394 0000BD29 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   395                              <1> 					; dx = 2FEh for COM2
   396 0000BD2B EBEF                <1> 	jmp	short sp_i4s
   397                              <1> 
   398                              <1> sp_setp: ; Set serial port communication parameters
   399                              <1> 	; 07/11/2015
   400                              <1> 	; 29/10/2015
   401                              <1> 	; 29/06/2015
   402                              <1> 	; Retro UNIX 386 v1 feature only !	
   403                              <1> 	;
   404                              <1> 	; INPUT:
   405                              <1> 	;	AL = 0 for COM1
   406                              <1> 	;	     1 for COM2
   407                              <1> 	;	AH = Communication parameters (*)
   408                              <1> 	; OUTPUT:
   409                              <1> 	;	CL = Line status
   410                              <1> 	;	CH = Modem status
   411                              <1> 	;   If cf = 1 -> Error code in [u.error]
   412                              <1> 	;		 'invalid parameter !' 
   413                              <1> 	;		 	 or
   414                              <1> 	;		 'device not ready !' error
   415                              <1> 	;	
   416                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   417                              <1> 	;	Bit	4	3	2	1	0
   418                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   419                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   420                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   421                              <1> 	;		11 = even
   422                              <1> 	;  Baud rate setting bits: (29/06/2015)
   423                              <1> 	;		Retro UNIX 386 v1 feature only !
   424                              <1> 	;	Bit	7    6    5  | Baud rate
   425                              <1> 	;		------------------------
   426                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   427                              <1> 	;		0    0    1  | 9600 (12)
   428                              <1> 	;		0    1    0  | 19200 (6) 
   429                              <1> 	;		0    1	  1  | 38400 (3) 
   430                              <1> 	;		1    0	  0  | 14400 (8)
   431                              <1> 	;		1    0	  1  | 28800 (4)
   432                              <1> 	;		1    1    0  | 57600 (2)
   433                              <1> 	;		1    1    1  | 115200 (1) 
   434                              <1> 	;
   435                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   436                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   437                              <1> 	;
   438                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   439                              <1> 	;
   440 0000BD2D 66BAF803            <1> 	mov	dx, 3F8h
   441 0000BD31 BB[44CF0000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   442 0000BD36 3C01                <1> 	cmp	al, 1
   443 0000BD38 776B                <1> 	ja 	short sp_invp_err
   444 0000BD3A 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   445 0000BD3C FECE                <1> 	dec	dh ; 2F8h
   446 0000BD3E 43                  <1> 	inc	ebx ; COM2 control byte offset
   447                              <1> sp_setp1:
   448                              <1> 	; 29/10/2015
   449 0000BD3F 8823                <1> 	mov	[ebx], ah
   450 0000BD41 0FB6CC              <1> 	movzx 	ecx, ah
   451 0000BD44 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   452 0000BD47 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   453 0000BD4A 8A81[B4BD0000]      <1> 	mov	al, [ecx+b_div_tbl]
   454 0000BD50 6689C1              <1> 	mov	cx, ax
   455 0000BD53 E896FFFFFF          <1> 	call	sp_i3
   456 0000BD58 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   457 0000BD5B A880                <1> 	test	al, 80h
   458 0000BD5D 740F                <1> 	jz	short sp_setp2
   459 0000BD5F C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   460                              <1> stp_dnr_err:
   461 0000BD62 C705[D5DF0000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   461 0000BD6A 0000                <1>
   462                              <1> 	; CL = Line status, CH = Modem status
   463 0000BD6C F9                  <1> 	stc
   464 0000BD6D C3                  <1> 	retn
   465                              <1> sp_setp2:
   466 0000BD6E 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   467 0000BD71 0F8649FFFFFF        <1>         jna     sp_i6 
   468                              <1> 		      ; COM1 (3F?h)
   469                              <1> sp_i5: 
   470                              <1> 	; 07/11/2015
   471                              <1> 	; 26/10/2015
   472                              <1> 	; 29/06/2015
   473                              <1> 	;
   474                              <1> 	;; COM1 - enabling IRQ 4
   475 0000BD77 9C                  <1> 	pushf
   476 0000BD78 FA                  <1> 	cli
   477 0000BD79 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   478 0000BD7D EC                  <1> 	in	al, dx 	   		; read register
   479 0000BD7E EB00                <1> 	JMP	$+2			; I/O DELAY
   480 0000BD80 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   481 0000BD82 EE                  <1> 	out	dx, al     		; write back to register
   482 0000BD83 EB00                <1> 	JMP	$+2			; I/O DELAY
   483 0000BD85 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   484 0000BD89 EC                  <1> 	in	al, dx     		; read register
   485 0000BD8A EB00                <1> 	JMP	$+2			; I/O DELAY
   486                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   487 0000BD8C 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   488 0000BD8E EE                  <1> 	out	dx, al 	   		; write back to register
   489 0000BD8F EB00                <1> 	JMP	$+2        		; I/O DELAY
   490 0000BD91 E421                <1> 	in	al, 21h    		; read interrupt mask register
   491 0000BD93 EB00                <1> 	JMP	$+2			; I/O DELAY
   492 0000BD95 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   493 0000BD97 E621                <1> 	out	21h, al    		; write back to register
   494                              <1> 	;
   495                              <1> 	; 23/10/2015
   496 0000BD99 B8[A9BB0000]        <1> 	mov 	eax, com1_int
   497 0000BD9E A3[BBBD0000]        <1> 	mov	[com1_irq4], eax
   498                              <1> 	; 26/10/2015
   499 0000BDA3 9D                  <1> 	popf
   500 0000BDA4 C3                  <1> 	retn
   501                              <1> 
   502                              <1> sp_invp_err:
   503 0000BDA5 C705[D5DF0000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   503 0000BDAD 0000                <1>
   504 0000BDAF 31C9                <1> 	xor	ecx, ecx
   505 0000BDB1 49                  <1> 	dec	ecx ; 0FFFFh
   506 0000BDB2 F9                  <1> 	stc
   507 0000BDB3 C3                  <1> 	retn
   508                              <1> 
   509                              <1> ; 29/10/2015
   510                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   511 0000BDB4 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   512                              <1> 
   513                              <1> 
   514                              <1> ; 23/10/2015
   515                              <1> com1_irq4:
   516 0000BDBB [C3BD0000]          <1> 	dd dummy_retn
   517                              <1> com2_irq3:
   518 0000BDBF [C3BD0000]          <1> 	dd dummy_retn
   519                              <1> 
   520                              <1> dummy_retn:
   521 0000BDC3 C3                  <1> 	retn
   522                              <1> 
   523                              <1> wakeup:
   524                              <1> 	; 24/01/2016
   525 0000BDC4 C3                  <1> 	retn
  1932                                  %include 'trdosk9.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - INITIALIZED DATA : trdosk9.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 07/05/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; ----------------------------------------------------------------------------
     9                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
    10                              <1> ; ----------------------------------------------------------------------------
    11                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    12                              <1> ; TRDOS2.ASM (09/11/2011)
    13                              <1> ; ****************************************************************************
    14                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
    15                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
    16                              <1> ; CMD_INTR.ASM [29/01/2005] Last Update: 09/11/2011
    17                              <1> ; FILE.ASM [29/10/2009] Last Update: 09/10/2011
    18                              <1> 
    19                              <1> ; 12/02/2016
    20                              <1> Last_DOS_DiskNo: 
    21 0000BDC5 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 0000BDC6 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 0000BDC7 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 0000BDCB 04                  <1> 		db 4
    31 0000BDCC 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 0000BDCD 07                  <1> 		db 7
    34 0000BDCE 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.070516"
    34 0000BDD7 61696E2050726F6772- <1>
    34 0000BDE0 616D2076322E302E30- <1>
    34 0000BDE9 3730353136          <1>
    35 0000BDEE 0D0A                <1> 		db 0Dh, 0Ah
    36 0000BDF0 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
    36 0000BDF9 616E2054616E203230- <1>
    36 0000BE02 30352D32303136      <1>
    37 0000BE09 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile: ; 14/04/2016
    40 0000BE0C 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 0000BE15 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 0000BE19 5452444F53          <1> 		db "TRDOS"
    44 0000BE1E 00                  <1> 		db 0
    45 0000BE1F 00<rept>            <1>                 times 5 db 0
    46 0000BE24 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 0000BE25 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 0000BE29 434400              <1> Cmd_Cd:		db "CD", 0
    52 0000BE2C 433A00              <1> Cmd_Drive:	db "C:", 0
    53 0000BE2F 56455200            <1> Cmd_Ver:	db "VER", 0
    54 0000BE33 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 0000BE38 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 0000BE3F 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 0000BE46 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 0000BE4F 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 0000BE54 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 0000BE59 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 0000BE5D 53455400            <1> Cmd_Set:	db "SET", 0 
    62 0000BE61 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 0000BE65 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 0000BE6A 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 0000BE6E 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 0000BE75 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 0000BE7C 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 0000BE82 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 0000BE88 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 0000BE8D 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 0000BE92 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 0000BE97 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 0000BE9B 00                  <1> 		db 0
    74 0000BE9C 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 0000BEA1 5245414446494C4500  <1> Cmd_ReadFile:	db "READFILE", 0
    76 0000BEAA 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    77 0000BEAF 2A00                <1> Cmd_Remark:	db "*", 0
    78 0000BEB1 3F00                <1> Cmd_Help:	db "?", 0
    79 0000BEB3 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    80 0000BEBA 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    81 0000BEC2 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    82 0000BEC8 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    83                              <1> 		
    84 0000BECD 00                  <1> 		db 0
    85                              <1> 
    86                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    87                              <1> invalid_fname_chars:
    88 0000BECE 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    89 0000BED6 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    90 0000BEDD 5B5C5D5E60          <1> 		db 5Bh, 5Ch, 5Dh, 5Eh, 60h
    91                              <1> sizeInvFnChars  equ ($ - invalid_fname_chars)                
    92                              <1> ;
    93                              <1> 
    94                              <1> Msg_Enter_Date:
    95 0000BEE2 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    95 0000BEEB 206461746520286464- <1>
    95 0000BEF4 2D6D6D2D7979293A20  <1>
    96 0000BEFD 00                  <1>                 db 0
    97                              <1> Msg_Show_Date:
    98 0000BEFE 43757272656E742064- <1>                 db   'Current date is '
    98 0000BF07 61746520697320      <1>
    99 0000BF0E 30                  <1> Day:            db   '0'
   100 0000BF0F 30                  <1> 		db   '0'
   101 0000BF10 2F                  <1>                 db   '/'
   102 0000BF11 30                  <1> Month:          db   '0'
   103 0000BF12 30                  <1> 		db   '0'
   104 0000BF13 2F                  <1>                 db   '/'
   105 0000BF14 30                  <1> Century:        db   '0'
   106 0000BF15 30                  <1>                 db   '0'
   107 0000BF16 30                  <1> Year:           db   '0'
   108 0000BF17 30                  <1> 		db   '0'
   109 0000BF18 0D0A00              <1>                 db   0Dh, 0Ah, 0
   110                              <1> 
   111                              <1> Msg_Enter_Time:
   112 0000BF1B 456E746572206E6577- <1> 		db 'Enter new time: '
   112 0000BF24 2074696D653A20      <1>
   113 0000BF2B 00                  <1> 		db 0
   114                              <1> Msg_Show_Time:
   115 0000BF2C 43757272656E742074- <1> 		db   'Current time is '
   115 0000BF35 696D6520697320      <1>
   116 0000BF3C 30                  <1> Hour:           db   '0'
   117 0000BF3D 30                  <1> 		db   '0'
   118 0000BF3E 3A                  <1> 		db   ':'
   119 0000BF3F 30                  <1> Minute:         db   '0'
   120 0000BF40 30                  <1> 		db   '0'
   121 0000BF41 3A                  <1> 		db   ':'
   122 0000BF42 30                  <1> Second:         db   '0'
   123 0000BF43 30                  <1> 		db   '0'
   124 0000BF44 0D0A00              <1> 		db   0Dh, 0Ah, 0
   125                              <1> 
   126                              <1> ;VolSize_Unit1:   dd 0
   127                              <1> ;VolSize_Unit2:   dd 0
   128                              <1> 
   129                              <1> VolSize_KiloBytes:
   130 0000BF47 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   130 0000BF50 730D0A00            <1>
   131                              <1> VolSize_Bytes:
   132 0000BF54 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   133                              <1> Volume_in_drive:
   134 0000BF5D 0D0A                <1> 		db 0Dh, 0Ah
   135                              <1> Vol_FS_Name:
   136 0000BF5F 54522046533120      <1> 		db "TR FS1 "
   137 0000BF66 566F6C756D6520696E- <1> 		db "Volume in drive "
   137 0000BF6F 20647269766520      <1>
   138 0000BF76 30                  <1> Vol_Drv_Name:   db 30h
   139 0000BF77 3A                  <1> 		db ":"
   140 0000BF78 20697320            <1> 		db " is "
   141 0000BF7C 0D0A00              <1> 		db 0Dh, 0Ah, 0
   142                              <1> Dir_Drive_Str:
   143 0000BF7F 54522D444F53204472- <1>                 db "TR-DOS Drive "
   143 0000BF88 69766520            <1>
   144                              <1> Dir_Drive_Name:
   145 0000BF8C 303A                <1>                 db "0:"
   146 0000BF8E 0D0A                <1>                 db  0Dh, 0Ah
   147                              <1> Vol_Str_Header:
   148 0000BF90 566F6C756D65204E61- <1>                 db "Volume Name: "
   148 0000BF99 6D653A20            <1>
   149                              <1> Vol_Name:
   150 0000BF9D 00<rept>            <1> 		times 64 db 0
   151 0000BFDD 00                  <1> 		db 0
   152                              <1> Vol_Serial_Header:
   153 0000BFDE 0D0A                <1> 		db 0Dh, 0Ah
   154 0000BFE0 566F6C756D65205365- <1> 		db "Volume Serial No: "
   154 0000BFE9 7269616C204E6F3A20  <1>
   155                              <1> Vol_Serial1:
   156 0000BFF2 30303030            <1> 		db "0000"
   157 0000BFF6 2D                  <1> 		db "-"
   158                              <1> Vol_Serial2:
   159 0000BFF7 30303030            <1> 		db "0000"
   160 0000BFFB 0D0A00              <1> 		db 0Dh, 0Ah, 0
   161                              <1> 
   162                              <1> ;Vol_Tot_Sec_Str_Start:
   163                              <1> ;		dd 0
   164                              <1> Vol_Total_Sector_Header:
   165 0000BFFE 0D0A                <1> 		db 0Dh, 0Ah
   166 0000C000 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   166 0000C009 7A65203A2000        <1>
   167                              <1> ;Vol_Tot_Sec_Str: 
   168                              <1> ;		db "0000000000"
   169                              <1> ;Vol_Tot_Sec_Str_End:
   170                              <1> ;		db 0
   171                              <1> ;Vol_Free_Sectors_Str_Start:
   172                              <1> ;		dd 0
   173                              <1> Vol_Free_Sectors_Header:
   174 0000C00F 467265652053706163- <1> 		db "Free Space  : ", 0
   174 0000C018 6520203A2000        <1>
   175                              <1> ;Vol_Free_Sectors_Str:
   176                              <1> ;		db "0000000000"
   177                              <1> ;Vol_Free_Sectors_Str_End:
   178                              <1> ;		db 0
   179                              <1> 
   180                              <1> Dir_Str_Header:
   181 0000C01E 4469726563746F7279- <1>                 db "Directory: "
   181 0000C027 3A20                <1>
   182 0000C029 2F                  <1> Dir_Str_Root:   db "/"
   183 0000C02A 00<rept>            <1> Dir_Str:        times 64 db 0
   184 0000C06A 00000000            <1>                 dd 0
   185 0000C06E 00                  <1>                 db 0
   186                              <1> 
   187                              <1> Msg_Bad_Command:
   188 0000C06F 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   188 0000C078 6E64206F722066696C- <1>
   188 0000C081 65206E616D6521      <1>
   189 0000C088 0D0A00              <1>                 db 0Dh, 0Ah, 0
   190                              <1> 
   191                              <1> msgl_drv_not_ready: 
   192 0000C08B 070D0A              <1> 		db 07h, 0Dh, 0Ah
   193                              <1> 
   194                              <1> ; CMD_INTR.ASM - 09/11/2011 - Messages
   195                              <1> 
   196                              <1> Msg_Not_Ready_Read_Err:
   197 0000C08E 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   197 0000C097 207265616479206F72- <1>
   197 0000C0A0 207265616420657272- <1>
   197 0000C0A9 6F7221              <1>
   198 0000C0AC 0D0A00              <1>                 db 0Dh, 0Ah, 0
   199                              <1> 
   200                              <1> Msg_Not_Ready_Write_Err:
   201 0000C0AF 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   201 0000C0B8 207265616479206F72- <1>
   201 0000C0C1 207772697465206572- <1>
   201 0000C0CA 726F7221            <1>
   202 0000C0CE 0D0A00              <1>                 db 0Dh, 0Ah, 0
   203                              <1> 
   204                              <1> Msg_Dir_Not_Found:
   205 0000C0D1 4469726563746F7279- <1>                 db "Directory not found!"
   205 0000C0DA 206E6F7420666F756E- <1>
   205 0000C0E3 6421                <1>
   206 0000C0E5 0D0A00              <1>                 db 0Dh, 0Ah, 0
   207                              <1> 
   208                              <1> Msg_File_Not_Found:
   209 0000C0E8 46696C65206E6F7420- <1>                 db "File not found!"
   209 0000C0F1 666F756E6421        <1>
   210 0000C0F7 0D0A00              <1>                 db 0Dh, 0Ah, 0
   211                              <1> 
   212                              <1> Msg_File_Directory_Not_Found:
   213 0000C0FA 46696C65206F722064- <1>                 db "File or directory not found!"
   213 0000C103 69726563746F727920- <1>
   213 0000C10C 6E6F7420666F756E64- <1>
   213 0000C115 21                  <1>
   214 0000C116 0D0A00              <1>                 db 0Dh, 0Ah, 0
   215                              <1> 
   216                              <1> Msg_LongName_Not_Found:
   217 0000C119 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   217 0000C122 206E6F7420666F756E- <1>
   217 0000C12B 6421                <1>
   218 0000C12D 0D0A00              <1>                 db 0Dh, 0Ah, 0
   219                              <1> 
   220                              <1> Msg_Insufficient_Memory:
   221 0000C130 496E73756666696369- <1>                 db "Insufficient memory!"
   221 0000C139 656E74206D656D6F72- <1>
   221 0000C142 7921                <1>
   222 0000C144 0D0A00              <1>                 db 0Dh, 0Ah, 0
   223                              <1> 
   224                              <1> Msg_Error_Code:
   225 0000C147 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   225 0000C150 61696C656421204572- <1>
   225 0000C159 726F7220636F646520- <1>
   225 0000C162 3A20                <1>
   226 0000C164 303068              <1> error_code_hex: db '00h'
   227 0000C167 0A0A00              <1>                 db 0Ah, 0Ah, 0
   228                              <1> 
   229                              <1> align 2
   230                              <1> 
   231                              <1> ; 10/02/2016
   232                              <1> ; DIR.ASM - 09/10/2011
   233                              <1> 
   234 0000C16A 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   234 0000C173 20                  <1>
   235                              <1> 
   236                              <1> File_Name:
   237 0000C174 20<rept>            <1>                 times 12 db 20h
   238 0000C180 20                  <1> 		db 20h
   239                              <1> Dir_Or_FileSize:
   240 0000C181 20<rept>            <1>                 times 10 db 20h
   241 0000C18B 20                  <1> 		db 20h
   242                              <1> File_Attribute:
   243 0000C18C 20202020            <1> 		dd 20202020h
   244 0000C190 20                  <1> 		db 20h
   245                              <1> File_Day:
   246 0000C191 3030                <1>                 db '0','0'
   247 0000C193 2F                  <1> 		db '/'
   248                              <1> File_Month:
   249 0000C194 3030                <1>                 db '0','0'
   250 0000C196 2F                  <1> 		db '/'
   251                              <1> File_Year:
   252 0000C197 30303030            <1>                 db '0','0','0','0'
   253 0000C19B 20                  <1> 		db 20h
   254                              <1> File_Hour:
   255 0000C19C 3030                <1>                 db '0','0'
   256 0000C19E 3A                  <1> 		db ':'
   257                              <1> File_Minute:
   258 0000C19F 3030                <1>                 db '0','0'
   259 0000C1A1 00                  <1> 		db 0
   260                              <1> 
   261                              <1> Decimal_File_Count_Header:
   262 0000C1A2 0D0A                <1> 		db 0Dh, 0Ah
   263                              <1> Decimal_File_Count:
   264 0000C1A4 00<rept>            <1> 		times 6 db 0
   265                              <1> 
   266 0000C1AA 2066696C6528732920- <1> str_files:	db " file(s) & "
   266 0000C1B3 2620                <1>
   267                              <1> Decimal_Dir_Count: 
   268 0000C1B5 00<rept>            <1> 		times 6 db 0
   269                              <1> str_dirs:       
   270 0000C1BB 206469726563746F72- <1> 		db " directory(s) "
   270 0000C1C4 7928732920          <1>
   271 0000C1C9 0D0A00              <1> 		db 0Dh, 0Ah, 0
   272                              <1> 
   273 0000C1CC 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   273 0000C1D5 696E2066696C652873- <1>
   273 0000C1DE 29                  <1>
   274 0000C1DF 0D0A00              <1> 		db 0Dh, 0Ah, 0
   275                              <1> 
   276                              <1> ; CMD_INTR.ASM - 09/11/2011
   277                              <1> ; 07/10/2010
   278                              <1> Msg_invalid_name_chars:
   279 0000C1E2 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   279 0000C1EB 696C65206F72206469- <1>
   279 0000C1F4 726563746F7279206E- <1>
   279 0000C1FD 616D65206368617261- <1>
   279 0000C206 637465727321        <1>
   280 0000C20C 0D0A00              <1>         	db 0Dh, 0Ah, 0
   281                              <1> ; 21/02/2016
   282 0000C20F 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   282 0000C218 69726563746F727920- <1>
   282 0000C221 6E616D652065786973- <1>
   282 0000C22A 747321              <1>
   283 0000C22D 0D0A00              <1>                 db 0Dh, 0Ah, 0
   284                              <1> Msg_DoYouWantMkdir:
   285 0000C230 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   285 0000C239 6E7420746F206D616B- <1>
   285 0000C242 65206469726563746F- <1>
   285 0000C24B 72792000            <1>
   286 0000C24F 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   286 0000C258 00                  <1>
   287 0000C259 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   288 0000C25D 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   289                              <1> 
   290                              <1> ; 27/02/2016
   291                              <1> Msg_DoYouWantRmDir:
   292 0000C263 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   292 0000C26C 6E7420746F2064656C- <1>
   292 0000C275 657465206469726563- <1>
   292 0000C27E 746F72792000        <1>
   293                              <1> Msg_Dir_Not_Empty:
   294 0000C284 4469726563746F7279- <1>                 db "Directory not empty!"
   294 0000C28D 206E6F7420656D7074- <1>
   294 0000C296 7921                <1>
   295 0000C298 0D0A00              <1>                 db 0Dh, 0Ah, 0
   296                              <1> 
   297                              <1> Msg_DoYouWantDelete:
   298 0000C29B 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   298 0000C2A4 6E7420746F2064656C- <1>
   298 0000C2AD 6574652066696C6520- <1>
   298 0000C2B6 00                  <1>
   299                              <1> 
   300 0000C2B7 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   300 0000C2C0 2E0D0A00            <1>
   301                              <1> 
   302                              <1> Msg_Permission_Denied:
   303 0000C2C4 07                  <1>                 db 7
   304 0000C2C5 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   304 0000C2CE 6E2064656E69656421- <1>
   304 0000C2D7 0D0A00              <1>
   305                              <1> 
   306                              <1> ; 04/03/2016
   307 0000C2DA 4E657720            <1> Msg_New:        db "New "
   308 0000C2DE 00                  <1>                 db 0
   309                              <1> Str_Attributes:
   310 0000C2DF 417474726962757465- <1>                 db "Attributes : "
   310 0000C2E8 73203A20            <1>
   311 0000C2EC 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   312 0000C2F2 00                  <1>                 db 0
   313                              <1> 
   314                              <1> ; 06/03/2016
   315                              <1> ; CMD_INTR.ASM - 16/11/2010 
   316                              <1> Msg_DoYouWantRename:
   317 0000C2F3 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   317 0000C2FC 6E7420746F2072656E- <1>
   317 0000C305 616D652000          <1>
   318 0000C30A 66696C652000        <1> Rename_File:    db "file ", 0
   319 0000C310 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   319 0000C319 2000                <1>
   320 0000C31B 00<rept>            <1> Rename_OldName: times 13 db 0
   321 0000C328 20617320            <1> Msg_File_rename_as: db " as "
   322 0000C32C 00<rept>            <1> Rename_NewName: times 13 db 0
   323                              <1> 
   324                              <1> ; 08/03/2016
   325                              <1> ; CMD_INTR.ASM - 01/08/2010 - 23/04/2011
   326                              <1> msg_not_same_drv:
   327 0000C339 4E6F742073616D6520- <1>                 db "Not same drive!" 
   327 0000C342 647269766521        <1>
   328 0000C348 0D0A00              <1>                 db 0Dh, 0Ah, 0 
   329                              <1> 
   330                              <1> Msg_DoYouWantMoveFile:
   331 0000C34B 446F20796F75207761- <1>                 db "Do you want to move file", 0
   331 0000C354 6E7420746F206D6F76- <1>
   331 0000C35D 652066696C6500      <1>
   332                              <1> 
   333                              <1> msg_insufficient_disk_space:
   334 0000C364 496E73756666696369- <1>                 db "Insufficient disk space!" 
   334 0000C36D 656E74206469736B20- <1>
   334 0000C376 737061636521        <1>
   335 0000C37C 0D0A00              <1>                 db 0Dh, 0Ah, 0
   336                              <1> 
   337                              <1> ; 01/08/2010
   338                              <1> msg_source_file: 
   339 0000C37F 0D0A536F7572636520- <1> 		db 0Dh, 0Ah, "Source file name      :   "
   339 0000C388 66696C65206E616D65- <1>
   339 0000C391 2020202020203A2020- <1>
   339 0000C39A 20                  <1>
   340                              <1> msg_source_file_drv: 
   341 0000C39B 203A00              <1> 		db " :", 0
   342                              <1> msg_destination_file: 
   343 0000C39E 0D0A44657374696E61- <1> 		db 0Dh, 0Ah, "Destination file name :   "
   343 0000C3A7 74696F6E2066696C65- <1>
   343 0000C3B0 206E616D65203A2020- <1>
   343 0000C3B9 20                  <1>
   344                              <1> msg_destination_file_drv: 
   345 0000C3BA 203A00              <1> 		db " :", 0
   346                              <1> msg_copy_nextline: 
   347 0000C3BD 0D0A00              <1> 		db 0Dh, 0Ah, 0
   348                              <1> 
   349                              <1> ; 15/03/2016
   350                              <1> ; CMD_INTR.ASM
   351                              <1> 
   352                              <1> Msg_DoYouWantOverWriteFile:
   353 0000C3C0 446F20796F75207761- <1>                 db "Do you want to overwrite file ",0
   353 0000C3C9 6E7420746F206F7665- <1>
   353 0000C3D2 727772697465206669- <1>
   353 0000C3DB 6C652000            <1>
   354                              <1>   
   355                              <1> Msg_DoYouWantCopyFile:
   356 0000C3DF 446F20796F75207761- <1>                 db "Do you want to copy file",0
   356 0000C3E8 6E7420746F20636F70- <1>
   356 0000C3F1 792066696C6500      <1>
   357                              <1> 
   358                              <1> Msg_read_file_error_before_EOF:
   359 0000C3F8 46696C652072656164- <1> 		db "File reading error! (before EOF)"
   359 0000C401 696E67206572726F72- <1>
   359 0000C40A 2120286265666F7265- <1>
   359 0000C413 20454F4629          <1>
   360 0000C418 0A0A00              <1> 		db 0Ah, 0Ah, 0
   361                              <1> 
   362                              <1> ; 18/03/2016
   363                              <1> ; TRDOS 386 (v2.0) mainprog copy procedure
   364                              <1> msg_reading:
   365 0000C41B 52656164696E672E2E- <1> 		db "Reading... ", 0
   365 0000C424 2E2000              <1>
   366                              <1> msg_writing:
   367 0000C427 57726974696E672E2E- <1> 		db "Writing... ", 0
   367 0000C430 2E2000              <1>
   368                              <1> percentagestr:
   369 0000C433 2020202500          <1> 		db "   %", 0  ; "  0%" .. "100%"
   370                              <1> ; 11/04/2016
   371                              <1> Msg_No_Set_Space:
   372 0000C438 496E73756666696369- <1>                 db "Insufficient environment space!"
   372 0000C441 656E7420656E766972- <1>
   372 0000C44A 6F6E6D656E74207370- <1>
   372 0000C453 61636521            <1>
   373 0000C457 0D0A00              <1>                 db 0Dh, 0Ah, 0
   374                              <1> ; 18/04/2016
   375                              <1> isc_msg:	
   376 0000C45A 0D0A                <1> 		db 0Dh, 0Ah
   377 0000C45C 494E56414C49442053- <1> 		db "INVALID SYSTEM CALL", 0
   377 0000C465 595354454D2043414C- <1>
   377 0000C46E 4C00                <1>
   378                              <1> usi_msg:
   379 0000C470 0D0A                <1> 		db 0Dh, 0Ah
   380 0000C472 554E444546494E4544- <1> 		db "UNDEFINED SOFTWARE INTERRUPT", 0
   380 0000C47B 20534F465457415245- <1>
   380 0000C484 20494E544552525550- <1>
   380 0000C48D 5400                <1>
   381                              <1> ifc_msg:
   382 0000C48F 0D0A                <1> 		db 0Dh, 0Ah
   383 0000C491 494E56414C49442046- <1> 		db "INVALID FUNCTION CALL"
   383 0000C49A 554E4354494F4E2043- <1>
   383 0000C4A3 414C4C              <1>
   384                              <1> inv_msg_for_trdos_v2:
   385 0000C4A6 20                  <1> 		db 20h
   386 0000C4A7 666F72205452444F53- <1> 		db "for TRDOS v2!"
   386 0000C4B0 20763221            <1>
   387 0000C4B4 07                  <1> 		db 07h
   388 0000C4B5 0D0A                <1> 		db 0Dh, 0Ah
   389 0000C4B7 0D0A                <1> 		db 0Dh, 0Ah
   390 0000C4B9 494E5420            <1> 		db "INT "
   391 0000C4BD 303068              <1> int_num_str:	db "00h"
   392 0000C4C0 0D0A                <1> 		db 0Dh, 0Ah
   393 0000C4C2 454158203A20        <1> 		db "EAX : "
   394 0000C4C8 303030303030303068- <1> eax_str:	db "00000000h", 0Dh, 0Ah
   394 0000C4D1 0D0A                <1>
   395 0000C4D3 454950203A20        <1> 		db "EIP : "
   396 0000C4D9 303030303030303068- <1> eip_str:	db "00000000h", 0Dh, 0Ah, 0
   396 0000C4E2 0D0A00              <1>
   397                              <1> 		
  1933                                  
  1934                                  ; 15/04/2016
  1935                                  ; TRDOS 386 (TRDOS v2.0)
  1936                                  
  1937                                  ; 29/04/2016
  1938                                  int30h:
  1939                                  trdos_isc_routine:
  1940                                  	; 02/05/2016
  1941                                  	; 01/05/2016
  1942                                  	; 29/04/2016
  1943                                  	; 18/04/2016
  1944                                  	; 15/04/2016 (TRDOS 386 = TRDOS v2.0)
  1945                                  	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
  1946                                  	; 03/02/2011 ('trdos_ifc_routine')
  1947                                  	;
  1948 0000C4E5 8B1C24                  	mov	ebx, [esp] ; EIP (next)
  1949 0000C4E8 83EB02                  	sub	ebx, 2 ; EIP (CD ##h)
  1950                                  
  1951 0000C4EB 89C1                    	mov	ecx, eax
  1952 0000C4ED 8A4301                  	mov	al, [ebx+1] ; CDh ##h
  1953                                  
  1954 0000C4F0 66BA1000                	mov	dx, KDATA
  1955 0000C4F4 8EDA                    	mov	ds, dx
  1956 0000C4F6 8EC2                    	mov	es, dx
  1957                                  
  1958 0000C4F8 FC                      	cld
  1959 0000C4F9 8B15[D8CE0000]          	mov	edx, [k_page_dir]
  1960 0000C4FF 0F22DA                  	mov	cr3, edx
  1961                                  
  1962 0000C502 E8A854FFFF              	call	bytetohex
  1963 0000C507 66A3[BDC40000]          	mov	[int_num_str], ax
  1964                                  
  1965 0000C50D 89D8                    	mov	eax, ebx ; EIP
  1966 0000C50F E8DB54FFFF              	call	dwordtohex
  1967 0000C514 8915[D9C40000]          	mov	[eip_str], edx
  1968 0000C51A A3[DDC40000]            	mov	[eip_str+4], eax
  1969                                  
  1970 0000C51F 89C8                    	mov	eax, ecx
  1971 0000C521 E8C954FFFF              	call	dwordtohex
  1972 0000C526 8915[C8C40000]          	mov	[eax_str], edx
  1973 0000C52C A3[CCC40000]            	mov	[eax_str+4], eax 	
  1974                                  
  1975 0000C531 43                      	inc	ebx
  1976 0000C532 8A03                    	mov	al, [ebx] ; Interrupt number
  1977                                  
  1978                                  trdos_isc_handler:
  1979 0000C534 80FE30                  	cmp	dh, 30h ; Retro UNIX, SINGLIX System calls
  1980 0000C537 7507                    	jne	short trdos_usi_handler
  1981 0000C539 BE[5AC40000]            	mov	esi, isc_msg
  1982 0000C53E EB05                    	jmp	short loc_write_inv_system_call_msg
  1983                                  
  1984                                  trdos_usi_handler:
  1985 0000C540 BE[70C40000]            	mov	esi, usi_msg
  1986                                  
  1987                                  loc_write_inv_system_call_msg:
  1988 0000C545 E8D579FFFF              	call	print_msg
  1989                                  	; 29/04/2016
  1990 0000C54A BE[A6C40000]            	mov	esi, inv_msg_for_trdos_v2
  1991 0000C54F E8CB79FFFF              	call	print_msg
  1992                                  
  1993                                  loc_ifc_terminate_process:
  1994                                  	; u.uno = process number
  1995                                  	; 29/04/2016
  1996                                  
  1997                                  	; 02/05/2016
  1998 0000C554 FE05[77DF0000]          	inc	byte [sysflg] ; 0FFh -> 0
  1999                                  
  2000 0000C55A B801000000              	mov	eax, 1
  2001 0000C55F E989DBFFFF              	jmp	sysexit
  2002                                  
  2003                                  ; 07/03/2015
  2004                                  ; Temporary Code
  2005                                  display_disks:
  2006 0000C564 803D[6EC90000]00        	cmp 	byte [fd0_type], 0
  2007 0000C56B 7605                    	jna 	short ddsks1
  2008 0000C56D E87D000000              	call	pdskm
  2009                                  ddsks1:
  2010 0000C572 803D[6FC90000]00        	cmp	byte [fd1_type], 0
  2011 0000C579 760C                    	jna	short ddsks2
  2012 0000C57B C605[65CB0000]31        	mov	byte [dskx], '1'
  2013 0000C582 E868000000              	call	pdskm
  2014                                  ddsks2:
  2015 0000C587 803D[70C90000]00        	cmp	byte [hd0_type], 0
  2016 0000C58E 7654                    	jna	short ddsk6
  2017 0000C590 66C705[63CB0000]68-     	mov	word [dsktype], 'hd'
  2017 0000C598 64                 
  2018 0000C599 C605[65CB0000]30        	mov	byte [dskx], '0'
  2019 0000C5A0 E84A000000              	call	pdskm
  2020                                  ddsks3:
  2021 0000C5A5 803D[71C90000]00        	cmp	byte [hd1_type], 0
  2022 0000C5AC 7636                    	jna	short ddsk6
  2023 0000C5AE C605[65CB0000]31        	mov	byte [dskx], '1'
  2024 0000C5B5 E835000000              	call	pdskm
  2025                                  ddsks4:
  2026 0000C5BA 803D[72C90000]00        	cmp	byte [hd2_type], 0
  2027 0000C5C1 7621                    	jna	short ddsk6
  2028 0000C5C3 C605[65CB0000]32        	mov	byte [dskx], '2'
  2029 0000C5CA E820000000              	call	pdskm
  2030                                  ddsks5:
  2031 0000C5CF 803D[73C90000]00        	cmp	byte [hd3_type], 0
  2032 0000C5D6 760C                    	jna	short ddsk6
  2033 0000C5D8 C605[65CB0000]33        	mov	byte [dskx], '3'
  2034 0000C5DF E80B000000              	call	pdskm
  2035                                  ddsk6:
  2036 0000C5E4 BE[76CB0000]            	mov	esi, nextline
  2037 0000C5E9 E806000000              	call	pdskml
  2038                                  pdskm_ok:
  2039 0000C5EE C3                      	retn
  2040                                  pdskm:
  2041 0000C5EF BE[61CB0000]            	mov	esi, dsk_ready_msg
  2042                                  pdskml:	
  2043 0000C5F4 AC                      	lodsb
  2044 0000C5F5 08C0                    	or	al, al
  2045 0000C5F7 74F5                    	jz	short pdskm_ok
  2046 0000C5F9 56                      	push	esi
  2047 0000C5FA 31DB                    	xor	ebx, ebx ; 0
  2048                                  			; Video page 0 (bl=0)
  2049 0000C5FC B407                    	mov	ah, 07h ; Black background, 
  2050                                  			; light gray forecolor
  2051 0000C5FE E8BC51FFFF              	call	WRITE_TTY
  2052 0000C603 5E                      	pop	esi
  2053 0000C604 EBEE                    	jmp	short pdskml
  2054                                  
  2055 0000C606 90<rept>                align 16
  2056                                  
  2057                                  gdt:	; Global Descriptor Table
  2058                                  	; (30/07/2015, conforming cs)
  2059                                  	; (26/03/2015)
  2060                                  	; (24/03/2015, tss)
  2061                                  	; (19/03/2015)
  2062                                  	; (29/12/2013)
  2063                                  	;
  2064 0000C610 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  2065                                  	; 18/08/2014
  2066                                  			; 8h kernel code segment, base = 00000000h		
  2067 0000C618 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2068                                  			; 10h kernel data segment, base = 00000000h	
  2069 0000C620 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2070                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2071 0000C628 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  2072                                  			; 23h user data segment, base address = 400000h ; CORE
  2073 0000C630 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2074                                  			; Task State Segment
  2075 0000C638 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2076                                  			       ;  no IO permission in ring 3)
  2077                                  gdt_tss0:
  2078 0000C63A 0000                    	dw 0  ; TSS base address, bits 0-15 
  2079                                  gdt_tss1:
  2080 0000C63C 00                      	db 0  ; TSS base address, bits 16-23 
  2081                                  	      		; 49h	
  2082 0000C63D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2083 0000C63E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2084                                  gdt_tss2:
  2085 0000C63F 00                      	db 0  ; TSS base address, bits 24-31 
  2086                                  
  2087                                  gdt_end:
  2088                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2089                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2090                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2091                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2092                                  
  2093                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2094                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2095                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2096                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2097                                  		; W= Writeable, A= Accessed
  2098                                  	
  2099                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2100                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2101                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2102                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2103                                  
  2104                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2105                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2106                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2107                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2108                                  	
  2109                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2110                                  
  2111                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2112                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2113                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2114                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2115                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2116                                  		; AVL= Available to programmers	
  2117                                  
  2118                                  gdtd:
  2119 0000C640 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2120 0000C642 [10C60000]                      dd gdt			; Address of the GDT
  2121                                  
  2122                                  	; 20/08/2014
  2123                                  idtd:
  2124 0000C646 7F02                            dw idt_end - idt - 1    ; Limit (size)
  2125 0000C648 [F0CB0000]                      dd idt			; Address of the IDT
  2126                                  
  2127                                  Align 4
  2128                                  	; 15/04/2016
  2129                                  	; TRDOS 386 (TRDOS v2.0)
  2130                                  
  2131                                  	; 21/08/2014
  2132                                  ilist:
  2133                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  2134                                  	;
  2135                                  	; Exception list
  2136                                  	; 25/08/2014	
  2137 0000C64C [DB080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2138 0000C650 [E2080000]              	dd	exc1	
  2139 0000C654 [E9080000]              	dd 	exc2	
  2140 0000C658 [F0080000]              	dd	exc3	
  2141 0000C65C [F4080000]              	dd	exc4	
  2142 0000C660 [F8080000]              	dd	exc5	
  2143 0000C664 [FC080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2144 0000C668 [00090000]              	dd	exc7	
  2145 0000C66C [04090000]              	dd	exc8	
  2146 0000C670 [08090000]              	dd	exc9	
  2147 0000C674 [0C090000]              	dd 	exc10	
  2148 0000C678 [10090000]              	dd	exc11
  2149 0000C67C [14090000]              	dd	exc12
  2150 0000C680 [18090000]              	dd	exc13	; 0Dh, General Protection Fault
  2151 0000C684 [1C090000]              	dd 	exc14	; 0Eh, Page Fault
  2152 0000C688 [20090000]              	dd	exc15
  2153 0000C68C [24090000]              	dd	exc16
  2154 0000C690 [28090000]              	dd	exc17
  2155 0000C694 [2C090000]              	dd 	exc18
  2156 0000C698 [30090000]              	dd	exc19
  2157 0000C69C [34090000]              	dd 	exc20
  2158 0000C6A0 [38090000]              	dd	exc21
  2159 0000C6A4 [3C090000]              	dd	exc22
  2160 0000C6A8 [40090000]              	dd	exc23
  2161 0000C6AC [44090000]              	dd 	exc24
  2162 0000C6B0 [48090000]              	dd	exc25
  2163 0000C6B4 [4C090000]              	dd	exc26
  2164 0000C6B8 [50090000]              	dd	exc27
  2165 0000C6BC [54090000]              	dd 	exc28
  2166 0000C6C0 [58090000]              	dd	exc29
  2167 0000C6C4 [5C090000]              	dd 	exc30
  2168 0000C6C8 [60090000]              	dd	exc31
  2169                                  	; Interrupt list
  2170 0000C6CC [11070000]              	dd	timer_int	; INT 20h
  2171                                  		;dd	irq0	
  2172 0000C6D0 [B50D0000]              	dd	kb_int		; 24/01/2016
  2173                                  		;dd	irq1
  2174 0000C6D4 [31080000]              	dd	irq2
  2175                                  		; COM2 int
  2176 0000C6D8 [35080000]              	dd	irq3
  2177                                  		; COM1 int
  2178 0000C6DC [40080000]              	dd	irq4
  2179 0000C6E0 [4B080000]              	dd	irq5
  2180                                  ;DISKETTE_INT: ;06/02/2015
  2181 0000C6E4 [7F280000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  2182                                  		;dd	irq6
  2183                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2184                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2185 0000C6E8 [CF0B0000]              	dd	default_irq7	; 25/02/2015
  2186                                  		;dd	irq7
  2187                                  ; Real Time Clock Interrupt
  2188 0000C6EC [720A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2189                                  		;dd	irq8	; INT 28h
  2190 0000C6F0 [5B080000]              	dd	irq9
  2191 0000C6F4 [5F080000]              	dd	irq10
  2192 0000C6F8 [63080000]              	dd	irq11
  2193 0000C6FC [67080000]              	dd	irq12
  2194 0000C700 [6B080000]              	dd	irq13
  2195                                  ;HDISK_INT1:  ;06/02/2015 	
  2196 0000C704 [C2300000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2197                                  		;dd	irq14
  2198                                  ;HDISK_INT2:  ;06/02/2015
  2199 0000C708 [E9300000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  2200                                  		;dd	irq15	; INT 2Fh
  2201                                  		; 14/08/2015
  2202                                  	;dd	sysent		; INT 30h (system calls)
  2203                                  
  2204                                  	; 15/04/2016
  2205                                  	; TRDOS 386(TRDOS v2.0) Software Interrupts
  2206                                  
  2207 0000C70C [E5C40000]              	dd	int30h		; Reserved for
  2208                                  				; !!! Retro UNIX (RUNIX) !!!
  2209                                  				; !!! SINGLIX !!! System Calls
  2210 0000C710 [A8140000]              	dd	int31h		; Video BIOS (IBM PC/AT, Int 10h)
  2211 0000C714 [F70B0000]              	dd	int32h		; Keyboard Functions (IBM PC/AT, Int 16h)
  2212 0000C718 [33290000]              	dd	int33h		; DISK I/O (IBM PC/AT, Int 13h)
  2213 0000C71C [9EBB0000]              	dd	int34h		; #IOCTL# (I/O port access support for ring 3)
  2214 0000C720 [743B0000]              	dd	int35h		; Time/Date Functions (IBM PC/AT, Int 1Ah)
  2215 0000C724 [310A0000]              	dd	ignore_int	; INT 36h : Timer Functions	
  2216 0000C728 [310A0000]              	dd	ignore_int	; INT 37h	
  2217 0000C72C [310A0000]              	dd	ignore_int	; INT 38h
  2218 0000C730 [310A0000]              	dd	ignore_int	; INT 39h
  2219 0000C734 [310A0000]              	dd	ignore_int	; INT 3Ah	
  2220 0000C738 [310A0000]              	dd	ignore_int	; INT 3Bh
  2221 0000C73C [310A0000]              	dd	ignore_int	; INT 3Ch
  2222 0000C740 [310A0000]              	dd	ignore_int	; INT 3Dh	
  2223 0000C744 [310A0000]              	dd	ignore_int	; INT 3Eh
  2224 0000C748 [310A0000]              	dd	ignore_int	; INT 3Fh
  2225 0000C74C [E89E0000]              	dd	sysent		; INT 40h : !!! TRDOS 386 System Calls !!!
  2226                                  	;dd	ignore_int
  2227 0000C750 00000000                	dd	0
  2228                                  ;;;
  2229                                  ;;; 11/03/2015
  2230                                  %include 'kybdata.s'	; KEYBOARD (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - kybdata.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 17/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 17/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; kybdata.inc (11/03/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - KYBDATA.INC
    20                              <1> ; Last Modification: 11/03/2015
    21                              <1> ;		 (Data Section for 'KEYBOARD.INC')	
    22                              <1> ;
    23                              <1> ; ///////// KEYBOARD DATA ///////////////
    24                              <1> 
    25                              <1> ; 05/12/2014
    26                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-) 
    27                              <1> ; 03/06/86  KEYBOARD BIOS
    28                              <1> 
    29                              <1> ;---------------------------------------------------------------------------------
    30                              <1> ;	KEY IDENTIFICATION SCAN TABLES
    31                              <1> ;---------------------------------------------------------------------------------
    32                              <1> 
    33                              <1> ;-----	TABLES FOR ALT CASE ------------
    34                              <1> ;-----	ALT-INPUT-TABLE 
    35 0000C754 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000C759 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 0000C75E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 0000C764 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000C76A 202122232425        <1> 	db	32,33,34,35,36,37
    41 0000C770 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000C776 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000C778 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000C779 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 0000C77E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 0000C780 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 0000C781 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000C786 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000C788 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 0000C78E 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 0000C794 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000C79A 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 0000C7A0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000C7A6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 0000C7AC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 0000C7B2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000C7B8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 0000C7BE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 0000C7C2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000C7C8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 0000C7CE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 0000C7D4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 0000C7DA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 0000C7E0 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 0000C7E9 39302D3D0809        <1>
    76 0000C7EF 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 0000C7F8 705B5D0DFF61736466- <1>
    76 0000C801 67686A6B6C3B27      <1>
    77 0000C808 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 0000C811 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 0000C81A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 0000C81F 4041424344          <1> 	db	64,65,66,67,68
    81 0000C824 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 0000C826 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 0000C82C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 0000C833 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000C838 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 0000C841 28295F2B0800        <1>
    90 0000C847 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 0000C850 507B7D0DFF41534446- <1>
    90 0000C859 47484A4B4C3A22      <1>
    91 0000C860 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000C869 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 0000C872 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000C877 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 0000C87C FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 0000C87E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000C887 3233302E            <1>
    99                              <1> 	;
   100 0000C88B FFFF7C8788          <1> 	db	-1,-1,124,135,136	; SysRq, Undef, WT, F11, F12
   101                              <1> 
   102                              <1> ; 26/08/2014
   103                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (03/03/2014)
   104                              <1> ; Derived from IBM "pc-at" 
   105                              <1> ; rombios source code (06/10/1985)
   106                              <1> ; 'dseg.inc'
   107                              <1> 
   108                              <1> ;---------------------------------------;
   109                              <1> ;	SYSTEM DATA AREA		;
   110                              <1> ;----------------------------------------
   111 0000C890 00                  <1> BIOS_BREAK	db	0		; BIT 7=1 IF BREAK KEY HAS BEEN PRESSED
   112                              <1> 
   113                              <1> ;----------------------------------------
   114                              <1> ;	KEYBOARD DATA AREAS		;
   115                              <1> ;----------------------------------------
   116                              <1> 
   117 0000C891 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 0000C892 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 0000C893 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 0000C894 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 0000C895 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000C896 [A6C80000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000C89A [C6C80000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 0000C89E [A6C80000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 0000C8A2 [A6C80000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000C8A6 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
   128                              <1> 
   129                              <1> ; /// End Of KEYBOARD DATA ///
  2231                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - vidata.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; vidata.inc (11/03/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.S
    20                              <1> ; Last Modification: 11/03/2015
    21                              <1> ;		    (Data section for 'VIDEO.INC')	
    22                              <1> ;
    23                              <1> ; ///////// VIDEO DATA ///////////////
    24                              <1> 
    25                              <1> ;-----	COLUMNS
    26                              <1> ;M6:
    27                              <1> ;	db	40, 40, 80, 80, 40, 40, 80, 80
    28                              <1> 
    29                              <1> ;-----	C_REG_TAB
    30                              <1> ;M7:
    31                              <1> ;	db	2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 29h	; TABLE OF MODE SETS
    32                              <1> 
    33                              <1> ;----------------------------------------
    34                              <1> ;	VIDEO DISPLAY DATA AREA		;
    35                              <1> ;----------------------------------------
    36 0000C8C6 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
    37 0000C8C7 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
    38                              <1> 				; (29h default setting for video mode 3)
    39                              <1> 				; Mode Select register Bits
    40                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
    41                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
    42                              <1> 				;   BIT 2 - COLOR (0), BW (1)
    43                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
    44                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
    45                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
    46                              <1> 				;   BIT 6, 7 - Not Used
    47                              <1> 
    48                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
    49                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
    50                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
    51                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
    52                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
    53                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
    54                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
    55                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
    56                              <1> ; Mode & 37h = Video signal OFF
    57                              <1> 			
    58                              <1> video_params:
    59                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
    60                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
    61                              <1> 	; VIDEO MODE 3
    62 0000C8C8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
    63 0000C8CF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
    64 0000C8D4 00000000            <1> 	db	0,0,0,0
    65                              <1> 
    66                              <1> ; 16/01/2016
    67                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
    68 0000C8D8 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    69                              <1> ; 30/01/2016
    70                              <1> vmode:
    71 0000C8E0 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    72                              <1> 
    73                              <1> ; /// End Of VIDEO DATA ///
  2232                                  %include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskdata.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskdata.inc (11/03/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKDATA.INC
    20                              <1> ; Last Modification: 11/03/2015
    21                              <1> ;	(Initialized Disk Parameters Data section for 'DISKIO.INC') 
    22                              <1> ;
    23                              <1> 
    24                              <1> ;----------------------------------------
    25                              <1> ;	80286 INTERRUPT LOCATIONS	:
    26                              <1> ;	REFERENCED BY POST & BIOS	:
    27                              <1> ;----------------------------------------
    28                              <1> 
    29 0000C8E8 [4BC90000]          <1> DISK_POINTER:	dd	MD_TBL6		; Pointer to Diskette Parameter Table
    30                              <1> 
    31                              <1> ; IBM PC-XT Model 286 source code ORGS.ASM (06/10/85) - 14/12/2014
    32                              <1> ;----------------------------------------------------------------
    33                              <1> ; DISK_BASE							:
    34                              <1> ;	THIS IS THE SET OF PARAMETERS REQUIRED FOR		:
    35                              <1> ;	DISKETTE OPERATION. THEY ARE POINTED AT BY THE		:
    36                              <1> ;	DATA VARIABLE @DISK_POINTER. TO MODIFY THE PARAMETERS,	:
    37                              <1> ;	BUILD ANOTHER PARAMETER BLOCK AND POINT AT IT		:
    38                              <1> ;----------------------------------------------------------------
    39                              <1> 
    40                              <1> ;DISK_BASE:	
    41                              <1> ;	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
    42                              <1> ;	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
    43                              <1> ;	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
    44                              <1> ;	DB	2		; 512 BYTES/SECTOR
    45                              <1> ;	;DB	15		; EOT (LAST SECTOR ON TRACK)
    46                              <1> ;	db	18		; (EOT for 1.44MB diskette)
    47                              <1> ;	DB	01BH		; GAP LENGTH
    48                              <1> ;	DB	0FFH		; DTL
    49                              <1> ;	;DB	054H		; GAP LENGTH FOR FORMAT
    50                              <1> ;	db	06ch		; (for 1.44MB dsikette)
    51                              <1> ;	DB	0F6H		; FILL BYTE FOR FORMAT
    52                              <1> ;	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
    53                              <1> ;	DB	8		; MOTOR START TIME (1/8 SECONDS)
    54                              <1> 
    55                              <1> ;----------------------------------------
    56                              <1> ;	ROM BIOS DATA AREAS		:
    57                              <1> ;----------------------------------------
    58                              <1> 
    59                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
    60                              <1> 
    61                              <1> ;@EQUIP_FLAG	DW	?		; INSTALLED HARDWARE FLAGS
    62                              <1> 
    63                              <1> ;----------------------------------------
    64                              <1> ;	DISKETTE DATA AREAS		:
    65                              <1> ;----------------------------------------
    66                              <1> 
    67                              <1> ;@SEEK_STATUS	DB	?		; DRIVE RECALIBRATION STATUS
    68                              <1> ;					; BIT 3-0 = DRIVE 3-0 RECALIBRATION
    69                              <1> ;					; BEFORE NEXT SEEK IF BIT IS = 0
    70                              <1> ;@MOTOR_STATUS	DB	?		; MOTOR STATUS
    71                              <1> ;					; BIT 3-0 = DRIVE 3-0 CURRENTLY RUNNING
    72                              <1> ;					; BIT 7 = CURRENT OPERATION IS A WRITE
    73                              <1> ;@MOTOR_COUNT	DB	?		; TIME OUT COUNTER FOR MOTOR(S) TURN OFF
    74                              <1> ;@DSKETTE_STATUS DB	?		; RETURN CODE STATUS BYTE
    75                              <1> ;					; CMD_BLOCK  IN STACK FOR DISK OPERATION
    76                              <1> ;@NEC_STATUS	DB	7 DUP(?)	; STATUS BYTES FROM DISKETTE OPERATION
    77                              <1> 
    78                              <1> ;----------------------------------------
    79                              <1> ;	POST AND BIOS WORK DATA AREA	:
    80                              <1> ;----------------------------------------
    81                              <1> 
    82                              <1> ;@INTR_FLAG	DB	?		; FLAG INDICATING AN INTERRUPT HAPPENED
    83                              <1> 
    84                              <1> ;----------------------------------------
    85                              <1> ;	TIMER DATA AREA 		:
    86                              <1> ;----------------------------------------
    87                              <1> 
    88                              <1> ; 17/12/2014  (IRQ 0 - INT 08H)
    89                              <1> ;TIMER_LOW	equ	46Ch		; Timer ticks (counter)  @ 40h:006Ch
    90                              <1> ;TIMER_HIGH	equ	46Eh		; (18.2 timer ticks per second)
    91                              <1> ;TIMER_OFL	equ	470h		; Timer - 24 hours flag  @ 40h:0070h
    92                              <1> 
    93                              <1> ;----------------------------------------
    94                              <1> ;	ADDITIONAL MEDIA DATA		:
    95                              <1> ;----------------------------------------
    96                              <1> 
    97                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
    98                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
    99                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
   100                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
   101                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
   102                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
   103                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
   104                              <1> 
   105                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
   106                              <1> 
   107                              <1> ;--------------------------------------------------------
   108                              <1> ;	DRIVE TYPE TABLE				:
   109                              <1> ;--------------------------------------------------------
   110                              <1> 		; 16/02/2015 (unix386.s, 32 bit modifications)
   111                              <1> DR_TYPE:
   112 0000C8EC 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 0000C8ED [0AC90000]          <1> 		dd	MD_TBL1
   115 0000C8F1 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000C8F2 [17C90000]          <1>                 dd      MD_TBL2
   118 0000C8F6 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 0000C8F7 [24C90000]          <1> 		dd      MD_TBL3
   121 0000C8FB 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 0000C8FC [31C90000]          <1> 		dd      MD_TBL4
   124 0000C900 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000C901 [3EC90000]          <1> 		dd      MD_TBL5
   127 0000C905 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 0000C906 [4BC90000]          <1> 		dd      MD_TBL6
   130                              <1> DR_TYPE_E       equ $                   ; END OF TABLE
   131                              <1> ;DR_CNT		EQU	(DR_TYPE_E-DR_TYPE)/3
   132                              <1> DR_CNT		equ	(DR_TYPE_E-DR_TYPE)/5
   133                              <1> ;--------------------------------------------------------
   134                              <1> ;	MEDIA/DRIVE PARAMETER TABLES			:
   135                              <1> ;--------------------------------------------------------
   136                              <1> ;--------------------------------------------------------
   137                              <1> ;	360 KB MEDIA IN 360 KB DRIVE			:
   138                              <1> ;--------------------------------------------------------
   139                              <1> MD_TBL1:        
   140 0000C90A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 0000C90B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 0000C90C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 0000C90D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000C90E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000C90F 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000C910 FF                  <1> 	DB	0FFH		; DTL
   147 0000C911 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000C912 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000C913 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 0000C914 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 0000C915 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 0000C916 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
   153                              <1> ;--------------------------------------------------------
   154                              <1> ;	360 KB MEDIA IN 1.2 MB DRIVE			:
   155                              <1> ;--------------------------------------------------------
   156                              <1> MD_TBL2:        
   157 0000C917 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 0000C918 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 0000C919 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 0000C91A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 0000C91B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 0000C91C 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 0000C91D FF                  <1> 	DB	0FFH		; DTL
   164 0000C91E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000C91F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000C920 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000C921 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000C922 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000C923 40                  <1> 	DB	RATE_300	; DATA TRANSFER RATE
   170                              <1> ;--------------------------------------------------------
   171                              <1> ;	1.2 MB MEDIA IN 1.2 MB DRIVE			:
   172                              <1> ;--------------------------------------------------------
   173                              <1> MD_TBL3:
   174 0000C924 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 0000C925 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 0000C926 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 0000C927 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 0000C928 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 0000C929 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 0000C92A FF                  <1> 	DB	0FFH		; DTL
   181 0000C92B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 0000C92C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 0000C92D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000C92E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000C92F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000C930 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
   187                              <1> ;--------------------------------------------------------
   188                              <1> ;	720 KB MEDIA IN 720 KB DRIVE			:
   189                              <1> ;--------------------------------------------------------
   190                              <1> MD_TBL4:
   191 0000C931 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000C932 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000C933 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 0000C934 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 0000C935 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 0000C936 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 0000C937 FF                  <1> 	DB	0FFH		; DTL
   198 0000C938 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 0000C939 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 0000C93A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 0000C93B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 0000C93C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 0000C93D 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
   204                              <1> ;--------------------------------------------------------
   205                              <1> ;	720 KB MEDIA IN 1.44 MB DRIVE			:
   206                              <1> ;--------------------------------------------------------
   207                              <1> MD_TBL5:
   208 0000C93E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000C93F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000C940 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000C941 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000C942 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000C943 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 0000C944 FF                  <1> 	DB	0FFH		; DTL
   215 0000C945 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 0000C946 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 0000C947 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 0000C948 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 0000C949 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 0000C94A 80                  <1> 	DB	RATE_250	; DATA TRANSFER RATE
   221                              <1> ;--------------------------------------------------------
   222                              <1> ;	1.44 MB MEDIA IN 1.44 MB DRIVE			:
   223                              <1> ;--------------------------------------------------------
   224                              <1> MD_TBL6:
   225 0000C94B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 0000C94C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 0000C94D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 0000C94E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 0000C94F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 0000C950 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 0000C951 FF                  <1> 	DB	0FFH		; DTL
   232 0000C952 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 0000C953 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 0000C954 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 0000C955 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 0000C956 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 0000C957 00                  <1> 	DB	RATE_500	; DATA TRANSFER RATE
   238                              <1> 
   239                              <1> 
   240                              <1> ; << diskette.inc >>
   241                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   242                              <1> ;
   243                              <1> ;----------------------------------------
   244                              <1> ;	ROM BIOS DATA AREAS		:
   245                              <1> ;----------------------------------------
   246                              <1> 
   247                              <1> ;DATA		SEGMENT AT 40H		; ADDRESS= 0040:0000
   248                              <1> 
   249                              <1> ;----------------------------------------
   250                              <1> ;	FIXED DISK DATA AREAS		:
   251                              <1> ;----------------------------------------
   252                              <1> 
   253                              <1> ;DISK_STATUS1:	DB	0		; FIXED DISK STATUS
   254                              <1> ;HF_NUM:		DB	0		; COUNT OF FIXED DISK DRIVES
   255                              <1> ;CONTROL_BYTE:	DB	0		; HEAD CONTROL BYTE
   256                              <1> ;@PORT_OFF	DB	?		;  RESERVED (PORT OFFSET)
   257                              <1> 
   258                              <1> ;----------------------------------------
   259                              <1> ;	ADDITIONAL MEDIA DATA		:
   260                              <1> ;----------------------------------------
   261                              <1> 
   262                              <1> ;@LASTRATE	DB	?		; LAST DISKETTE DATA RATE SELECTED
   263                              <1> ;HF_STATUS	DB	0		; STATUS REGISTER
   264                              <1> ;HF_ERROR	DB	0		; ERROR REGISTER
   265                              <1> ;HF_INT_FLAG	DB	0		; FIXED DISK INTERRUPT FLAG
   266                              <1> ;HF_CNTRL	DB	0		; COMBO FIXED DISK/DISKETTE CARD BIT 0=1
   267                              <1> ;@DSK_STATE	DB	?		; DRIVE 0 MEDIA STATE
   268                              <1> ;		DB	?		; DRIVE 1 MEDIA STATE
   269                              <1> ;		DB	?		; DRIVE 0 OPERATION START STATE
   270                              <1> ;		DB	?		; DRIVE 1 OPERATION START STATE
   271                              <1> ;@DSK_TRK	DB	?		; DRIVE 0 PRESENT CYLINDER
   272                              <1> ;		DB	?		; DRIVE 1 PRESENT CYLINDER
   273                              <1> 
   274                              <1> ;DATA		ENDS			; END OF BIOS DATA SEGMENT
   275                              <1> ;
   276                              <1> ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   277                              <1> 
   278                              <1> ERR_TBL:
   279 0000C958 E0                  <1> 	db	NO_ERR
   280 0000C959 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 0000C95D 04BB100A            <1> 	db	RECORD_NOT_FND,UNDEF_ERR,BAD_ECC,BAD_SECTOR
   282                              <1> 
   283                              <1> ; 17/12/2014 (mov ax, [cfd])
   284                              <1> ; 11/12/2014
   285 0000C961 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 0000C962 01                  <1> pfd:		db 1			; previous floppy drive (for GET_PARM)
   288                              <1> 					; (initial value of 'pfd 
   289                              <1> 					; must be different then 'cfd' value
   290                              <1> 					; to force updating/initializing
   291                              <1> 					; current drive parameters) 
   292 0000C963 90                  <1> align 2
   293                              <1> 
   294 0000C964 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 0000C966 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 0000C968 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2233                                  ;;;
  2234                                  
  2235 0000C969 90                      Align 2
  2236                                  
  2237                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2238 0000C96A 00                      boot_drv:    db 0 ; boot drive number (physical)
  2239                                  ; 24/11/2014
  2240 0000C96B 00                      drv:	     db 0 
  2241 0000C96C 00                      last_drv:    db 0 ; last hdd
  2242 0000C96D 00                      hdc:         db 0  ; number of hard disk drives
  2243                                  		     ; (present/detected)
  2244                                  ;
  2245                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2246                                  ; Physical drive type & flags
  2247 0000C96E 00                      fd0_type:    db 0  ; floppy drive type
  2248 0000C96F 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2249                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2250                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2251                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2252                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2253 0000C970 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  2254 0000C971 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  2255 0000C972 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  2256 0000C973 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
  2257                                  		     ; bit 0 - Fixed disk access subset supported
  2258                                  		     ; bit 1 - Drive locking and ejecting
  2259                                  		     ; bit 2 - Enhanced disk drive support
  2260                                  		     ; bit 3 = Reserved (64 bit EDD support)
  2261                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  2262                                  		     ; will interpret it as 'LBA ready'!)		
  2263                                  
  2264                                  ; 11/03/2015 - 10/07/2015
  2265 0000C974 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  2265 0000C97D 0000000000         
  2266 0000C982 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  2266 0000C98B 0000000000         
  2267 0000C990 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  2267 0000C999 0000000000         
  2268 0000C99E 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2268 0000C9A7 000000000000000000-
  2268 0000C9B0 000000000000000000-
  2268 0000C9B9 00                 
  2269 0000C9BA 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2270 0000C9C1 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
  2271                                  ;
  2272                                  
  2273                                  ; 27/08/2014
  2274                                  scr_row:
  2275 0000C9C8 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2276                                  scr_col:
  2277 0000C9CC 00000000                	dd 0
  2278                                  
  2279                                  ; 20/08/2014
  2280                                    ; /* This is the default interrupt "handler" :-) */ 
  2281                                    ; Linux v0.12 (head.s)
  2282                                  int_msg:
  2283 0000C9D0 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2283 0000C9D9 6E7465727275707420-
  2283 0000C9E2 212000             
  2284                                  
  2285                                  ; 21/08/2014
  2286                                  timer_msg:
  2287 0000C9E5 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
  2287 0000C9EE 542032306829202120-
  2287 0000C9F7 54696D657220496E74-
  2287 0000CA00 657272757074203A20 
  2288                                  tcountstr:
  2289 0000CA09 303030303020            	db "00000 "
  2290 0000CA0F 00                      	db 0
  2291                                  
  2292                                  Align 2
  2293                                  	; 21/08/2014
  2294                                  exc_msg:
  2295 0000CA10 435055206578636570-     	db "CPU exception ! "
  2295 0000CA19 74696F6E202120     
  2296                                  excnstr: 		; 25/08/2014
  2297 0000CA20 3F3F68202045495020-     	db "??h", "  EIP : "
  2297 0000CA29 3A20               
  2298                                  EIPstr: ; 29/08/2014
  2299 0000CA2B 00<rept>                	times 12 db 0
  2300                                  rtc_msg:
  2301 0000CA37 5265616C2054696D65-     	db "Real Time Clock - "
  2301 0000CA40 20436C6F636B202D20 
  2302                                  datestr:
  2303 0000CA49 30302F30302F303030-     	db "00/00/0000"
  2303 0000CA52 30                 
  2304 0000CA53 20                      	db " "
  2305                                  daystr:
  2306 0000CA54 44415920                	db "DAY "
  2307                                  timestr:	
  2308 0000CA58 30303A30303A3030                db "00:00:00"
  2309 0000CA60 20                      	db " "
  2310 0000CA61 00                      	db 0 
  2311                                  
  2312                                  daytmp:
  2313                                  	; 28/02/2015
  2314 0000CA62 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
  2314 0000CA6B 4F4E20545545205745-
  2314 0000CA74 442054485520465249-
  2314 0000CA7D 2053415420         
  2315                                  
  2316 0000CA82 FF                      ptime_seconds: db 0FFh
  2317                                  
  2318                                  	; 23/02/2015
  2319                                  	; 25/08/2014
  2320                                  ;scounter:
  2321                                  ;	db 5
  2322                                  ;	db 19
  2323                                  
  2324                                  ; 05/11/2014
  2325                                  msg_out_of_memory:
  2326 0000CA83 070D0A                  	db 	07h, 0Dh, 0Ah
  2327 0000CA86 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2327 0000CA8F 656E74206D656D6F72-
  2327 0000CA98 79202120284D696E69-
  2327 0000CAA1 6D756D2032204D4220-
  2327 0000CAAA 6D656D6F7279206973-
  2327 0000CAB3 206E65656465642E29 
  2328 0000CABC 0D0A00                   	db	0Dh, 0Ah, 0
  2329                                  	;
  2330                                  setup_error_msg:
  2331 0000CABF 0D0A                    	db 0Dh, 0Ah
  2332 0000CAC1 4469736B2053657475-     	db 'Disk Setup Error!' 
  2332 0000CACA 70204572726F7221   
  2333 0000CAD2 0D0A00                  	db 0Dh, 0Ah,0
  2334                                  
  2335                                  ; 06/11/2014
  2336                                  ; Memory Information message
  2337                                  ; 14/08/2015
  2338                                  msg_memory_info:
  2339 0000CAD5 07                      	db	07h
  2340 0000CAD6 0D0A                    	db	0Dh, 0Ah
  2341                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2342 0000CAD8 546F74616C206D656D-     	db	"Total memory : "
  2342 0000CAE1 6F7279203A20       
  2343                                  mem_total_b_str: ; 10 digits
  2344 0000CAE7 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2344 0000CAF0 302062797465730D0A 
  2345 0000CAF9 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2345 0000CB02 202020202020202020 
  2346                                  mem_total_p_str: ; 7 digits
  2347 0000CB0B 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2347 0000CB14 616765730D0A       
  2348 0000CB1A 0D0A                    	db 	0Dh, 0Ah
  2349 0000CB1C 46726565206D656D6F-     	db	"Free memory  : "
  2349 0000CB25 727920203A20       
  2350                                  free_mem_b_str:  ; 10 digits
  2351 0000CB2B 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2351 0000CB34 3F2062797465730D0A 
  2352 0000CB3D 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2352 0000CB46 202020202020202020 
  2353                                  free_mem_p_str:  ; 7 digits
  2354 0000CB4F 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2354 0000CB58 616765730D0A       
  2355 0000CB5E 0D0A00                  	db	0Dh, 0Ah, 0
  2356                                  
  2357                                  dsk_ready_msg:
  2358 0000CB61 0D0A                    	db 	0Dh, 0Ah
  2359                                  dsktype:
  2360 0000CB63 6664                    	db	'fd'
  2361                                  dskx:
  2362 0000CB65 30                      	db	'0'
  2363 0000CB66 20                      	db	20h
  2364 0000CB67 697320524541445920-     	db 	'is READY ...'
  2364 0000CB70 2E2E2E             
  2365 0000CB73 00                      	db 	0
  2366                                  
  2367                                  next2line: ; 08/02/2016
  2368 0000CB74 0D0A                    	db	0Dh, 0Ah
  2369                                  nextline:
  2370 0000CB76 0D0A00                  	db 	0Dh, 0Ah, 0
  2371                                  
  2372                                  ; KERNEL - SYSINIT Messages
  2373                                  ; 24/08/2015
  2374                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  2375                                  ; 14/07/2013
  2376                                  ;kernel_init_err_msg:
  2377                                  ;	db 0Dh, 0Ah
  2378                                  ;	db 07h
  2379                                  ;	db 'Kernel initialization ERROR !'
  2380                                  ;	db 0Dh, 0Ah, 0 
  2381                                  
  2382                                  ;welcome_msg: 
  2383                                  ;	db 0Dh, 0Ah
  2384                                  ;	db 07h
  2385                                  ;	db 'Welcome to TRDOS 386 Operating System !'
  2386                                  ;	db 0Dh, 0Ah
  2387                                  ;	db 'by Erdogan Tan - 07/05/2016 (v2.0.0)'
  2388                                  ;	db 0Dh, 0Ah, 0
  2389                                  
  2390                                  panic_msg:
  2391 0000CB79 0D0A07                  	db 0Dh, 0Ah, 07h
  2392 0000CB7C 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2392 0000CB85 726E656C2050616E69-
  2392 0000CB8E 632021             
  2393 0000CB91 0D0A00                  	db 0Dh, 0Ah, 0
  2394                                  
  2395                                  align 2
  2396                                  
  2397                                  ; EPOCH Variables
  2398                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  2399                                  ; 09/04/2013 epoch variables
  2400                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  2401                                  ;
  2402 0000CB94 B207                    year: 	dw 1970
  2403 0000CB96 0100                    month: 	dw 1
  2404 0000CB98 0100                    day: 	dw 1
  2405 0000CB9A 0000                    hour: 	dw 0
  2406 0000CB9C 0000                    minute: dw 0
  2407 0000CB9E 0000                    second: dw 0
  2408                                  
  2409                                  DMonth:
  2410 0000CBA0 0000                    	dw 0
  2411 0000CBA2 1F00                    	dw 31
  2412 0000CBA4 3B00                    	dw 59
  2413 0000CBA6 5A00                    	dw 90
  2414 0000CBA8 7800                    	dw 120
  2415 0000CBAA 9700                    	dw 151
  2416 0000CBAC B500                    	dw 181
  2417 0000CBAE D400                    	dw 212
  2418 0000CBB0 F300                    	dw 243
  2419 0000CBB2 1101                    	dw 273
  2420 0000CBB4 3001                    	dw 304
  2421 0000CBB6 4E01                    	dw 334
  2422                                  
  2423                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2424 0000CBB8 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2425                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2426 0000CBBA 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2427                                  		   ;   between 16 MB and 4 GB.
  2428                                  
  2429                                  starting_msg:
  2430 0000CBBC 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [07/05/2016] ...", 0
  2430 0000CBC5 6174696F6E616C2044-
  2430 0000CBCE 4F532076322E30205B-
  2430 0000CBD7 30372F30352F323031-
  2430 0000CBE0 365D202E2E2E00     
  2431                                  NextLine:
  2432 0000CBE7 0D0A00                  	db 0Dh, 0Ah, 0
  2433                                  
  2434                                  ;msgl_drv_not_ready: 
  2435                                  ;	db 07h, 0Dh, 0Ah
  2436                                  ;       db 'Drive not ready or read error !'
  2437                                  ;       db 0Dh, 0Ah, 0
  2438                                  
  2439 0000CBEA 90<rept>                align 16
  2440                                  
  2441                                  bss_start:
  2442                                  
  2443                                  ABSOLUTE bss_start
  2444                                  
  2445                                  	; 15/04/2016
  2446                                  	; TRDOS 386 (TRDOS v2.0)
  2447                                  	; 	80 interrupts 	
  2448                                  	; 11/03/2015
  2449                                  	; Interrupt Descriptor Table (20/08/2014)
  2450                                  idt:
  2451                                  	;resb	64*8 ; INT 0 to INT 3Fh
  2452                                  	; 15/04/2016
  2453 0000CBF0 <res 00000280>          	resb	80*8 ; INT 0 to INT 4Fh
  2454                                  
  2455                                  idt_end:
  2456                                  
  2457                                  ;alignb 4
  2458                                  
  2459                                  task_state_segment:
  2460                                  	; 24/03/2015
  2461 0000CE70 <res 00000002>          tss.link:   resw 1
  2462 0000CE72 <res 00000002>          	    resw 1
  2463                                  ; tss offset 4	
  2464 0000CE74 <res 00000004>          tss.esp0:   resd 1
  2465 0000CE78 <res 00000002>          tss.ss0:    resw 1
  2466 0000CE7A <res 00000002>          	    resw 1	
  2467 0000CE7C <res 00000004>          tss.esp1:   resd 1
  2468 0000CE80 <res 00000002>          tss.ss1:    resw 1
  2469 0000CE82 <res 00000002>          	    resw 1 	
  2470 0000CE84 <res 00000004>          tss.esp2:   resd 1
  2471 0000CE88 <res 00000002>          tss.ss2:    resw 1
  2472 0000CE8A <res 00000002>          	    resw 1
  2473                                  ; tss offset 28
  2474 0000CE8C <res 00000004>          tss.CR3:    resd 1
  2475 0000CE90 <res 00000004>          tss.eip:    resd 1
  2476 0000CE94 <res 00000004>          tss.eflags: resd 1
  2477                                  ; tss offset 40
  2478 0000CE98 <res 00000004>          tss.eax:    resd 1		 		
  2479 0000CE9C <res 00000004>          tss.ecx:    resd 1
  2480 0000CEA0 <res 00000004>          tss.edx:    resd 1
  2481 0000CEA4 <res 00000004>          tss.ebx:    resd 1
  2482 0000CEA8 <res 00000004>          tss.esp:    resd 1
  2483 0000CEAC <res 00000004>          tss.ebp:    resd 1
  2484 0000CEB0 <res 00000004>          tss.esi:    resd 1
  2485 0000CEB4 <res 00000004>          tss.edi:    resd 1
  2486                                  ; tss offset 72
  2487 0000CEB8 <res 00000002>          tss.ES:     resw 1
  2488 0000CEBA <res 00000002>          	    resw 1	
  2489 0000CEBC <res 00000002>          tss.CS:	    resw 1
  2490 0000CEBE <res 00000002>          	    resw 1
  2491 0000CEC0 <res 00000002>          tss.SS:	    resw 1
  2492 0000CEC2 <res 00000002>          	    resw 1
  2493 0000CEC4 <res 00000002>          tss.DS:	    resw 1
  2494 0000CEC6 <res 00000002>          	    resw 1
  2495 0000CEC8 <res 00000002>          tss.FS:	    resw 1
  2496 0000CECA <res 00000002>          	    resw 1
  2497 0000CECC <res 00000002>          tss.GS:	    resw 1
  2498 0000CECE <res 00000002>          	    resw 1		
  2499 0000CED0 <res 00000002>          tss.LDTR:   resw 1
  2500 0000CED2 <res 00000002>          	    resw 1
  2501                                  ; tss offset 100		
  2502 0000CED4 <res 00000002>          	    resw 1		
  2503 0000CED6 <res 00000002>          tss.IOPB:   resw 1
  2504                                  ; tss offset 104 
  2505                                  tss_end:
  2506                                  
  2507 0000CED8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2508                                  		    ; (Physical address = Virtual address)	 	
  2509 0000CEDC <res 00000004>          memory_size: resd 1 ; memory size in pages
  2510 0000CEE0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  2511 0000CEE4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  2512                                  		    ; first free page search
  2513 0000CEE8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
  2514                                  		    ; next free page search will be
  2515                                  		    ; stopped after it. (end of M.A.T.)
  2516 0000CEEC <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
  2517                                  		    ; first free page search
  2518                                  		    ; will be started on it. (for user)
  2519 0000CEF0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
  2520                                  
  2521                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2522                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  2523 0000CEF4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  2524                                  			  ; NOTE: active page only	
  2525 0000CEF6 <res 00000002>          CURSOR_MODE: resw 1 ; 24/01/2016
  2526 0000CEF8 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  2527                                  ACTIVE_PAGE: 
  2528 0000CF08 <res 00000001>          ptty: 	     resb 1 ; current tty
  2529                                  ; 01/07/2015 - 29/01/2016
  2530 0000CF09 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  2531                                  ; 26/10/2015
  2532                                  ; 07/09/2014
  2533 0000CF0A <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  2534                                  
  2535                                  ; 21/08/2014
  2536 0000CF1E <res 00000004>          tcount:	     resd 1
  2537                                  
  2538                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2539 0000CF22 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
  2540                                  
  2541                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  2542                                  ; (open mode locks for pseudo TTYs)
  2543                                  ; [ major tty locks (return error in any conflicts) ]
  2544 0000CF26 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
  2545                                  
  2546                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2547                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  2548 0000CF3A <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  2549                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2550                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  2551                                  ;; 0 means serial port is not available 
  2552                                  ;;comprm: ; 25/06/2014
  2553 0000CF44 <res 00000001>          com1p:       resb 1  ;;0E3h
  2554 0000CF45 <res 00000001>          com2p:       resb 1  ;;0E3h
  2555                                  
  2556                                  ; 17/11/2015
  2557                                  ; request for response (from the terminal)	
  2558 0000CF46 <res 00000002>          req_resp:    resw 1 			
  2559                                  ; 07/11/2015
  2560 0000CF48 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  2561                                  		    ; (0= COM1, 1= COM2)
  2562                                  ; 09/11/2015
  2563 0000CF49 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2564                                  ; 07/11/2015
  2565 0000CF4A <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2566 0000CF4C <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2567                                  
  2568                                  ; 22/08/2014 (RTC)
  2569                                  ; (Packed BCD)
  2570 0000CF4E <res 00000001>          time_seconds: resb 1
  2571 0000CF4F <res 00000001>          time_minutes: resb 1
  2572 0000CF50 <res 00000001>          time_hours:   resb 1
  2573 0000CF51 <res 00000001>          date_wday:    resb 1
  2574 0000CF52 <res 00000001>          date_day:     resb 1
  2575 0000CF53 <res 00000001>          date_month:   resb 1			
  2576 0000CF54 <res 00000001>          date_year:    resb 1
  2577 0000CF55 <res 00000001>          date_century: resb 1
  2578                                  
  2579                                  ; 24/01/2016
  2580 0000CF56 <res 00000004>          RTC_LH:	       resd 1
  2581 0000CF5A <res 00000001>          RTC_WAIT_FLAG: resb 1
  2582 0000CF5B <res 00000001>          USER_FLAG:     resb 1
  2583                                  
  2584                                  
  2585                                  %include 'diskbss.s'	; UNINITIALIZED DISK (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskbss.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskbss.inc (10/07/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
    20                              <1> ; Last Modification: 10/07/2015
    21                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
    22                              <1> 
    23                              <1> alignb 2
    24                              <1> 
    25                              <1> ;----------------------------------------
    26                              <1> ;	TIMER DATA AREA 		:
    27                              <1> ;----------------------------------------
    28                              <1> 
    29                              <1> TIMER_LH:	; 16/02/205
    30 0000CF5C <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0000CF5E <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0000CF60 <res 00000001>      <1> TIMER_OFL:      resb 	1               ; TIMER HAS ROLLED OVER SINCE LAST READ
    33                              <1> 
    34                              <1> ;----------------------------------------
    35                              <1> ;	DISKETTE DATA AREAS		:
    36                              <1> ;----------------------------------------
    37                              <1> 
    38 0000CF61 <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0000CF62 <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0000CF63 <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 0000CF64 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 0000CF65 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 0000CF6C <res 00000001>      <1> LASTRATE:	resb 	1
    49 0000CF6D <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0000CF6E <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0000CF6F <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0000CF70 <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0000CF71 <res 00000004>      <1> DSK_STATE:	resb 	4
    54 0000CF75 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 0000CF77 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 0000CF78 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 0000CF79 <res 00000001>      <1> CONTROL_BYTE:	resb 	1		; HEAD CONTROL BYTE
    63                              <1> ;@PORT_OFF	resb	1		; RESERVED (PORT OFFSET)
    64                              <1> ;port1_off	resb	1		; Hard disk controller 1 - port offset
    65                              <1> ;port2_off	resb	1		; Hard idsk controller 2 - port offset
    66                              <1> 
    67 0000CF7A <res 00000002>      <1> alignb 4
    68                              <1> 
    69                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    70                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    71                              <1> HF_TBL_VEC: ; 22/12/2014	
    72 0000CF7C <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0000CF80 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 0000CF84 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 0000CF88 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 0000CF8C <res 00000001>      <1> LBAMode:     	resb	1
    79                              <1> 
    80                              <1> ; *****************************************************************************
  2586                                  
  2587                                  ;;; Real Mode Data (10/07/2015 - BSS)
  2588                                  
  2589                                  ;alignb 2
  2590                                  
  2591                                  ; 10/01/2016
  2592                                  %include 'trdoskx.s'	; UNINITIALIZED KERNEL (Logical Drive & FS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - UNINITIALIZED DATA : trdoskx.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 06/05/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
    14                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
    15                              <1> ; DIR.ASM      [17/01/2004] Last Update: 09/10/2011
    16                              <1> ; CMD_INTR.ASM [29/01/2005] Last update: 09/11/2011
    17                              <1> ; DRV_FAT.ASM  [07/07/2009] Last update: 21/08/2011
    18                              <1> 
    19 0000CF8D <res 00000003>      <1> alignb 4
    20                              <1> 
    21                              <1> ; MAINPROG.ASM
    22 0000CF90 <res 00000004>      <1> MainProgCfg_FileSize:   resd 1 ; 14/04/2016
    23 0000CF94 <res 00000004>      <1> MainProgCfg_LineOffset: resd 1 ; 14/04/2016
    24                              <1> 
    25 0000CF98 <res 00000004>      <1> Current_VolSerial: resd 1
    26                              <1> 
    27 0000CF9C <res 00000004>      <1> Current_Dir_FCluster: resd 1
    28                              <1> 
    29 0000CFA0 <res 00000001>      <1> Current_Dir_Level: resb 1
    30 0000CFA1 <res 00000001>      <1> Current_FATType: resb 1
    31 0000CFA2 <res 00000001>      <1> Current_Drv: resb 1
    32 0000CFA3 <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    33 0000CFA4 <res 00000001>      <1>                    resb 1 ; ':'
    34 0000CFA5 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    35 0000CFA6 <res 0000005A>      <1> Current_Directory: resb 90
    36 0000D000 <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    37 0000D001 <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    38                              <1> 
    39 0000D002 <res 00000001>      <1> CursorColumn: 	resb 1
    40 0000D003 <res 00000001>      <1> CmdArgStart:    resb 1
    41                              <1> 
    42                              <1> Remark: ; 03/02/2016
    43 0000D004 <res 0000004E>      <1> 		resb 78
    44                              <1> 
    45 0000D052 <res 00000050>      <1> CommandBuffer: 	resb 80
    46                              <1> 
    47 0000D0A2 <res 00000100>      <1> TextBuffer: resb 256
    48                              <1> 
    49                              <1> MasterBootBuff:
    50 0000D1A2 <res 000001BE>      <1> MasterBootCode: resb 1BEh
    51 0000D360 <res 00000040>      <1> PartitionTable: resb 64
    52 0000D3A0 <res 00000002>      <1> MBIDCode: resw 1
    53                              <1> 
    54                              <1> PTable_Buffer:
    55 0000D3A2 <res 00000040>      <1> PTable_hd0: resb 64
    56 0000D3E2 <res 00000040>      <1> PTable_hd1: resb 64
    57 0000D422 <res 00000040>      <1> PTable_hd2: resb 64
    58 0000D462 <res 00000040>      <1> PTable_hd3: resb 64
    59 0000D4A2 <res 00000040>      <1> PTable_ep0: resb 64
    60 0000D4E2 <res 00000040>      <1> PTable_ep1: resb 64
    61 0000D522 <res 00000040>      <1> PTable_ep2: resb 64
    62 0000D562 <res 00000040>      <1> PTable_ep3: resb 64
    63                              <1> 
    64 0000D5A2 <res 00000001>      <1> HD_LBA_yes: resb 1
    65 0000D5A3 <res 00000001>      <1> PP_Counter: resb 1
    66 0000D5A4 <res 00000001>      <1> EP_Counter: resb 1
    67                              <1> 
    68 0000D5A5 <res 00000004>      <1> EP_StartSector: resd 1
    69 0000D5A9 <res 00000004>      <1>                 resd 1
    70 0000D5AD <res 00000004>      <1>                 resd 1
    71 0000D5B1 <res 00000004>      <1>                 resd 1
    72                              <1> 
    73 0000D5B5 <res 00000200>      <1> DOSBootSectorBuff: resb 512
    74                              <1> 
    75                              <1> FAT_BuffDescriptor:
    76 0000D7B5 <res 00000004>      <1> FAT_CurrentCluster: resd 1
    77 0000D7B9 <res 00000001>      <1> FAT_BuffValidData: resb 1
    78 0000D7BA <res 00000001>      <1> FAT_BuffDrvName: resb 1
    79 0000D7BB <res 00000002>      <1> FAT_BuffOffset: resw 1
    80 0000D7BD <res 00000004>      <1> FAT_BuffSector: resd 1
    81                              <1> 
    82 0000D7C1 <res 00000004>      <1> FAT_ClusterCounter: resd 1
    83 0000D7C5 <res 00000004>      <1> LastCluster: resd 1
    84                              <1> 
    85                              <1> ; 18/03/2016 (TRDOS v2.0)
    86 0000D7C9 <res 00000001>      <1> ClusterBuffer_Valid: resb 1
    87                              <1> 
    88                              <1> Dir_BuffDescriptor:
    89 0000D7CA <res 00000001>      <1> DirBuff_DRV: resb 1
    90 0000D7CB <res 00000001>      <1> DirBuff_FATType: resb 1
    91 0000D7CC <res 00000001>      <1> DirBuff_ValidData: resb 1
    92 0000D7CD <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
    93 0000D7CF <res 00000002>      <1> DirBuff_LastEntry: resw 1
    94 0000D7D1 <res 00000004>      <1> DirBuff_Cluster: resd 1 
    95 0000D7D5 <res 00000002>      <1> DirBuffer_Size: resw 1
    96                              <1> ;DirBuff_EntryCounter: resw 1
    97                              <1> 
    98                              <1> ; 01/02/2016
    99                              <1> ; these are on (real mode) segment 8000h and later
   100                              <1> ; FAT_Buffer:	resb 1536 ; 3 sectors
   101                              <1> ; Dir_Buffer:	resb 512*32
   102                              <1> ; Logical_DOSDisks:  resb 6656 ; 26 * 256 bytes
   103                              <1> 
   104                              <1> ; 18/01/2016
   105                              <1> 
   106 0000D7D7 <res 00000004>      <1> FreeClusterCount: resd 1
   107                              <1> 
   108 0000D7DB <res 00000004>      <1> VolSize_Unit1:   resd 1
   109 0000D7DF <res 00000004>      <1> VolSize_Unit2:   resd 1
   110                              <1> 
   111 0000D7E3 <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   112 0000D7E7 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   113 0000D7F1 <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   114 0000D7F2 <res 00000001>      <1> resb 1
   115 0000D7F3 <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   116 0000D7F7 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   117 0000D801 <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   118                              <1> 
   119                              <1> ; 10/02/2016
   120 0000D802 <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   121                              <1> 
   122                              <1> ; 24/01/2016
   123 0000D803 <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   124                              <1> ; 06/02/2016
   125 0000D883 <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   126 0000D887 <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   127 0000D888 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   128                              <1> ;
   129 0000D889 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   130 0000D88B <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   131 0000D88F <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   132                              <1> ;
   133 0000D891 <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   134                              <1> 
   135 0000D892 <res 00000002>      <1> alignb 4
   136                              <1> 
   137                              <1> ; 29/01/2016
   138 0000D894 <res 00000001>      <1> Program_Exit:	resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   139                              <1> 
   140                              <1> ;alignb 4
   141                              <1> ; 23/02/2016
   142 0000D895 <res 00000001>      <1> disk_rw_op:	resb 1 ;  0 = disk read, 1 = disk write
   143                              <1> ;disk_rw_spt:	resb 1 ; sectors per track (<= 63) /// (<256)
   144                              <1> ; 31/01/2016
   145 0000D896 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   146 0000D897 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   147 0000D898 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   148                              <1> 
   149                              <1> ; 06/02/2016 (long name)
   150 0000D89C <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   151 0000D89E <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   152 0000D8A0 <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   153                              <1> ;	
   154 0000D8A1 <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   155 0000D8A2 <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   156 0000D8A3 <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   157 0000D8A4 <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   158                              <1> 
   159                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   160 0000D928 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   161 0000D929 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   162                              <1> 
   163                              <1> ; 07/02/2016
   164 0000D92A <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   165                              <1> 
   166                              <1> ; 10/02/2016
   167                              <1> Dir_Entry_Name:
   168 0000D937 <res 0000000D>      <1> 		resb 13 ; DIR.ASM
   169                              <1> 
   170                              <1> alignb 2
   171                              <1> 
   172 0000D944 <res 00000002>      <1> AttributesMask: resw 1 ; CMD_INTR.ASM ; 09/11/2011
   173                              <1> 
   174                              <1> ; 10/02/2016 (128 bytes -> 126 bytes)
   175                              <1> ; 08/02/2016
   176                              <1> ;FFF Structure (128 bytes) ; DIR.ASM ; 09/10/2011
   177 0000D946 <res 00000001>      <1> FindFile_Drv:		  resb 1
   178 0000D947 <res 00000041>      <1> FindFile_Directory:	  resb 65
   179 0000D988 <res 0000000D>      <1> FindFile_Name:		  resb 13
   180                              <1> FindFile_LongNameEntryLength:
   181 0000D995 <res 00000001>      <1> FindFile_LongNameYes: 	  resb 1 ; Sign for longname procedures
   182                              <1> ;Above 80 bytes form
   183                              <1> ;TR-DOS Source/Destination File FullName Format/Structure
   184 0000D996 <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   185 0000D998 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   186 0000D9B8 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   187 0000D9BC <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   188 0000D9C0 <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   189 0000D9C2 <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   190 0000D9C4 <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   191                              <1> 
   192 0000D9C6 <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   193 0000D9CA <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   194                              <1> 
   195                              <1> ; 10/02/2016
   196 0000D9CE <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   197 0000D9D0 <res 00000002>      <1> Dir_Count:      resw 1
   198 0000D9D2 <res 00000004>      <1> Total_FSize:    resd 1
   199 0000D9D6 <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   200 0000D9DA <res 0000000A>      <1>                 resb 10
   201 0000D9E4 <res 00000001>      <1> TFS_Dec_End:    resb 1
   202                              <1> 
   203 0000D9E5 <res 00000001>      <1> PrintDir_RowCounter: resb 1
   204                              <1> 
   205 0000D9E6 <res 00000002>      <1> alignb 4
   206                              <1> ; 15/02/2015 ('show' command variables)
   207 0000D9E8 <res 00000004>      <1> Show_FDT:	resd 1
   208 0000D9EC <res 00000004>      <1> Show_LDDDT:	resd 1
   209 0000D9F0 <res 00000004>      <1> Show_Cluster:	resd 1
   210 0000D9F4 <res 00000004>      <1> Show_FileSize:	resd 1
   211 0000D9F8 <res 00000004>      <1> Show_FilePointer: resd 1
   212 0000D9FC <res 00000002>      <1> Show_ClusterPointer: resw 1
   213 0000D9FE <res 00000002>      <1> Show_ClusterSize: resw 1
   214 0000DA00 <res 00000001>      <1> Show_RowCount:	resb 1
   215                              <1> 
   216 0000DA01 <res 00000003>      <1> alignb 4
   217                              <1> ; 21/02/2016
   218 0000DA04 <res 00000004>      <1> DelFile_FNPointer:	resd 1 ; ; CMD_INTR.ASM (word) ; 09/11/2011
   219                              <1> ; 27/02/2016
   220                              <1> ; DIR.ASM (09/10/2011)
   221 0000DA08 <res 00000004>      <1> DelFile_FCluster:	resd 1
   222 0000DA0C <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   223 0000DA0E <res 00000001>      <1> DelFile_LNEL:		resb 1
   224 0000DA0F <res 00000001>      <1> resb 1
   225                              <1> 
   226                              <1> ; DIR.ASM
   227 0000DA10 <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   228 0000DA14 <res 00000004>      <1> mkdir_FFCluster:	resd 1
   229 0000DA18 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   230 0000DA1C <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   231 0000DA20 <res 00000002>      <1> mkdir_attrib:		resw 1 
   232 0000DA22 <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   233 0000DA23 <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   234 0000DA24 <res 0000000D>      <1> mkdir_Name:		resb 13
   235 0000DA31 <res 00000002>      <1> resw 1 ; 01/03/2016
   236                              <1> ; 27/02/2016
   237 0000DA33 <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   238 0000DA34 <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   239 0000DA38 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   240 0000DA3C <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   241 0000DA40 <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   242                              <1> ; 22/02/2016
   243 0000DA44 <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   244 0000DA45 <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   245                              <1> 	
   246 0000DA49 <res 00000003>      <1> alignb 4
   247                              <1> ; DRV_FAT.ASM ; 21/08/2011
   248 0000DA4C <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   249 0000DA50 <res 00000004>      <1> gffc_first_free_cluster: resd 1
   250 0000DA54 <res 00000004>      <1> gffc_last_free_cluster:  resd 1
   251                              <1> 
   252                              <1> ;29/04/2016
   253                              <1> Cluster_Index: ; resd 1
   254                              <1> ; 22/02/2016
   255 0000DA58 <res 00000004>      <1> ClusterValue:	resd 1
   256                              <1> ; 04/03/2016
   257 0000DA5C <res 00000001>      <1> Attributes:	resb 1 
   258                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   259 0000DA5D <res 00000001>      <1> resb 1
   260 0000DA5E <res 00000001>      <1> CFS_OPType: resb 1
   261 0000DA5F <res 00000001>      <1> CFS_Drv:    resb 1
   262 0000DA60 <res 00000004>      <1> CFS_CC:	    resd 1
   263 0000DA64 <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   264 0000DA68 <res 00000004>      <1> CFS_FAT32FC: resd 1
   265                              <1> 
   266                              <1> ; 27/02/2016
   267                              <1> ;alignb 4
   268 0000DA6C <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   269                              <1> 
   270                              <1> ; DIR.ASM
   271 0000DA70 <res 00000002>      <1> DLN_EntryNumber: resw 1
   272 0000DA72 <res 00000001>      <1> DLN_40h:	 resb 1
   273                              <1> ; 28/02/2016
   274 0000DA73 <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   275                              <1> 
   276                              <1> alignb 4
   277                              <1> ; DIR.ASM (09/10/2011)
   278 0000DA74 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   279 0000DA76 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   280 0000DA78 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   281 0000DA7C <res 00000004>      <1> LCDE_ByteOffset: resd 1
   282                              <1> 
   283                              <1> ;alignb4
   284                              <1> ; 06/03/2016 (word -> dword)
   285                              <1> ; CMD_INTR.ASM (01/08/2010)
   286 0000DA80 <res 00000004>      <1> SourceFilePath:	     resd 1
   287 0000DA84 <res 00000004>      <1> DestinationFilePath: resd 1
   288                              <1> 
   289                              <1> ;alignb 4
   290                              <1> ; 06/03/2016
   291                              <1> ; FILE.ASM (09/10/2011)
   292                              <1> ;Source File Structure (same with 'Find File' Structure)
   293 0000DA88 <res 00000001>      <1> SourceFile_Drv:			resb 1
   294 0000DA89 <res 00000041>      <1> SourceFile_Directory:		resb 65
   295 0000DACA <res 0000000D>      <1> SourceFile_Name:		resb 13
   296                              <1> SourceFile_LongNameEntryLength: 
   297 0000DAD7 <res 00000001>      <1> SourceFile_LongNameYes:		resb 1 ; Sign for longname procedures
   298                              <1> ;Above 80 bytes
   299                              <1> ;is TR-DOS Source File FullName Format/Structure
   300 0000DAD8 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   301 0000DADA <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   302 0000DAFA <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   303 0000DAFE <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   304 0000DB02 <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   305 0000DB04 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   306                              <1> ; 16/03/2016
   307 0000DB06 <res 00000001>      <1> SourceFile_SecPerClust:		resb 1
   308 0000DB07 <res 00000001>      <1> SourceFile_Reserved:		resb 1
   309                              <1> ; Above is 128 bytes
   310                              <1> 
   311                              <1> ;Destination File Structure (same with 'Find File' Structure)
   312 0000DB08 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   313 0000DB09 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   314 0000DB4A <res 0000000D>      <1> DestinationFile_Name:		resb 13
   315                              <1> DestinationFile_LongNameEntryLength:
   316 0000DB57 <res 00000001>      <1> DestinationFile_LongNameYes:	resb 1 ; Sign for longname procedures
   317                              <1> ;Above 80 bytes
   318                              <1> ;is TR-DOS Destination File FullName Format/Structure
   319 0000DB58 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   320 0000DB5A <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   321 0000DB7A <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   322 0000DB7E <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   323 0000DB82 <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   324 0000DB84 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   325                              <1> ; 16/03/2016
   326 0000DB86 <res 00000001>      <1> DestinationFile_SecPerClust:	resb 1
   327 0000DB87 <res 00000001>      <1> DestinationFile_Reserved:	resb 1
   328                              <1> ; Above is 128 bytes
   329                              <1> 
   330                              <1> ; 24/04/2016
   331 0000DB88 <res 00000002>      <1> resw 1
   332                              <1> 
   333                              <1> ; 10/03/2016
   334                              <1> ; FILE.ASM
   335 0000DB8A <res 00000001>      <1> move_cmd_phase:	   resb 1
   336 0000DB8B <res 00000001>      <1> msftdf_sf_df_drv:  resb 1
   337 0000DB8C <res 00000004>      <1> msftdf_drv_offset: resd 1
   338                              <1> 
   339                              <1> ; 11/03/2016
   340                              <1> ; DRV_FAT.ASM (21/08/2011)
   341 0000DB90 <res 00000004>      <1> FAT_anc_LCluster:  resd 1
   342 0000DB94 <res 00000004>      <1> FAT_anc_FFCluster: resd 1
   343                              <1> 
   344                              <1> ;alignb 4
   345                              <1> 
   346                              <1> ; 14/03/2016
   347                              <1> ; TRDOS 386 = TRDOS v2.0 feature only !
   348                              <1> ; 'allocate_memory_block' in 'memory.s'
   349 0000DB98 <res 00000004>      <1> mem_ipg_count:	resd 1 ; page count (for contiguous allocation)
   350 0000DB9C <res 00000004>      <1> mem_pg_count:	resd 1 ; page count (for count down)
   351 0000DBA0 <res 00000004>      <1> mem_aperture:	resd 1 ; contiguous free pages (current)
   352 0000DBA4 <res 00000004>      <1> mem_max_aperture: resd 1 ; maximum value of contiguous free pages
   353 0000DBA8 <res 00000004>      <1> mem_pg_pos:	resd 1 ; mem. position (page #) of current aperture
   354 0000DBAC <res 00000004>      <1> mem_max_pg_pos: resd 1 ; mem. position (page #) of max. aperture
   355                              <1> 
   356                              <1> ; 15/03/2016
   357                              <1> ; FILE.ASM ('copy_source_file_to_destination_file')
   358 0000DBB0 <res 00000001>      <1> copy_cmd_phase:       resb 1
   359 0000DBB1 <res 00000001>      <1> csftdf_rw_err:	      resb 1
   360 0000DBB2 <res 00000001>      <1> DestinationFileFound: resb 1
   361 0000DBB3 <res 00000001>      <1> csftdf_cdrv: 	      resb 1
   362 0000DBB4 <res 00000004>      <1> csftdf_filesize:      resd 1
   363                              <1> ; TRDOS386 (TRDOS v2.0)
   364 0000DBB8 <res 00000004>      <1> csftdf_sf_mem_addr:   resd 1
   365 0000DBBC <res 00000004>      <1> csftdf_sf_mem_bsize:  resd 1
   366                              <1> ;
   367                              <1> 
   368 0000DBC0 <res 00000004>      <1> csftdf_sf_cluster:    resd 1 ; 16/03/2016
   369 0000DBC4 <res 00000004>      <1> csftdf_df_cluster:    resd 1
   370                              <1> ; 16/03/2016
   371 0000DBC8 <res 00000004>      <1> csftdf_r_size:        resd 1
   372 0000DBCC <res 00000004>      <1> csftdf_w_size:        resd 1
   373 0000DBD0 <res 00000004>      <1> csftdf_sf_rbytes:     resd 1
   374 0000DBD4 <res 00000004>      <1> csftdf_df_wbytes:     resd 1
   375 0000DBD8 <res 00000001>      <1> csftdf_percentage:    resb 1
   376                              <1> ; 17/03/2016
   377 0000DBD9 <res 00000001>      <1> csftdf_videopage:     resb 1
   378 0000DBDA <res 00000002>      <1> csftdf_cursorpos:     resw 1
   379 0000DBDC <res 00000004>      <1> csftdf_sf_drv_dt:     resd 1
   380 0000DBE0 <res 00000004>      <1> csftdf_df_drv_dt:     resd 1
   381                              <1> 
   382                              <1> ; 21/03/2016
   383                              <1> ; 20/03/2016
   384                              <1> ; FILE.ASM
   385 0000DBE4 <res 00000004>      <1> createfile_Name_Offset:  resd 1
   386 0000DBE8 <res 00000004>      <1> createfile_FreeSectors:  resd 1 
   387 0000DBEC <res 00000004>      <1> createfile_size:         resd 1
   388 0000DBF0 <res 00000004>      <1> createfile_FFCluster:    resd 1 ; 11/03/2016
   389 0000DBF4 <res 00000004>      <1> createfile_LastDirCluster: resd 1
   390 0000DBF8 <res 00000004>      <1> createfile_Cluster:      resd 1
   391 0000DBFC <res 00000004>      <1> createfile_PCluster:     resd 1
   392 0000DC00 <res 00000001>      <1> createfile_attrib:	 resb 1
   393 0000DC01 <res 00000001>      <1> createfile_SecPerClust:  resb 1
   394 0000DC02 <res 00000002>      <1> createfile_DirIndex:     resw 1
   395 0000DC04 <res 00000004>      <1> createfile_CCount:	 resd 1
   396 0000DC08 <res 00000002>      <1> createfile_BytesPerSec:	 resw 1 ; 23/03/2016
   397 0000DC0A <res 00000001>      <1> createfile_wfc:	         resb 1
   398 0000DC0B <res 00000001>      <1> createfile_UpdatePDir:	 resb 1 ; 31/03/2016
   399                              <1> 
   400                              <1> ;alignb 4
   401                              <1> 
   402                              <1> ; 11/04/2016
   403 0000DC0C <res 00000002>      <1> env_var_length:	   resw 1
   404                              <1> 
   405 0000DC0E <res 00000002>      <1> alignb 4
   406                              <1> 
   407                              <1> ; 25/04/2016
   408 0000DC10 <res 00000001>      <1> readi.valid:	resb 1 ; valid data (>0 = valid for readi)
   409 0000DC11 <res 00000001>      <1> readi.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   410 0000DC12 <res 00000001>      <1> readi.spc:	resb 1 ; sectors per cluster for 'readi' drive
   411 0000DC13 <res 00000001>      <1> readi.s_index:  resb 1 ; sector index in current cluster (buffer)
   412 0000DC14 <res 00000004>      <1> readi.sector:	resd 1 ; current disk sector
   413 0000DC18 <res 00000002>      <1> readi.bpc:	resw 1 ; bytes per cluster - 1
   414 0000DC1A <res 00000002>      <1> readi.offset:	resw 1 ; byte offset in cluster buffer
   415 0000DC1C <res 00000004>      <1> readi.cluster:  resd 1 ; current cluster number
   416 0000DC20 <res 00000004>      <1> readi.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   417 0000DC24 <res 00000004>      <1> readi.fclust:	resd 1 ; first cluster of the current cluster
   418 0000DC28 <res 00000004>      <1> readi.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   419                              <1> ;readi.buffer:	resd 1 ; readi sector buffer address
   420                              <1> 
   421 0000DC2C <res 00000001>      <1> writei.valid:	resb 1 ; valid data (>0 = valid for writei)
   422 0000DC2D <res 00000001>      <1> writei.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   423 0000DC2E <res 00000001>      <1> writei.spc:	resb 1 ; sectors per cluster for 'writei' drive
   424 0000DC2F <res 00000001>      <1> writei.s_index: resb 1 ; sector index in current cluster (buffer)
   425 0000DC30 <res 00000004>      <1> writei.sector:	resd 1 ; current disk sector
   426 0000DC34 <res 00000002>      <1> writei.bpc:	resw 1 ; bytes per cluster - 1
   427 0000DC36 <res 00000002>      <1> writei.offset:	resw 1 ; byte offset in cluster buffer
   428 0000DC38 <res 00000004>      <1> writei.cluster: resd 1 ; current cluster number
   429 0000DC3C <res 00000004>      <1> writei.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   430 0000DC40 <res 00000004>      <1> writei.fclust:  resd 1 ; first cluster of the current cluster
   431 0000DC44 <res 00000004>      <1> writei.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   432                              <1> ;writei.buffer:	resd 1 ; writei sector buffer address
   433                              <1> 
   434                              <1> ; 29/04/2016
   435 0000DC48 <res 00000004>      <1> Run_CDirFC:	resd 1
   436 0000DC4C <res 00000001>      <1> Run_Auto_Path:	resb 1
   437 0000DC4D <res 00000001>      <1> Run_Manual_Path: resb 1 ; 0 -> auto path sequence needed
   438 0000DC4E <res 00000001>      <1> EXE_ID:		resb 1
   439 0000DC4F <res 00000001>      <1> EXE_dot:	resb 1
   440                              <1> 
   441                              <1> ; 06/05/2016
   442 0000DC50 <res 00000004>      <1> mainprog_return_addr: resd 1
   443 0000DC54 <res 00000004>      <1> last_error:	resd 1  ; this will be used to return error code to MainProg
   444                              <1> 			; 'lasterror' keyword will be used later to get the
   445                              <1> 			; last error code/number/status.
  2593                                  ; 24/01/2016
  2594                                  %include 'ubss.s'	; UNINITIALIZED KERNEL (USER) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - UNINITIALIZED USER DATA : ubss.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/04/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    11                              <1> ; ux.s (04/12/2015)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> ; Retro UNIX 386 v1 Kernel - ux.s
    15                              <1> ; Last Modification: 04/12/2015
    16                              <1> ;
    17                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
    18                              <1> ; (Modified from 
    19                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
    20                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
    21                              <1> ; ----------------------------------------------------------------------------
    22                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    23                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
    24                              <1> ; <Bell Laboratories (17/3/1972)>
    25                              <1> ; <Preliminary Release of UNIX Implementation Document>
    26                              <1> ; (Section E10 (17/3/1972) - ux.s)
    27                              <1> ; ****************************************************************************
    28                              <1> 
    29                              <1> alignb 2
    30                              <1> 
    31                              <1> inode:
    32                              <1> 	; 11/03/2013. 
    33                              <1> 	;Derived from UNIX v1 source code 'inode' structure (ux).
    34                              <1> 	;i.
    35                              <1> 
    36 0000DC58 <res 00000002>      <1> 	i.flgs:	 resw 1
    37 0000DC5A <res 00000001>      <1> 	i.nlks:	 resb 1
    38 0000DC5B <res 00000001>      <1> 	i.uid:	 resb 1
    39                              <1>         ;i.size:  resw 1 ; size
    40 0000DC5C <res 00000002>      <1> 	resw 1 ; 29/04/2016
    41 0000DC5E <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    42 0000DC6E <res 00000004>      <1> 	i.ctim:	 resd 1
    43 0000DC72 <res 00000004>      <1> 	i.mtim:	 resd 1
    44 0000DC76 <res 00000002>      <1> 	i.rsvd:  resw 1 ; Reserved (ZERO/Undefined word for UNIX v1.)
    45                              <1> 
    46                              <1> I_SIZE	equ $ - inode 
    47                              <1> 
    48                              <1> process:
    49                              <1> 	; 06/05/2015
    50                              <1> 	; 11/03/2013 - 05/02/2014
    51                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
    52                              <1> 	;p.
    53                              <1> 	
    54 0000DC78 <res 00000020>      <1>         p.pid:   resw nproc
    55 0000DC98 <res 00000020>      <1>         p.ppid:  resw nproc
    56 0000DCB8 <res 00000020>      <1>         p.break: resw nproc
    57 0000DCD8 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    58 0000DCE8 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    59 0000DCF8 <res 00000010>      <1> 	p.link:	 resb nproc
    60 0000DD08 <res 00000010>      <1> 	p.stat:	 resb nproc
    61                              <1> 
    62                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
    63 0000DD18 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
    64                              <1> 			    ; 'user' structure	
    65                              <1> 
    66                              <1> 
    67                              <1> P_SIZE	equ $ - process
    68                              <1> 
    69                              <1> 
    70                              <1> ; fsp table (original UNIX v1)
    71                              <1> ;
    72                              <1> ;Entry
    73                              <1> ;          15                                      0
    74                              <1> ;  1     |---|---------------------------------------|
    75                              <1> ;        |r/w|       i-number of open file           |
    76                              <1> ;        |---|---------------------------------------| 
    77                              <1> ;        |               device number               |
    78                              <1> ;        |-------------------------------------------|
    79                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
    80                              <1> ;        |-------------------------------------------| 
    81                              <1> ;        |  flag that says    | number of processes  |
    82                              <1> ;        |   file deleted     | that have file open  |
    83                              <1> ;        |-------------------------------------------| 
    84                              <1> ;  2     |                                           |
    85                              <1> ;        |-------------------------------------------| 
    86                              <1> ;        |                                           |
    87                              <1> ;        |-------------------------------------------|
    88                              <1> ;        |                                           |
    89                              <1> ;        |-------------------------------------------|
    90                              <1> ;        |                                           |
    91                              <1> ;        |-------------------------------------------| 
    92                              <1> ;  3     |                                           | 
    93                              <1> ;        |                                           |  
    94                              <1> ;
    95                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
    96                              <1> 
    97                              <1> 
    98                              <1> ; 15/04/2015
    99 0000DD58 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
   100 0000DF4C <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
   101 0000DF64 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   102 0000DF66 <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   103                              <1> ; 18/05/2015
   104                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
   105                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
   106                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
   107                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
   108                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
   109                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
   110                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
   111                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
   112                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
   113                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
   114                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
   115 0000DF68 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
   116                              <1> 	        ; as above, for physical drives numbers in following table
   117 0000DF69 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   118                              <1> ; 15/04/2015
   119 0000DF6A <res 00000001>      <1> active:	 resb 1 
   120 0000DF6B <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   121 0000DF6C <res 00000002>      <1> mnti:	 resw 1
   122 0000DF6E <res 00000002>      <1> mpid:	 resw 1
   123 0000DF70 <res 00000002>      <1> rootdir: resw 1
   124                              <1> ; 14/02/2014
   125                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
   126                              <1> ;		      Single level run queue
   127                              <1> ;		      (in order to solve sleep/wakeup lock)
   128 0000DF72 <res 00000002>      <1> runq:	 resw 1
   129 0000DF74 <res 00000001>      <1> imod:	 resb 1
   130 0000DF75 <res 00000001>      <1> smod:	 resb 1
   131 0000DF76 <res 00000001>      <1> mmod:	 resb 1
   132 0000DF77 <res 00000001>      <1> sysflg:	 resb 1
   133                              <1> 
   134                              <1> alignb 4
   135                              <1> 
   136                              <1> user:
   137                              <1> 	; 04/12/2015 
   138                              <1> 	; 18/10/2015
   139                              <1> 	; 12/10/2015
   140                              <1> 	; 21/09/2015
   141                              <1> 	; 24/07/2015
   142                              <1> 	; 16/06/2015
   143                              <1> 	; 09/06/2015
   144                              <1> 	; 11/05/2015
   145                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
   146                              <1> 	; 10/10/2013
   147                              <1> 	; 11/03/2013. 
   148                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
   149                              <1> 	;u.
   150                              <1> 
   151 0000DF78 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   152 0000DF7C <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   153 0000DF80 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   154 0000DF84 <res 00000002>      <1> 	u.cdir:	  resw 1
   155 0000DF86 <res 0000000A>      <1> 	u.fp:	  resb 10
   156 0000DF90 <res 00000004>      <1> 	u.fofp:	  resd 1
   157 0000DF94 <res 00000004>      <1> 	u.dirp:	  resd 1
   158 0000DF98 <res 00000004>      <1> 	u.namep:  resd 1
   159 0000DF9C <res 00000004>      <1> 	u.off:	  resd 1
   160 0000DFA0 <res 00000004>      <1> 	u.base:	  resd 1
   161 0000DFA4 <res 00000004>      <1> 	u.count:  resd 1
   162 0000DFA8 <res 00000004>      <1> 	u.nread:  resd 1
   163 0000DFAC <res 00000004>      <1> 	u.break:  resd 1 ; break
   164 0000DFB0 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   165 0000DFB2 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   166                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   167 0000DFC2 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   168 0000DFC3 <res 00000001>      <1> 	u.pri:	  resb 1 ; 
   169 0000DFC4 <res 00000002>      <1> 	u.intr:	  resw 1
   170 0000DFC6 <res 00000002>      <1> 	u.quit:	  resw 1
   171                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   172 0000DFC8 <res 00000002>      <1> 	u.ilgins: resw 1
   173 0000DFCA <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   174 0000DFCC <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   175 0000DFCD <res 00000001>      <1> 	u.ruid:	  resb 1
   176 0000DFCE <res 00000001>      <1> 	u.bsys:	  resb 1
   177 0000DFCF <res 00000001>      <1> 	u.uno:	  resb 1
   178 0000DFD0 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   179                              <1> 	; tty number (rtty, rcvt, wtty)
   180 0000DFD4 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   181                              <1> 	; last error number
   182 0000DFD5 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   183                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   184 0000DFD9 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   185 0000DFDD <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   186 0000DFE1 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   187 0000DFE5 <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
   188                              <1> 	;u.pncount: resw 1 
   189                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
   190                              <1> 	;u.pnbase:  resd 1 
   191                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
   192                              <1> 			 ; 09/06/2015
   193 0000DFE7 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   194 0000DFE8 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
   195                              <1> 			 ; 24/07/2015 - 24/06/2015
   196                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
   197                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
   198                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
   199                              <1>  			 ; 24/06/2015	  	
   200                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
   201                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
   202                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
   203 0000DFE9 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   204                              <1> 
   205 0000DFED <res 00000003>      <1> alignb 4
   206                              <1> 
   207                              <1> U_SIZE	equ $ - user
   208                              <1> 
   209                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
   210 0000DFF0 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
   211 0000DFF4 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
   212 0000DFF8 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   213 0000DFFC <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   214 0000DFFE <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   215 0000E000 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
   216                              <1> 
   217                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
   218                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
   219 0000E004 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   220                              <1> 
   221                              <1> ;alignb 4
   222                              <1> 
   223                              <1> ; 24/04/2016
   224 0000E005 <res 00000004>      <1> ii:		resd 1 ; first cluster of the program file
   225 0000E009 <res 00000004>      <1> i.size:		resd 1 ; size of the program file
   226                              <1> 
   227                              <1> ; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
   228                              <1> ; 22/08/2015 (Retro UNIX 386 v1)
   229                              <1> buffer: 
   230 0000E00D <res 00000008>      <1> 	resb	8 
   231                              <1> readi_buffer:
   232 0000E015 <res 00000200>      <1> 	resb 	512
   233 0000E215 <res 00000008>      <1> 	resb	8
   234                              <1> writei_buffer:
   235 0000E21D <res 00000200>      <1> 	resb	512	
   236 0000E41D <res 00000410>      <1> 	resb (nbuf-2) * 520
   237                              <1> 
   238 0000E82D <res 00000008>      <1> sb0:	resd 2
   239                              <1> ;s:
   240                              <1> ; (root disk) super block buffer
   241                              <1> systm:
   242                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
   243                              <1> 	; 11/03/2013. 
   244                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
   245                              <1> 	;s.
   246                              <1> 
   247 0000E835 <res 00000002>      <1> 	resw 1
   248 0000E837 <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
   249 0000E99F <res 00000002>      <1> 	resw 1
   250 0000E9A1 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
   251 0000E9C1 <res 00000004>      <1> 	s.time:	 resd 1
   252 0000E9C5 <res 00000004>      <1> 	s.syst:	 resd 1
   253 0000E9C9 <res 00000004>      <1>         s.wait_: resd 1 ; wait
   254 0000E9CD <res 00000004>      <1> 	s.idlet: resd 1
   255 0000E9D1 <res 00000004>      <1> 	s.chrgt: resd 1
   256 0000E9D5 <res 00000002>      <1> 	s.drerr: resw 1
   257                              <1> 
   258                              <1> S_SIZE	equ $ - systm
   259                              <1> 
   260 0000E9D7 <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
   261                              <1> 
   262 0000EA35 <res 00000008>      <1> sb1:	resd 2
   263                              <1> ; (mounted disk) super block buffer
   264                              <1> mount:	
   265 0000EA3D <res 00000200>      <1> 	resb 512  ; 03/06/2015
  2595                                  
  2596                                  ;; Memory (swap) Data (11/03/2015)
  2597                                  ; 09/03/2015
  2598 0000EC3D <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  2599 0000EC3F <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2600 0000EC43 <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2601 0000EC47 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2602 0000EC4B <res 00000004>          swpd_next:  resd 1 ; next free page block
  2603 0000EC4F <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  2604                                  
  2605 0000EC53 <res 00000001>          alignb 4
  2606                                  
  2607                                  ; 10/07/2015
  2608                                  ; 28/08/2014
  2609 0000EC54 <res 00000004>          error_code:	resd 1
  2610                                  ; 29/08/2014
  2611 0000EC58 <res 00000004>          FaultOffset: 	resd 1
  2612                                  ; 21/09/2015
  2613 0000EC5C <res 00000004>          PF_Count:	resd 1	; total page fault count
  2614                                  		       	; (for debugging - page fault analyze)
  2615                                  		 	; 'page_fault_handler' (memory.inc)
  2616                                  			; 'sysgeterr' (u9.s)
  2617                                  ;; 21/08/2015
  2618                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
  2619                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
  2620                                  
  2621                                  bss_end:
  2622                                  
  2623                                  ; 27/12/2013
  2624                                  _end:  ; end of kernel code
