     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 29/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[8ACD]              	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[62CF]              	mov	[mem_1m_1k], cx
   160 00000017 8916[64CF]              	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[2DCE]                	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: 28/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> ; 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[8DCD]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    42 0000004E 8816[8CCD]          <1>         mov     [last_drv], dl  ; last hard disk number
    43 00000052 BB[10CD]            <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[8ECD]            <1> 	mov	si, fd0_type
    61                              <1> L3:
    62                              <1> 	; 14/01/2015
    63 00000063 8816[8BCD]          <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 E8B801              <1> 	call	set_disk_parms
    77                              <1> 	; 10/12/2014
    78 00000072 81FE[8ECD]          <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[8DCD]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[8BCD]          <1>         mov     [drv], dl
    94 0000008E 8816[8CCD]          <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[8DCD]          <1>         mov     [hdc], dl ; number of drives
    99                              <1> 	;; 14/01/2013
   100                              <1> 	;;push	cx
   101 0000009E E88901              <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[8BCD]          <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[8BCD]          <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[8BCD]          <1> 	inc	byte [drv]
   148 000000FD BB[10CD]            <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[8DCD]            <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[8BCD]          <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[8BCD]          <1> 	mov	dl, [drv]
   166 0000012A 52                  <1> 	push	dx
   167 0000012B 51                  <1> 	push	cx
   168 0000012C E8FB00              <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[30F1]            <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[90CD]          <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[8ECD]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   188 00000155 81C3[DACD]          <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[DACD]          <1> 	sub	bx, drv.status
   197 00000167 C1E302              <1> 	shl	bx, 2
   198 0000016A 81C3[BECD]          <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[90CD]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   301 000001F4 808F[DCCD]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[DCCD]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[8CCD]          <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 7466                <1> 	jz 	short L16 ; 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> 
   335                              <1> set_disk_parms:
   336                              <1> 	; 04/02/2016 (ebx -> bx)
   337                              <1> 	; 10/07/2015
   338                              <1> 	; 14/01/2015
   339                              <1> 	;push	bx
   340 0000022A 28FF                <1> 	sub	bh, bh
   341 0000022C 8A1E[8BCD]          <1> 	mov	bl, [drv]
   342 00000230 80FB80              <1> 	cmp	bl, 80h
   343 00000233 7203                <1> 	jb	short sdp0
   344 00000235 80EB7E              <1> 	sub	bl, 7Eh
   345                              <1> sdp0:	
   346 00000238 81C3[DACD]          <1> 	add	bx, drv.status
   347 0000023C C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   348                              <1> 	;
   349 0000023F 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   350 00000241 88CC                <1> 	mov	ah, cl ; 
   351 00000243 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   352 00000246 81EB[DACD]          <1> 	sub	bx, drv.status
   353 0000024A D0E3                <1> 	shl	bl, 1
   354 0000024C 81C3[94CD]          <1> 	add	bx, drv.cylinders
   355 00000250 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   356 00000251 8907                <1> 	mov	[bx], ax
   357 00000253 50                  <1> 	push	ax ; ** cylinders
   358 00000254 81EB[94CD]          <1> 	sub	bx, drv.cylinders
   359 00000258 81C3[A2CD]          <1> 	add	bx, drv.heads
   360 0000025C 30E4                <1> 	xor	ah, ah
   361 0000025E 88F0                <1> 	mov	al, dh ; heads
   362 00000260 40                  <1> 	inc	ax
   363 00000261 8907                <1> 	mov	[bx], ax
   364 00000263 81EB[A2CD]          <1>         sub     bx, drv.heads
   365 00000267 81C3[B0CD]          <1>         add     bx, drv.spt
   366 0000026B 30ED                <1> 	xor	ch, ch
   367 0000026D 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   368 00000270 890F                <1> 	mov	[bx], cx
   369 00000272 81EB[B0CD]          <1>         sub     bx, drv.spt
   370 00000276 D1E3                <1> 	shl	bx, 1
   371 00000278 81C3[BECD]          <1> 	add	bx, drv.size ; disk size (in sectors)
   372                              <1> 	; LBA size = cylinders * heads * secpertrack
   373 0000027C F7E1                <1> 	mul	cx 
   374 0000027E 89C2                <1> 	mov	dx, ax	; heads*spt					
   375 00000280 58                  <1> 	pop	ax ; ** cylinders
   376 00000281 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   377 00000282 F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   378 00000284 8907                <1> 	mov	[bx], ax
   379 00000286 895702              <1> 	mov	[bx+2], dx
   380                              <1> 	;
   381                              <1> 	;pop	bx
   382 00000289 C3                  <1> 	retn
   383                              <1> 
   384                              <1> L16:	; 28/05/2016
   186                                  
   187                                  	; 10/11/2014
   188 0000028A 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 0000028B B080                    	mov   	al, 80h 
   197 0000028D E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   198                                  	;23/02/2015
   199 0000028F 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 00000290 31C0                    	xor	ax, ax
   208 00000292 8EC0                    	mov	es, ax ; ES = 0
   209                                  	;
   210 00000294 B90040                  	mov	cx, (KEND - KLOAD)/4
   211 00000297 31F6                    	xor	si, si
   212 00000299 31FF                    	xor	di, di
   213 0000029B F366A5                  	rep	movsd
   214                                  	;
   215 0000029E 06                      	push	es ; 0
   216 0000029F 68[A302]                	push	L17
   217 000002A2 CB                      	retf
   218                                  	;
   219                                  L17:
   220                                  	; Turn off the floppy drive motor
   221 000002A3 BAF203                          mov     dx, 3F2h
   222 000002A6 EE                              out     dx, al ; 0 ; 31/12/2013
   223                                  
   224                                  	; Enable access to memory above one megabyte
   225                                  L18:
   226 000002A7 E464                    	in	al, 64h
   227 000002A9 A802                    	test	al, 2
   228 000002AB 75FA                            jnz     short L18
   229 000002AD B0D1                    	mov	al, 0D1h	; Write output port
   230 000002AF E664                    	out	64h, al
   231                                  L19:
   232 000002B1 E464                    	in	al, 64h
   233 000002B3 A802                    	test	al, 2
   234 000002B5 75FA                            jnz     short L19
   235 000002B7 B0DF                    	mov	al, 0DFh	; Enable A20 line
   236 000002B9 E660                    	out	60h, al
   237                                  ;L20:
   238                                  	;
   239                                  	; Load global descriptor table register
   240                                  
   241                                          ;mov     ax, cs
   242                                          ;mov     ds, ax
   243                                  
   244 000002BB 2E0F0116[60CA]                  lgdt    [cs:gdtd]
   245                                  
   246 000002C1 0F20C0                          mov     eax, cr0
   247                                  	; or 	eax, 1
   248 000002C4 40                      	inc     ax
   249 000002C5 0F22C0                  	mov     cr0, eax
   250                                  
   251                                  	; Jump to 32 bit code
   252                                  	
   253 000002C8 66                      	db 66h 			; Prefix for 32-bit
   254 000002C9 EA                      	db 0EAh 		; Opcode for far jump
   255 000002CA [D0020000]              	dd StartPM 		; Offset to start, 32-bit
   256                                  				; (1000h:StartPM = StartPM + 10000h)
   257 000002CE 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 000002D0 66B81000                	mov ax, KDATA           ; Save data segment identifier
   265 000002D4 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   266 000002D6 8EC0                           	mov es, ax              ; Move data segment into ES register
   267 000002D8 8EE0                           	mov fs, ax              ; Move data segment into FS register
   268 000002DA 8EE8                          	mov gs, ax              ; Move data segment into GS register
   269 000002DC 8ED0                            mov ss, ax              ; Move data segment into SS register
   270 000002DE BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   271                                  
   272                                  clear_bss: ; Clear uninitialized data area
   273                                  	; 11/03/2015
   274 000002E3 31C0                    	xor  eax, eax ; 0
   275 000002E5 B964080000              	mov  ecx, (bss_end - bss_start)/4
   276                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   277 000002EA BF[A0CF0000]            	mov  edi, bss_start	
   278 000002EF 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 000002F1 B108                    	mov	cl, 8
   293 000002F3 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   294 000002F8 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   295                                  				   ; for the first 1 MB memory
   296                                  	;
   297 000002FA 668B0D[62CF0000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   298                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   299 00000301 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   300 00000305 890D[90D20000]          	mov	[free_pages], ecx
   301 0000030B 668B15[64CF0000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   302                                  				   ; between 16 MB and 4 GB.	
   303 00000312 6609D2                  	or	dx, dx
   304 00000315 7413                    	jz	short mi_0
   305                                  	;
   306 00000317 6689D0                  	mov	ax, dx
   307 0000031A C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   308 0000031D 0105[90D20000]          	add	[free_pages], eax
   309 00000323 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   310 00000328 EB07                    	jmp	short mi_1
   311                                  mi_0:
   312 0000032A 6689C8                  	mov	ax, cx
   313 0000032D 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   314                                  mi_1:
   315 00000331 A3[8CD20000]            	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 00000336 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   320 0000033B 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 0000033E 66A3[A0D20000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   324 00000344 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   325                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   326 00000347 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   327                                  	; Set/Calculate Kernel's Page Directory Address
   328 00000349 81C300001000            	add	ebx, MEM_ALLOC_TBL
   329 0000034F 891D[88D20000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   330                                  				   ; just after the last M.A.T. page
   331                                  	;
   332 00000355 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   333 00000358 A3[98D20000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   334                                  	;			   ; (allocation status search must be 
   335                                  				   ; stopped after here)	
   336 0000035D 31C0                    	xor	eax, eax
   337 0000035F 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   338 00000360 6651                    	push	cx
   339 00000362 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   340                                  				   ; count of 32 allocation bits
   341 00000365 F3AB                    	rep	stosd
   342 00000367 6659                    	pop	cx
   343 00000369 40                      	inc	eax		   ; 0	
   344 0000036A 80E11F                  	and	cl, 31		   ; remain bits
   345 0000036D 7412                    	jz	short mi_4
   346 0000036F 8907                    	mov	[edi], eax	   ; reset	
   347                                  mi_2:
   348 00000371 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   349 00000374 FEC9                    	dec	cl
   350 00000376 7404                    	jz	short mi_3
   351 00000378 FEC0                    	inc	al
   352 0000037A EBF5                    	jmp	short mi_2
   353                                  mi_3:
   354 0000037C 28C0                    	sub	al, al	   	   ; 0
   355 0000037E 83C704                  	add	edi, 4		   ; 15/11/2014
   356                                  mi_4:
   357 00000381 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   358 00000384 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   359                                  	;	
   360 00000386 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   361                                  	;	
   362 0000038B 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   363 0000038D 7406                    	jz	short mi_5	  ; jump if EDI points to 
   364                                  				  ;         end of first 16 MB	
   365 0000038F D1E9                    	shr	ecx, 1		  ; convert to dword count
   366 00000391 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   367 00000393 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   368                                  				  ; (memory hole under 16 MB)
   369                                  mi_5:
   370 00000395 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   371 00000398 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   372 0000039A 9C                      	pushf			  ; 16/11/2014		
   373 0000039B 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   374 0000039C F3AB                    	rep	stosd
   375 0000039E 40                      	inc	eax		  ; 0
   376 0000039F 9D                      	popf			  ; 16/11/2014
   377 000003A0 7305                    	jnc	short mi_6
   378 000003A2 6648                    	dec	ax		  ; eax = 0000FFFFh
   379 000003A4 AB                      	stosd
   380 000003A5 6640                    	inc	ax		  ; 0		
   381                                  mi_6:
   382 000003A7 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   383 000003A9 730A                    	jnb	short mi_7	  ; end of memory allocation table
   384                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   385 000003AB 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   386 000003AD 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   387 000003AF D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   388 000003B1 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   389 000003B3 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 000003B5 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 000003BA 668B0D[A0D20000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   396 000003C1 89D7                    	mov	edi, edx
   397 000003C3 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 000003C6 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   405                                  	; eax = 0
   406 000003C8 290D[90D20000]          	sub	[free_pages], ecx ; 07/11/2014
   407                                  mi_8:
   408 000003CE 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   409                                  	;dec	bl
   410 000003D1 FEC9                    	dec	cl
   411 000003D3 7404                    	jz	short mi_9
   412 000003D5 FEC0                    	inc	al
   413 000003D7 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 000003D9 8B0D[8CD20000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   421 000003DF 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   422 000003E5 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   423                                  				 ; page table count (PDE count)
   424                                  	;
   425 000003E8 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   426                                  	;
   427 000003E9 41                      	inc	ecx		 ; +1 for kernel page directory	
   428                                  	;
   429 000003EA 290D[90D20000]          	sub	[free_pages], ecx ; 07/11/2014
   430                                  	;
   431 000003F0 8B35[88D20000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   432 000003F6 C1EE0C                  	shr	esi, 12		 ; convert to page number
   433                                  mi_10:
   434 000003F9 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   435 000003FB 89C3                    	mov	ebx, eax
   436 000003FD C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   437 00000400 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   438                                  				 ;   to align on dword boundary
   439 00000403 83E01F                  	and	eax, 31		 ; set allocation bit position 
   440                                  				 ;  (bit 0 to bit 31)
   441                                  	;
   442 00000406 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   443                                  	;
   444 00000408 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   445                                  	;
   446 0000040B 46                      	inc	esi		 ; next page table
   447 0000040C E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   448                                  				 ; (ecx = page table count + 1)		
   449                                  	;
   450 0000040E 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 0000040F 8B3D[88D20000]          	mov	edi, [k_page_dir]
   456 00000415 89F8                    	mov	eax, edi
   457 00000417 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   458                                  		     	      ; supervisor + read&write + present
   459 00000419 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   460                                  mi_11:
   461 0000041B 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   462                                  			        ; EAX points to next page table
   463 00000420 AB                      	stosd
   464 00000421 E2F8                    	loop	mi_11
   465 00000423 29C0                    	sub	eax, eax	; Empty PDE
   466 00000425 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   467 00000429 29D1                    	sub	ecx, edx
   468 0000042B 7402                    	jz	short mi_12
   469 0000042D 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 0000042F 8B0D[8CD20000]          	mov	ecx, [memory_size] ; memory size in pages
   478 00000435 89CA                    	mov	edx, ecx	; (***)
   479 00000437 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
   480                                  			     ; supervisor + read&write + present 	
   481                                  mi_13:
   482 00000439 AB                      	stosd
   483 0000043A 0500100000              	add	eax, 4096	
   484 0000043F E2F8                    	loop	mi_13	
   485 00000441 6681E2FF03              	and	dx, 1023	; (***)
   486 00000446 740B                    	jz	short mi_14
   487 00000448 66B90004                	mov	cx, 1024	
   488 0000044C 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
   489 0000044F 31C0                    	xor	eax, eax
   490 00000451 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 00000453 89F8                    	mov	eax, edi	; end of the last page table page
   496                                  			        ; (beginging of user space pages)
   497 00000455 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
   498 00000458 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
   499                                  				; aligning on dword boundary	
   500                                  	 
   501 0000045A A3[9CD20000]            	mov	[first_page], eax
   502 0000045F A3[94D20000]            	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 00000464 A1[88D20000]                    mov     eax, [k_page_dir]
   512 00000469 0F22D8                  	mov	cr3, eax
   513 0000046C 0F20C0                  	mov	eax, cr0
   514 0000046F 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
   515 00000474 0F22C0                  	mov	cr0, eax
   516                                          ;jmp    KCODE:StartPMP
   517                                  
   518 00000477 EA                      	db 0EAh 		; Opcode for far jump
   519 00000478 [7E040000]                      dd StartPMP		; 32 bit offset
   520 0000047C 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 0000047E B9E8030000              	mov	ecx, 80*25/2
   530 00000483 BF00800B00              	mov	edi, 0B8000h
   531                                  	; 30/01/2016
   532                                  	;xor	eax, eax	; black background, black fore color
   533 00000488 B800070007              	mov	eax, 07000700h  ; black background, light gray fore color
   534 0000048D 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 0000048F BE[66CF0000]            	mov	esi, starting_msg
   543                                  	;; 14/08/2015 (kernel version message will appear
   544                                  	;;	       when protected mode and paging is enabled)
   545 00000494 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
   546 00000499 B40A                    	mov	ah, 0Ah ; Black background, light green forecolor
   547                                  	; 20/08/2014
   548 0000049B E880010000              	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 000004A0 B011                    	mov	al, 11h			; Initialization sequence
   557 000004A2 E620                    	out	20h, al			; 	8259A-1
   558                                  	; jmp 	$+2
   559 000004A4 E6A0                    	out	0A0h, al		; 	8259A-2
   560                                  					;; ICW2
   561 000004A6 B020                    	mov	al, 20h			; Start of hardware ints (20h)
   562 000004A8 E621                    	out	21h, al			;	for 8259A-1
   563                                  	; jmp 	$+2
   564 000004AA B028                    	mov	al, 28h			; Start of hardware ints (28h)
   565 000004AC E6A1                    	out	0A1h, al		; 	for 8259A-2
   566                                  					;
   567 000004AE B004                    	mov	al, 04h			;; ICW3
   568 000004B0 E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
   569                                  	; jmp 	$+2
   570 000004B2 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
   571 000004B4 E6A1                    	out	0A1h, al		;
   572                                  					;; ICW4
   573 000004B6 B001                    	mov	al, 01h	 		;
   574 000004B8 E621                    	out	21h, al			; 	8086 mode, normal EOI	
   575                                  	; jmp 	$+2
   576 000004BA 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 000004BC BE[6CCA0000]            	mov	esi, ilist
   594 000004C1 8D3D[A0CF0000]          	lea	edi, [idt]
   595                                  	; 26/03/2015
   596 000004C7 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
   597                                  	; 02/04/2015
   598 000004CC BB00000800              	mov	ebx,  80000h
   599                                  rp_sidt1:
   600 000004D1 AD                      	lodsd
   601 000004D2 89C2                    	mov	edx, eax
   602 000004D4 66BA008E                	mov	dx, 8E00h
   603 000004D8 6689C3                  	mov	bx, ax
   604 000004DB 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
   605                                         			        ; /* interrupt gate - dpl=0, present */
   606 000004DD AB                      	stosd	; selector & offset bits 0-15 	
   607 000004DE 89D0                    	mov	eax, edx
   608 000004E0 AB                      	stosd	; attributes & offset bits 16-23
   609 000004E1 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 000004E3 B120                    	mov	cl, 32	      ;  16 software interrupts (INT 30h to INT 4Fh)	
   614                                  rp_sidt2:
   615 000004E5 AD                      	lodsd
   616 000004E6 21C0                    	and	eax, eax
   617 000004E8 7413                    	jz	short rp_sidt3
   618 000004EA 89C2                    	mov	edx, eax
   619 000004EC 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   620 000004F0 6689C3                  	mov	bx, ax
   621 000004F3 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   622 000004F5 AB                      	stosd
   623 000004F6 89D0                    	mov	eax, edx
   624 000004F8 AB                      	stosd
   625 000004F9 E2EA                    	loop	rp_sidt2
   626 000004FB EB16                    	jmp	short sidt_OK
   627                                  rp_sidt3:
   628 000004FD B8[8B090000]            	mov	eax, ignore_int
   629 00000502 89C2                    	mov	edx, eax
   630 00000504 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   631 00000508 6689C3                  	mov	bx, ax
   632 0000050B 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   633                                  rp_sidt4:
   634 0000050D AB                      	stosd
   635 0000050E 92                      	xchg	eax, edx
   636 0000050F AB                      	stosd
   637 00000510 92                      	xchg	edx, eax
   638 00000511 E2FA                    	loop	rp_sidt4
   639                                  sidt_OK: 
   640 00000513 0F011D[66CA0000]        	lidt 	[idtd]
   641                                  	;
   642                                  	; TSS descriptor setup ; 24/03/2015
   643 0000051A B8[20D20000]            	mov	eax, task_state_segment
   644 0000051F 66A3[5ACA0000]          	mov	[gdt_tss0], ax
   645 00000525 C1C010                  	rol	eax, 16
   646 00000528 A2[5CCA0000]            	mov	[gdt_tss1], al
   647 0000052D 8825[5FCA0000]          	mov	[gdt_tss2], ah
   648 00000533 66C705[86D20000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
   648 0000053B 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 0000053C 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 00000540 0F00D8                  	ltr	ax  ; Load task register
   663                                  	;
   664                                  esp0_set0:
   665                                  	; 30/07/2015
   666 00000543 8B0D[8CD20000]          	mov 	ecx, [memory_size] ; memory size in pages
   667 00000549 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
   668 0000054C 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
   669                                  			  ; (kernel mode virtual address)
   670 00000552 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 00000554 B900004000              	mov	ecx, CORE
   677                                  esp0_set1:
   678 00000559 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
   679                                  esp0_set_ok:
   680                                  	; 30/07/2015 (**tss.esp0**) 
   681 0000055B 8925[24D20000]          	mov	[tss.esp0], esp
   682 00000561 66C705[28D20000]10-             mov     word [tss.ss0], KDATA
   682 00000569 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 0000056A 30C0                    	xor	al, al		; Enable all hardware interrupts!
   690 0000056C E621                    	out	21h, al		; (IBM PC-AT compatibility)
   691 0000056E EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
   692 00000570 E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
   693                                  				; (Even if related hardware component
   694                                  				;  does not exist!)
   695                                  	; Enable NMI 
   696 00000572 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
   697 00000574 E670                    	out  	70h, al
   698                                  	; 23/02/2015
   699 00000576 90                      	nop
   700 00000577 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 00000579 6631DB                  	xor	bx, bx
   707 0000057C 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
   708 00000580 E8EE110000              	call	_set_cpos	; 24/01/2016
   709                                  	;
   710                                  	; 06/11/2014
   711 00000585 E8CF120000              	call	memory_info
   712                                  	; 14/08/2015
   713                                  	;call getch ; 28/02/2015
   714                                  drv_init:
   715 0000058A FB                      	sti	; Enable Interrupts 
   716                                  	; 06/02/2015
   717 0000058B 8B15[90CD0000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   718 00000591 668B1D[8ECD0000]        	mov	bx, [fd0_type] ; fd0, fd1
   719                                  	; 22/02/2015
   720 00000598 6621DB                  	and	bx, bx
   721 0000059B 751C                    	jnz	short di1
   722                                  	;
   723 0000059D 09D2                    	or 	edx, edx
   724 0000059F 752A                    	jnz	short di2
   725                                  	;
   726                                  setup_error:
   727 000005A1 BE[69CE0000]            	mov 	esi, setup_error_msg
   728                                  psem:	
   729 000005A6 AC                      	lodsb
   730 000005A7 08C0                    	or	al, al
   731                                  	;jz	short haltx ; 22/02/2015
   732 000005A9 7427                    	jz	short di3
   733 000005AB 56                      	push	esi
   734                                  	; 13/05/2016
   735 000005AC BB07000000              	mov	ebx, 7	; Black background, 
   736                                  			; light gray forecolor
   737                                  			; Video page 0 (BH=0)
   738 000005B1 E832110000              	call	_write_tty
   739 000005B6 5E                      	pop	esi
   740 000005B7 EBED                    	jmp	short psem
   741                                  
   742                                  di1:
   743                                  	; supress 'jmp short T6'
   744                                  	;  (activate fdc motor control code)
   745 000005B9 66C705[A0060000]90-     	mov	word [T5], 9090h ; nop
   745 000005C1 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 000005C2 E801220000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   756                                  	;
   757 000005C7 09D2                    	or	edx, edx
   758 000005C9 7407                            jz      short di3
   759                                  di2:
   760 000005CB E83E220000              	call   	DISK_SETUP	; Initialize Fixed Disks
   761 000005D0 72CF                            jc      short setup_error
   762                                  di3:
   763 000005D2 E856120000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   764                                  	;
   765 000005D7 E8A6C30000              	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 000005DC E8CC380000              	call	sys_init
   795                                  	;
   796                                  	;jmp 	cpu_reset ; 22/02/2015
   797                                  hang:  
   798                                  	; 23/02/2015
   799                                  	;sti			; Enable interrupts
   800 000005E1 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 000005E2 31DB                    	xor	ebx, ebx
   813 000005E4 8A1D[B8D20000]          	mov	bl, [ptty]	; active_page
   814 000005EA 89DE                    	mov	esi, ebx
   815 000005EC 66D1E6                  	shl 	si, 1
   816 000005EF 81C6[BAD20000]          	add	esi, ttychr
   817 000005F5 668B06                  	mov	ax, [esi]
   818 000005F8 6621C0                  	and	ax, ax
   819                                  	;jz	short _c8
   820 000005FB 74E4                    	jz	short hang
   821 000005FD 66C7060000              	mov	word [esi], 0
   822 00000602 80FB03                  	cmp	bl, 3		; Video page 3
   823                                  	;jb	short _c8
   824 00000605 72DA                    	jb	short hang
   825                                  	;	
   826                                  	; 13/05/2016
   827                                  	; 07/09/2014
   828                                  nxtl:
   829 00000607 6653                    	push	bx
   830 00000609 66BB0E00                	mov	bx, 0Eh 	; Yellow character 
   831                                  				; on black background
   832                                  				; bh = 0 (video page 0)
   833                                  				; Retro UNIX 386 v1 - Video Mode 0
   834                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
   835 0000060D 6650                    	push	ax
   836 0000060F E8D4100000              	call 	_write_tty
   837 00000614 6658                    	pop	ax
   838 00000616 665B                    	pop	bx
   839 00000618 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
   840                                  	;jne	short _c8
   841 0000061A 75C5                    	jne	short hang
   842 0000061C B00A                    	mov	al, 0Ah		; next line
   843 0000061E EBE7                    	jmp	short nxtl
   844                                  	
   845                                  ;_c8:
   846                                  ;	; 25/08/2014
   847                                  ;	cli				; Disable interrupts
   848                                  ;	mov	al, [scounter + 1]
   849                                  ;	and	al, al
   850                                  ;	jnz	hang
   851                                  ;	call	rtc_p
   852                                  ;	jmp     hang
   853                                  
   854                                  
   855                                  	; 27/08/2014
   856                                  	; 20/08/2014
   857                                  printk:
   858                                          ;mov    edi, [scr_row]
   859                                  pkl:
   860 00000620 AC                      	lodsb
   861 00000621 08C0                    	or 	al, al
   862 00000623 7404                    	jz	short pkr
   863 00000625 66AB                    	stosw
   864 00000627 EBF7                    	jmp	short pkl
   865                                  pkr:
   866 00000629 C3                      	retn
   867                                  
   868                                  ; 23/05/2016
   869                                  ; 22/05/2016 - TRDOS 386 (TRDOS v2.0) Timer Event Modifications
   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 0000062A 1E                      	push	ds
   901 0000062B 06                      	push	es
   902 0000062C 0FA0                    	push	fs
   903 0000062E 0FA8                    	push	gs
   904 00000630 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
   905 00000631 66B91000                	mov     cx, KDATA
   906 00000635 8ED9                            mov     ds, cx
   907 00000637 8EC1                            mov     es, cx
   908 00000639 8EE1                            mov     fs, cx
   909 0000063B 8EE9                            mov     gs, cx
   910                                  	;
   911 0000063D 0F20D9                  	mov	ecx, cr3
   912 00000640 890D[08F00000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   913                                  	;
   914 00000646 3B0D[88D20000]          	cmp 	ecx, [k_page_dir]
   915 0000064C 741F                    	je	short T3
   916                                  	;
   917                                  	; timer interrupt has been occurred while OS is in user mode
   918 0000064E A3[48E30000]            	mov 	[u.r0], eax
   919 00000653 89E1                    	mov	ecx, esp
   920 00000655 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   921 00000658 890D[40E30000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   922 0000065E 8925[44E30000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   923                                  	;
   924 00000664 8B0D[88D20000]          	mov	ecx, [k_page_dir]
   925 0000066A 0F22D9                  	mov	cr3, ecx
   926                                  T3:
   927                                  	;sti				; INTERRUPTS BACK ON
   928 0000066D 66FF05[0AD30000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   929 00000674 7507                    	JNZ	short T4		; GO TO TEST_DAY
   930 00000676 66FF05[0CD30000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   931                                  T4:					; TEST_DAY
   932 0000067D 66833D[0CD30000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
   933 00000685 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
   934 00000687 66813D[0AD30000]B0-     	CMP	word [TIMER_LOW],0B0H
   934 0000068F 00                 
   935 00000690 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 00000692 29C0                    	sub	eax, eax
   942 00000694 A3[0AD30000]            	mov	[TIMER_LH], eax
   943                                  	;	
   944 00000699 C605[0ED30000]01        	MOV	byte [TIMER_OFL],1
   945                                  
   946                                  ;-----	TEST FOR DISKETTE TIME OUT
   947                                  
   948                                  T5:
   949                                  	; 23/12/2014
   950 000006A0 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 000006A2 A0[11D30000]            	mov	al, [MOTOR_COUNT]
   955 000006A7 FEC8                    	dec	al
   956                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
   957 000006A9 A2[11D30000]            	mov	[MOTOR_COUNT], al
   958                                  	;mov	[ORG_MOTOR_COUNT], al
   959 000006AE 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
   960 000006B0 B0F0                    	mov 	al,0F0h
   961                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
   962 000006B2 2005[10D30000]          	and	[MOTOR_STATUS], al
   963                                  	;and	[ORG_MOTOR_STATUS], al
   964 000006B8 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 000006BA 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
   971 000006BE 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 000006BF E87F030000              	call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
   979                                  	; 23/05/2016
   980 000006C4 E8B6B80000              	call	clock			; Multi Tasking control procedure
   981                                  T7:
   982                                  	; 14/10/2015
   983 000006C9 B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
   984                                  	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
   985 000006CB E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
   986                                  	;
   987                                  	; 23/05/2016
   988                                  rtc_int_2:
   989                                  	; 22/05/2016
   990 000006CD 803D[09E00000]00        	cmp	byte [p_change], 0 ; in 'set_run_sequence', in 'rtc_p'
   991 000006D4 7615                    	jna	short timer_int_return ; 23/05/2016	
   992                                  	; present process must be changed with high priority process	
   993 000006D6 30C0                    	xor	al, al
   994 000006D8 A2[09E00000]            	mov	[p_change], al ; 0
   995                                  	;
   996 000006DD 803D[3FE30000]FF        	cmp     byte [sysflg], 0FFh ; user or system space ?
   997 000006E4 7415                    	je	short rtc_int_3     ; user space ([sysflg]= 0FFh)
   998                                  
   999                                  	; system space, wait for 'sysret'
  1000                                  	; to change running process 	
  1001                                  	; with high priority (event) process
  1002                                  
  1003 000006E6 A2[8AE30000]            	mov	[u.quant], al ; 0
  1004                                  
  1005                                  timer_int_return: ; 23/05/2016 - jump from 'rtc_int' ('rtc_int_2')
  1006 000006EB A1[08F00000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1007 000006F0 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1008                                  	;
  1009 000006F3 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1010                                  	;
  1011 000006F4 0FA9                    	pop	gs
  1012 000006F6 0FA1                    	pop	fs
  1013 000006F8 07                      	pop	es
  1014 000006F9 1F                      	pop	ds
  1015 000006FA CF                      	iretd	; return from interrupt
  1016                                  
  1017                                  rtc_int_3:
  1018 000006FB FE05[3FE30000]          	inc	byte [sysflg] 	; now, we are in system space
  1019                                  	;
  1020 00000701 E9FD990000                      jmp     sysrelease ; change running process immediatelly 
  1021                                  
  1022                                  	; 23/05/2016
  1023                                  	; 22/05/2016
  1024                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1025                                  	; 26/02/2015
  1026                                  	; 07/09/2014
  1027                                  	; 25/08/2014
  1028                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1029                                  	; 22/05/2016
  1030 00000706 1E                      	push	ds ; ** ; 23/05/2016
  1031 00000707 50                      	push	eax ; *
  1032 00000708 66B81000                	mov	ax, KDATA
  1033 0000070C 8ED8                    	mov	ds, ax
  1034                                  	;
  1035 0000070E 8A25[08D30000]          	mov	ah, [RTC_2Hz] ;  2 Hz interrupt to 1 Hz function
  1036 00000714 80F401                  	xor	ah, 1
  1037 00000717 8825[08D30000]          	mov	[RTC_2Hz], ah ; 1 = 0.5 second, 0 = 1 second
  1038 0000071D 754A                    	jnz	short rtc_int_return ; half second
  1039                                  	; 1 second
  1040                                  rtc_int_0:
  1041                                  	; 22/05/2016
  1042 0000071F 58                      	pop	eax ; *
  1043                                  	;
  1044                                  	; 14/10/2015 ('timer_int')
  1045                                  	; Here, we are simulating system call entry (for task switch)
  1046                                  	; (If multitasking is enabled, 
  1047                                  	; 'clock' procedure may jump to 'sysrelease')
  1048                                  	;push	ds ; ** ; 23/05/2016
  1049 00000720 06                      	push	es
  1050 00000721 0FA0                    	push	fs
  1051 00000723 0FA8                    	push	gs
  1052 00000725 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1053 00000726 66B91000                	mov     cx, KDATA
  1054 0000072A 8ED9                            mov     ds, cx
  1055 0000072C 8EC1                            mov     es, cx
  1056 0000072E 8EE1                            mov     fs, cx
  1057 00000730 8EE9                            mov     gs, cx
  1058                                  	;
  1059 00000732 0F20D9                  	mov	ecx, cr3
  1060 00000735 890D[08F00000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1061                                  	;
  1062 0000073B 3B0D[88D20000]          	cmp 	ecx, [k_page_dir]
  1063 00000741 741F                    	je	short rtc_int_1
  1064                                  	;
  1065                                  	; timer interrupt has been occurred while OS is in user mode
  1066 00000743 A3[48E30000]            	mov 	[u.r0], eax
  1067 00000748 89E1                    	mov	ecx, esp
  1068 0000074A 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1069 0000074D 890D[40E30000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1070 00000753 8925[44E30000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1071                                  	;
  1072 00000759 8B0D[88D20000]          	mov	ecx, [k_page_dir]
  1073 0000075F 0F22D9                  	mov	cr3, ecx
  1074                                  
  1075                                  rtc_int_1:
  1076                                  	; Timer event (kernel) functions must be performed with
  1077                                  	; 1 second intervals - TRDOS 386 (TRDOS v2.0) feature ! -
  1078                                   	;	
  1079                                  	; 25/08/2014
  1080 00000762 E8DC020000              	call	rtc_p  ; 19/05/2016 - major modification 
  1081                                  	; 23/05/2016
  1082 00000767 28E4                    	sub	ah, ah ; 0
  1083                                  	; 22/05/2016 - TRDOS 386 timer event modifications
  1084                                  rtc_int_return: ; 19/05/2016
  1085                                  	; 22/02/2015 - dsectpm.s
  1086                                  	; [ source: http://wiki.osdev.org/RTC ]
  1087                                  	; read status register C to complete procedure
  1088                                  	;(it is needed to get a next IRQ 8) 
  1089 00000769 B00C                    	mov	al, 0Ch ; 
  1090 0000076B E670                    	out	70h, al ; select register C
  1091 0000076D 90                      	nop
  1092 0000076E E471                    	in	al, 71h ; just throw away contents
  1093                                  	; 22/02/2015
  1094 00000770 B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1095                                  	;CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1096 00000772 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1097                                  
  1098                                  	; 23/05/2016
  1099 00000774 B020                    	MOV	AL,EOI		; GET END OF INTERRUPT MASK
  1100                                  	;CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1101 00000776 E620                    	OUT	INTA00,AL	; END OF INTERRUPT TO 8259 - 1	
  1102                                  	;
  1103                                  	; 23/05/2016
  1104 00000778 20E4                    	and	ah, ah
  1105 0000077A 0F844DFFFFFF                    jz      rtc_int_2
  1106                                  	
  1107                                  	; ah = 1 (half second)
  1108 00000780 58                      	pop	eax ; *
  1109 00000781 1F                      	pop	ds  ; **
  1110 00000782 CF                      	iretd
  1111                                  
  1112                                  ; ////////////////
  1113                                  
  1114                                  	; 28/08/2014
  1115                                  irq0:
  1116 00000783 6A00                            push 	dword 0
  1117 00000785 EB48                    	jmp	short which_irq
  1118                                  irq1:
  1119 00000787 6A01                            push 	dword 1
  1120 00000789 EB44                    	jmp	short which_irq
  1121                                  irq2:
  1122 0000078B 6A02                            push 	dword 2
  1123 0000078D EB40                    	jmp	short which_irq
  1124                                  irq3:
  1125                                  	; 20/11/2015
  1126                                  	; 24/10/2015
  1127 0000078F 2EFF15[DCC10000]        	call	dword [cs:com2_irq3]
  1128 00000796 6A03                    	push 	dword 3
  1129 00000798 EB35                    	jmp	short which_irq
  1130                                  irq4:
  1131                                  	; 20/11/2015
  1132                                  	; 24/10/2015
  1133 0000079A 2EFF15[D8C10000]        	call	dword [cs:com1_irq4]
  1134 000007A1 6A04                            push 	dword 4
  1135 000007A3 EB2A                    	jmp	short which_irq
  1136                                  irq5:
  1137 000007A5 6A05                            push 	dword 5
  1138 000007A7 EB26                    	jmp	short which_irq
  1139                                  irq6:
  1140 000007A9 6A06                            push 	dword 6
  1141 000007AB EB22                    	jmp	short which_irq
  1142                                  irq7:
  1143 000007AD 6A07                            push 	dword 7
  1144 000007AF EB1E                    	jmp	short which_irq
  1145                                  irq8:
  1146 000007B1 6A08                            push 	dword 8
  1147 000007B3 EB1A                    	jmp	short which_irq
  1148                                  irq9:
  1149 000007B5 6A09                            push 	dword 9
  1150 000007B7 EB16                    	jmp	short which_irq
  1151                                  irq10:
  1152 000007B9 6A0A                            push 	dword 10
  1153 000007BB EB12                    	jmp	short which_irq
  1154                                  irq11:
  1155 000007BD 6A0B                            push 	dword 11
  1156 000007BF EB0E                    	jmp	short which_irq
  1157                                  irq12:
  1158 000007C1 6A0C                            push 	dword 12
  1159 000007C3 EB0A                    	jmp	short which_irq
  1160                                  irq13:
  1161 000007C5 6A0D                            push 	dword 13
  1162 000007C7 EB06                    	jmp	short which_irq
  1163                                  irq14:
  1164 000007C9 6A0E                            push 	dword 14
  1165 000007CB EB02                    	jmp	short which_irq
  1166                                  irq15:
  1167 000007CD 6A0F                            push 	dword 15
  1168                                  	;jmp	short which_irq
  1169                                  
  1170                                  	; 19/10/2015
  1171                                  	; 29/08/2014
  1172                                  	; 21/08/2014
  1173                                  which_irq:
  1174 000007CF 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1175 000007D2 53                      	push	ebx
  1176 000007D3 56                      	push	esi
  1177 000007D4 57                      	push	edi
  1178 000007D5 1E                      	push 	ds
  1179 000007D6 06                      	push 	es
  1180                                  	;
  1181 000007D7 88C3                    	mov	bl, al
  1182                                  	;
  1183 000007D9 B810000000              	mov	eax, KDATA
  1184 000007DE 8ED8                    	mov	ds, ax
  1185 000007E0 8EC0                    	mov	es, ax
  1186                                  	; 19/10/2015
  1187 000007E2 FC                      	cld
  1188                                          ; 27/08/2014
  1189 000007E3 8105[E8CD0000]A000-             add     dword [scr_row], 0A0h
  1189 000007EB 0000               
  1190                                  	;
  1191 000007ED B417                    	mov	ah, 17h	; blue (1) background, 
  1192                                  			; light gray (7) forecolor
  1193 000007EF 8B3D[E8CD0000]                  mov     edi, [scr_row]
  1194 000007F5 B049                    	mov	al, 'I'
  1195 000007F7 66AB                    	stosw
  1196 000007F9 B052                    	mov	al, 'R'
  1197 000007FB 66AB                    	stosw
  1198 000007FD B051                    	mov	al, 'Q'
  1199 000007FF 66AB                    	stosw
  1200 00000801 B020                    	mov	al, ' '
  1201 00000803 66AB                    	stosw
  1202 00000805 88D8                    	mov	al, bl
  1203 00000807 3C0A                    	cmp	al, 10
  1204 00000809 7208                    	jb	short iix
  1205 0000080B B031                    	mov	al, '1'
  1206 0000080D 66AB                    	stosw
  1207 0000080F 88D8                    	mov	al, bl
  1208 00000811 2C0A                    	sub	al, 10
  1209                                  iix:
  1210 00000813 0430                    	add	al, '0'
  1211 00000815 66AB                    	stosw
  1212 00000817 B020                    	mov	al, ' '
  1213 00000819 66AB                    	stosw
  1214 0000081B B021                    	mov	al, '!'
  1215 0000081D 66AB                    	stosw
  1216 0000081F B020                    	mov	al, ' '
  1217 00000821 66AB                    	stosw
  1218                                  	; 23/02/2015
  1219 00000823 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1220 00000826 0F8695010000            	jna	iiret
  1221 0000082C B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1222 0000082E E6A0                    	out	0A0h, al ; the 2nd 8259
  1223 00000830 E98C010000              	jmp     iiret
  1224                                  	;
  1225                                  	; 22/08/2014
  1226                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1227                                  	;out	20h, al	; 8259 PORT
  1228                                  	;
  1229                                  	;pop	es
  1230                                  	;pop	ds
  1231                                  	;pop	edi
  1232                                  	;pop	esi
  1233                                  	;pop	ebx
  1234                                  	;pop 	eax
  1235                                  	;iret
  1236                                  
  1237                                  	; 02/04/2015
  1238                                  	; 25/08/2014
  1239                                  exc0:
  1240 00000835 6A00                            push 	dword 0
  1241 00000837 E990000000                      jmp     cpu_except
  1242                                  exc1:
  1243 0000083C 6A01                            push 	dword 1
  1244 0000083E E989000000                      jmp     cpu_except
  1245                                  exc2:
  1246 00000843 6A02                            push 	dword 2
  1247 00000845 E982000000                      jmp     cpu_except
  1248                                  exc3:
  1249 0000084A 6A03                            push 	dword 3
  1250 0000084C EB7E                            jmp     cpu_except
  1251                                  exc4:
  1252 0000084E 6A04                            push 	dword 4
  1253 00000850 EB7A                            jmp     cpu_except
  1254                                  exc5:
  1255 00000852 6A05                            push 	dword 5
  1256 00000854 EB76                            jmp     cpu_except
  1257                                  exc6:
  1258 00000856 6A06                            push 	dword 6
  1259 00000858 EB72                            jmp     cpu_except
  1260                                  exc7:
  1261 0000085A 6A07                            push 	dword 7
  1262 0000085C EB6E                            jmp     cpu_except
  1263                                  exc8:
  1264                                  	; [esp] = Error code
  1265 0000085E 6A08                            push 	dword 8
  1266 00000860 EB5C                            jmp     cpu_except_en
  1267                                  exc9:
  1268 00000862 6A09                            push 	dword 9
  1269 00000864 EB66                            jmp     cpu_except
  1270                                  exc10:
  1271                                  	; [esp] = Error code
  1272 00000866 6A0A                            push 	dword 10
  1273 00000868 EB54                            jmp     cpu_except_en
  1274                                  exc11:
  1275                                  	; [esp] = Error code
  1276 0000086A 6A0B                            push 	dword 11
  1277 0000086C EB50                            jmp     cpu_except_en
  1278                                  exc12:
  1279                                  	; [esp] = Error code
  1280 0000086E 6A0C                            push 	dword 12
  1281 00000870 EB4C                            jmp     cpu_except_en
  1282                                  exc13:
  1283                                  	; [esp] = Error code
  1284 00000872 6A0D                            push 	dword 13
  1285 00000874 EB48                            jmp     cpu_except_en
  1286                                  exc14:
  1287                                  	; [esp] = Error code
  1288 00000876 6A0E                            push 	dword 14
  1289 00000878 EB44                    	jmp	short cpu_except_en
  1290                                  exc15:
  1291 0000087A 6A0F                            push 	dword 15
  1292 0000087C EB4E                            jmp     cpu_except
  1293                                  exc16:
  1294 0000087E 6A10                            push 	dword 16
  1295 00000880 EB4A                            jmp     cpu_except
  1296                                  exc17:
  1297                                  	; [esp] = Error code
  1298 00000882 6A11                            push 	dword 17
  1299 00000884 EB38                    	jmp	short cpu_except_en
  1300                                  exc18:
  1301 00000886 6A12                            push 	dword 18
  1302 00000888 EB42                    	jmp	short cpu_except
  1303                                  exc19:
  1304 0000088A 6A13                            push 	dword 19
  1305 0000088C EB3E                    	jmp	short cpu_except
  1306                                  exc20:
  1307 0000088E 6A14                            push 	dword 20
  1308 00000890 EB3A                    	jmp	short cpu_except
  1309                                  exc21:
  1310 00000892 6A15                            push 	dword 21
  1311 00000894 EB36                    	jmp	short cpu_except
  1312                                  exc22:
  1313 00000896 6A16                            push 	dword 22
  1314 00000898 EB32                    	jmp	short cpu_except
  1315                                  exc23:
  1316 0000089A 6A17                            push 	dword 23
  1317 0000089C EB2E                    	jmp	short cpu_except
  1318                                  exc24:
  1319 0000089E 6A18                            push 	dword 24
  1320 000008A0 EB2A                    	jmp	short cpu_except
  1321                                  exc25:
  1322 000008A2 6A19                            push 	dword 25
  1323 000008A4 EB26                    	jmp	short cpu_except
  1324                                  exc26:
  1325 000008A6 6A1A                            push 	dword 26
  1326 000008A8 EB22                    	jmp	short cpu_except
  1327                                  exc27:
  1328 000008AA 6A1B                            push 	dword 27
  1329 000008AC EB1E                    	jmp	short cpu_except
  1330                                  exc28:
  1331 000008AE 6A1C                            push 	dword 28
  1332 000008B0 EB1A                    	jmp	short cpu_except
  1333                                  exc29:
  1334 000008B2 6A1D                            push 	dword 29
  1335 000008B4 EB16                    	jmp	short cpu_except
  1336                                  exc30:
  1337 000008B6 6A1E                            push 	dword 30
  1338 000008B8 EB04                    	jmp	short cpu_except_en
  1339                                  exc31:
  1340 000008BA 6A1F                            push 	dword 31
  1341 000008BC EB0E                            jmp     short cpu_except
  1342                                  
  1343                                  	; 19/10/2015
  1344                                  	; 19/09/2015
  1345                                  	; 01/09/2015
  1346                                  	; 28/08/2015
  1347                                  	; 28/08/2014
  1348                                  cpu_except_en:
  1349 000008BE 87442404                	xchg	eax, [esp+4] ; Error code
  1350 000008C2 36A3[24F10000]          	mov	[ss:error_code], eax
  1351 000008C8 58                      	pop	eax  ; Exception number
  1352 000008C9 870424                  	xchg	eax, [esp]
  1353                                  		; eax = eax before exception
  1354                                  		; [esp] -> exception number
  1355                                  		; [esp+4] -> EIP to return
  1356                                  	; 19/10/2015
  1357                                  	; 19/09/2015
  1358                                  	; 01/09/2015
  1359                                  	; 28/08/2015
  1360                                  	; 29/08/2014
  1361                                  	; 28/08/2014
  1362                                  	; 25/08/2014
  1363                                  	; 21/08/2014
  1364                                  cpu_except:	; CPU Exceptions
  1365 000008CC FC                      	cld
  1366 000008CD 870424                  	xchg	eax, [esp] 
  1367                                  		; eax = Exception number
  1368                                  		; [esp] = eax (before exception)	
  1369 000008D0 53                      	push	ebx
  1370 000008D1 56                      	push	esi
  1371 000008D2 57                      	push	edi
  1372 000008D3 1E                      	push 	ds
  1373 000008D4 06                      	push 	es
  1374                                  	; 28/08/2015
  1375 000008D5 66BB1000                	mov	bx, KDATA
  1376 000008D9 8EDB                    	mov	ds, bx
  1377 000008DB 8EC3                    	mov	es, bx
  1378 000008DD 0F20DB                  	mov	ebx, cr3
  1379 000008E0 53                      	push	ebx ; (*) page directory
  1380                                  	; 19/10/2015
  1381 000008E1 FC                      	cld
  1382                                  	; 25/03/2015
  1383 000008E2 8B1D[88D20000]          	mov	ebx, [k_page_dir]
  1384 000008E8 0F22DB                  	mov	cr3, ebx
  1385                                  	; 28/08/2015
  1386 000008EB 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1387 000008EE 7512                    	jne	short cpu_except_nfp
  1388 000008F0 E83E2B0000              	call	page_fault_handler
  1389 000008F5 21C0                    	and 	eax, eax
  1390 000008F7 0F84C0000000                    jz	iiretp ; 01/09/2015
  1391 000008FD B80E000000              	mov	eax, 0Eh ; 14
  1392                                  cpu_except_nfp:
  1393                                  	; 02/04/2015
  1394 00000902 BB[E1050000]            	mov	ebx, hang
  1395 00000907 875C241C                	xchg	ebx, [esp+28]
  1396                                  		; EIP (points to instruction which faults)
  1397                                  	  	; New EIP (hang)
  1398 0000090B 891D[28F10000]          	mov	[FaultOffset], ebx
  1399 00000911 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1400 00000919 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1401                                  	;
  1402 00000921 88C4                    	mov	ah, al
  1403 00000923 240F                    	and	al, 0Fh
  1404 00000925 3C09                    	cmp	al, 9
  1405 00000927 7602                    	jna	short h1ok
  1406 00000929 0407                    	add	al, 'A'-':'
  1407                                  h1ok:
  1408 0000092B D0EC                    	shr	ah, 1
  1409 0000092D D0EC                    	shr	ah, 1
  1410 0000092F D0EC                    	shr	ah, 1
  1411 00000931 D0EC                    	shr	ah, 1
  1412 00000933 80FC09                  	cmp	ah, 9
  1413 00000936 7603                    	jna	short h2ok
  1414 00000938 80C407                  	add	ah, 'A'-':'
  1415                                  h2ok:	
  1416 0000093B 86E0                    	xchg 	ah, al	
  1417 0000093D 66053030                	add	ax, '00'
  1418 00000941 66A3[16CE0000]          	mov	[excnstr], ax
  1419                                  	;
  1420                                  	; 29/08/2014
  1421 00000947 A1[28F10000]            	mov	eax, [FaultOffset]
  1422 0000094C 51                      	push	ecx
  1423 0000094D 52                      	push	edx
  1424 0000094E 89E3                    	mov	ebx, esp
  1425                                  	; 28/08/2015
  1426 00000950 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1427                                  			  ; to hexadecimal string
  1428                                  	;mov	ecx, 10	    ; divisor to convert	
  1429                                  			    ; binary number to decimal string
  1430                                  b2d1:
  1431 00000955 31D2                    	xor	edx, edx
  1432 00000957 F7F1                    	div	ecx
  1433 00000959 6652                    	push	dx
  1434 0000095B 39C8                    	cmp	eax, ecx
  1435 0000095D 73F6                    	jnb	short b2d1
  1436 0000095F BF[21CE0000]            	mov	edi, EIPstr ; EIP value
  1437                                  			    ; points to instruction which faults	
  1438                                  	; 28/08/2015
  1439 00000964 89C2                    	mov	edx, eax
  1440                                  b2d2:
  1441                                  	;add	al, '0'
  1442 00000966 8A82[20190000]          	mov	al, [edx+hexchrs]
  1443 0000096C AA                      	stosb		    ; write hexadecimal digit to its place	
  1444 0000096D 39E3                    	cmp	ebx, esp
  1445 0000096F 7606                    	jna	short b2d3
  1446 00000971 6658                    	pop	ax
  1447 00000973 88C2                    	mov	dl, al
  1448 00000975 EBEF                    	jmp	short b2d2
  1449                                  b2d3:
  1450 00000977 B068                    	mov 	al, 'h' ; 28/08/2015
  1451 00000979 AA                      	stosb
  1452 0000097A B020                    	mov	al, 20h	    ; space
  1453 0000097C AA                      	stosb
  1454 0000097D 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1455 0000097F AA                      	stosb
  1456                                  	;
  1457 00000980 5A                      	pop	edx
  1458 00000981 59                      	pop	ecx
  1459                                  	;
  1460 00000982 B44F                    	mov	ah, 4Fh	; red (4) background, 
  1461                                  			; white (F) forecolor
  1462 00000984 BE[06CE0000]            	mov	esi, exc_msg ; message offset
  1463                                  	;
  1464 00000989 EB19                    	jmp	short piemsg
  1465                                  	;
  1466                                          ;add    dword [scr_row], 0A0h
  1467                                          ;mov    edi, [scr_row]
  1468                                          ;
  1469                                  	;call 	printk
  1470                                  	;
  1471                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1472                                  	;out	20h, al	; 8259 PORT
  1473                                  	;
  1474                                  	;pop	es
  1475                                  	;pop	ds
  1476                                  	;pop	edi
  1477                                  	;pop	esi
  1478                                  	;pop 	eax
  1479                                  	;iret
  1480                                  	
  1481                                  	; 18/04/2016
  1482                                  	; 28/08/2015
  1483                                  	; 23/02/2015
  1484                                  	; 20/08/2014
  1485                                  ignore_int:
  1486 0000098B 50                      	push	eax
  1487 0000098C 53                      	push	ebx ; 23/02/2015
  1488 0000098D 56                      	push	esi
  1489 0000098E 57                      	push	edi
  1490 0000098F 1E                      	push 	ds
  1491 00000990 06                      	push 	es
  1492                                  	; 18/04/2016
  1493 00000991 66B81000                	mov	ax, KDATA
  1494 00000995 8ED8                    	mov	ds, ax
  1495 00000997 8EC0                    	mov	es, ax
  1496                                  	; 28/08/2015
  1497 00000999 0F20D8                  	mov	eax, cr3
  1498 0000099C 50                      	push	eax ; (*) page directory
  1499                                  	;
  1500 0000099D B467                    	mov	ah, 67h	; brown (6) background, 
  1501                                  			; light gray (7) forecolor
  1502 0000099F BE[F0CD0000]            	mov	esi, int_msg ; message offset
  1503                                  piemsg:
  1504                                          ; 27/08/2014
  1505 000009A4 8105[E8CD0000]A000-             add     dword [scr_row], 0A0h
  1505 000009AC 0000               
  1506 000009AE 8B3D[E8CD0000]                  mov     edi, [scr_row]
  1507                                          ;
  1508 000009B4 E867FCFFFF              	call 	printk
  1509                                  	;
  1510                                  	; 23/02/2015
  1511 000009B9 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1512 000009BB E6A0                    	out	0A0h, al ; the 2nd 8259
  1513                                  iiretp: ; 01/09/2015
  1514                                  	; 28/08/2015
  1515 000009BD 58                      	pop	eax ; (*) page directory
  1516 000009BE 0F22D8                  	mov	cr3, eax
  1517                                  	;
  1518                                  iiret:
  1519                                  	; 22/08/2014
  1520 000009C1 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1521 000009C3 E620                    	out	20h, al	; 8259 PORT
  1522                                  	;
  1523 000009C5 07                      	pop	es
  1524 000009C6 1F                      	pop	ds
  1525 000009C7 5F                      	pop	edi
  1526 000009C8 5E                      	pop	esi
  1527 000009C9 5B                      	pop	ebx ; 29/08/2014
  1528 000009CA 58                      	pop 	eax
  1529 000009CB CF                      	iretd
  1530                                  
  1531                                  	; 23/05/2016
  1532                                  	; 22/08/2014
  1533                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  1534                                  	; (INT 1Ah)
  1535                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  1536                                  time_of_day:
  1537 000009CC E88C340000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  1538 000009D1 726F                            jc      short time_of_day_retn ; 23/05/2016
  1539 000009D3 B000                    	mov	al, CMOS_SECONDS
  1540 000009D5 E89E340000              	call	CMOS_READ
  1541 000009DA A2[FAD20000]            	mov	[time_seconds], al 
  1542 000009DF B002                    	mov	al, CMOS_MINUTES
  1543 000009E1 E892340000              	call	CMOS_READ
  1544 000009E6 A2[FBD20000]            	mov	[time_minutes], al 
  1545 000009EB B004                    	mov	al, CMOS_HOURS
  1546 000009ED E886340000              	call	CMOS_READ
  1547 000009F2 A2[FCD20000]                    mov     [time_hours], al
  1548 000009F7 B006                    	mov	al, CMOS_DAY_WEEK 
  1549 000009F9 E87A340000              	call	CMOS_READ
  1550 000009FE A2[FDD20000]            	mov	[date_wday], al
  1551 00000A03 B007                     	mov	al, CMOS_DAY_MONTH
  1552 00000A05 E86E340000              	call	CMOS_READ
  1553 00000A0A A2[FED20000]            	mov	[date_day], al
  1554 00000A0F B008                    	mov	al, CMOS_MONTH
  1555 00000A11 E862340000              	call	CMOS_READ
  1556 00000A16 A2[FFD20000]            	mov	[date_month], al
  1557 00000A1B B009                    	mov	al, CMOS_YEAR
  1558 00000A1D E856340000              	call	CMOS_READ
  1559 00000A22 A2[00D30000]            	mov	[date_year], al
  1560 00000A27 B032                    	mov	al, CMOS_CENTURY
  1561 00000A29 E84A340000              	call	CMOS_READ
  1562 00000A2E A2[01D30000]            	mov	[date_century], al
  1563                                  	;
  1564 00000A33 B000                    	mov	al, CMOS_SECONDS
  1565 00000A35 E83E340000              	call 	CMOS_READ
  1566 00000A3A 3A05[FAD20000]          	cmp	al, [time_seconds]
  1567 00000A40 758A                    	jne	short time_of_day
  1568                                  
  1569                                  time_of_day_retn:
  1570 00000A42 C3                      	retn
  1571                                  
  1572                                  	; 23/05/2016
  1573                                  u_timer: 
  1574                                  rtc_p:
  1575                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1576                                  	; Major Modification:
  1577                                  	; Check and Perform Timer Events (for RTC)
  1578                                  	; 25/08/2014 - 07/09/2014
  1579                                  	; Retro UNIX 386 v1:
  1580                                   	; Print Real Time Clock content
  1581                                  	
  1582 00000A43 BE[0CF00000]            	mov	esi, timer_set  ; beginning address of
  1583                                  				; timer events space
  1584                                  rtc_p1:
  1585 00000A48 8B06                    	mov	eax, [esi]	
  1586 00000A4A 6621C0                  	and	ax, ax ; 0 = free, >0 = process ID
  1587 00000A4D 742C                    	jz	short rtc_p4 ; free (the last event)
  1588                                  			     ; nothing to do	
  1589 00000A4F C1C810                  	ror	eax, 16
  1590                                  	; ah = response value, al = interrupt type
  1591 00000A52 3C01                    	cmp	al, 1 ; RTC interrupt ?
  1592 00000A54 740D                    	je	short rtc_p3 ; yes, check for response
  1593                                  rtc_p2:			
  1594 00000A56 81FE[FCF00000]          	cmp	esi, timer_set + 240 ; 15*16 (last event)
  1595 00000A5C 731D                    	jnb	short rtc_p4 ; end of timer event space
  1596 00000A5E 83C610                  	add	esi, 16 ; next timer event
  1597 00000A61 EBE5                    	jmp	short rtc_p1
  1598                                  rtc_p3:	
  1599 00000A63 FF4E08                  	dec	dword [esi+8] ; current timer count
  1600 00000A66 75EE                    	jnz	short rtc_p2  ; check for the next 
  1601                                  	
  1602                                  	; it is the time of response! 
  1603 00000A68 8B5E04                  	mov	ebx, [esi+4] ; set (count limit) value
  1604 00000A6B 895E08                  	mov	[esi+8], ebx ; reset count down value
  1605                                  			     ; to count limit
  1606                                  	; response address is physical address of
  1607                                  	; the program's response (signal return) byte
  1608 00000A6E 88660C                  	mov	[esi+12], ah  ; response value 
  1609                                  	;
  1610 00000A71 C1C010                  	rol	eax, 16
  1611                                  	; ax = process ID	
  1612 00000A74 E89CB40000              	call	set_run_sequence ; 19/05/2016
  1613 00000A79 EBDB                    	jmp	short rtc_p2
  1614                                  rtc_p4:	 
  1615 00000A7B C3                      	retn
  1616                                  
  1617                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  1618                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  1619                                  default_irq7:
  1620 00000A7C 6650                    	push	ax
  1621 00000A7E B00B                    	mov	al, 0Bh  ; In-Service register
  1622 00000A80 E620                    	out	20h, al
  1623 00000A82 EB00                            jmp short $+2
  1624 00000A84 EB00                    	jmp short $+2
  1625 00000A86 E420                    	in	al, 20h
  1626 00000A88 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  1627 00000A8A 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  1628 00000A8C B020                            mov     al, 20h ; EOI
  1629 00000A8E E620                    	out	20h, al 
  1630                                  irq7_iret:
  1631 00000A90 6658                    	pop	ax
  1632 00000A92 CF                      	iretd
  1633                                  	
  1634                                  bcd_to_ascii:
  1635                                  	; 25/08/2014
  1636                                  	; INPUT ->
  1637                                  	;	al = Packed BCD number
  1638                                  	; OUTPUT ->
  1639                                  	;	ax  = ASCII word/number
  1640                                  	;
  1641                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  1642                                  	;
  1643 00000A93 D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  1644                                  					; AH = AL / 10h
  1645                                  					; AL = AL MOD 10h
  1646 00000A95 660D3030                	or ax,'00'                      ; Make it ASCII based
  1647                                  
  1648 00000A99 86E0                            xchg ah, al 
  1649                                  	
  1650 00000A9B C3                      	retn	
  1651                                  	
  1652                                  
  1653                                  %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/05/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 00000A9C 9C                  <1> 	pushfd	; 28/08/2014
    40 00000A9D 0E                  <1> 	push 	cs
    41 00000A9E E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
    42 00000AA3 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/05/2016
   136                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   137                              <1> int32h:  ; Keyboard BIOS
   138                              <1> 
   139                              <1> KEYBOARD_IO_1:	
   140 00000AA4 FB                  <1> 	sti				; INTERRUPTS BACK ON
   141                              <1> 	; 29/05/2016
   142 00000AA5 80642408BE          <1>         and     byte [esp+8], 10111110b ; clear zero flag and cary flag
   143                              <1> 	;
   144 00000AAA 1E                  <1> 	push	ds			; SAVE CURRENT DS
   145 00000AAB 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
   146                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
   147 00000AAC 66BB1000            <1>         mov     bx, KDATA 
   148 00000AB0 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
   149 00000AB2 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
   150 00000AB4 7439                <1> 	jz	short _K1		; ASCII_READ
   151 00000AB6 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
   152 00000AB8 7452                <1>         jz      short _K2               ; ASCII_STATUS
   153 00000ABA FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
   154 00000ABC 0F8492000000        <1>         jz      _K3                     ; SHIFT STATUS
   155 00000AC2 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
   156 00000AC4 0F8491000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
   157 00000ACA 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
   158 00000ACD 0F84B6000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
   159                              <1> _KIO1:	
   160 00000AD3 80EC0B              <1> 	sub	ah, 11			; AH =  10H
   161 00000AD6 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
   162 00000AD8 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
   163 00000ADA 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
   164 00000ADC FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
   165 00000ADE 7456                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
   166                              <1> _KIO_EXIT:
   167                              <1> 	;pop	ecx			; RECOVER REGISTER
   168 00000AE0 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   169 00000AE1 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   170 00000AE2 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
   171                              <1> 
   172                              <1> 	;-----	ASCII CHARACTER
   173                              <1> _K1E:	
   174 00000AE3 E8CE000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
   175 00000AE8 E843010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   176 00000AED EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
   177                              <1> _K1:	
   178 00000AEF E8C2000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
   179 00000AF4 E842010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   180 00000AF9 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
   181                              <1> _K1A:
   182 00000AFB EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
   183                              <1> 
   184                              <1> 	;-----	ASCII STATUS
   185                              <1> _K2E:	
   186 00000AFD E8FF000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
   187 00000B02 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   188 00000B04 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   189 00000B05 E826010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   190 00000B0A EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
   191                              <1> _K2:	
   192 00000B0C E8F0000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
   193 00000B11 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   194 00000B13 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   195 00000B14 E822010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   196 00000B19 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
   197 00000B1B 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
   198 00000B1C E895000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
   199 00000B21 EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
   200                              <1> _K2A:
   201 00000B23 9D                  <1> 	popf				; RESTORE ZF FROM TEST
   202                              <1> _K2B:
   203                              <1> 	;pop	ecx			; RECOVER REGISTER
   204 00000B24 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   205 00000B25 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   206                              <1> 	; (*) 29/05/2016
   207                              <1> 	; (*) retf 4			; THROW AWAY (e)FLAGS
   208 00000B26 7208                <1> 	jc	short _k2d
   209 00000B28 7505                <1> 	jnz	short _k2c
   210 00000B2A 804C240840          <1> 	or	byte [esp+8], 01000000b	; set zero flag bit of eflags register
   211                              <1> _k2c:
   212 00000B2F CF                  <1> 	iretd
   213                              <1> _k2d:
   214                              <1> 	; 29/05/2016 -set carry flag on stack-
   215                              <1> 	; [esp] = EIP
   216                              <1> 	; [esp+4] = CS
   217                              <1> 	; [esp+8] = E-FLAGS
   218 00000B30 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
   219                              <1> 	; [esp+12] = ESP (user)
   220                              <1> 	; [esp+16] = SS (User)
   221 00000B35 CF                  <1> 	iretd
   222                              <1> 
   223                              <1> 	
   224                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
   225                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
   226                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
   227                              <1> 	; // RETF instruction:
   228                              <1> 	;
   229                              <1> 	; IF OperandMode=32 THEN
   230                              <1>  	;    Load CS:EIP from stack;
   231                              <1>  	;    Set CS RPL to CPL;
   232                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
   233                              <1>  	;    Load SS:eSP from stack;
   234                              <1>  	; ELSE (* OperandMode=16 *)
   235                              <1>  	;    Load CS:IP from stack;
   236                              <1>  	;    Set CS RPL to CPL;
   237                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
   238                              <1> 	;    Load SS:eSP from stack;
   239                              <1>  	; FI;
   240                              <1> 	;
   241                              <1> 	; //
   242                              <1> 
   243                              <1> 	;-----	SHIFT STATUS
   244                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
   245 00000B36 8A25[B2CC0000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
   246 00000B3C 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
   247                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
   248                              <1> 	;shl	ah, cl			; BIT 7 POSITION
   249 00000B3F C0E405              <1>         shl	ah, 5
   250 00000B42 A0[B2CC0000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
   251 00000B47 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
   252 00000B49 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
   253 00000B4B A0[B4CC0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
   254 00000B50 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
   255 00000B52 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
   256                              <1> _K3:
   257 00000B54 A0[B1CC0000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
   258 00000B59 EB85                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
   259                              <1> 
   260                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
   261                              <1> _K300:
   262 00000B5B 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
   263 00000B5D 7581                <1> 	jne	short _KIO_EXIT		; NO, RETURN
   264 00000B5F F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
   265 00000B62 0F8578FFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   266 00000B68 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
   267 00000B6B 0F856FFFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   268 00000B71 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
   269 00000B73 E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   270                              <1> 	;mov	cx, 5			; SHIFT COUNT
   271                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
   272 00000B78 C0E705              <1> 	shl	bh, 5
   273 00000B7B 88D8                <1> 	mov	al, bl			; PUT IN RATE
   274 00000B7D 08F8                <1> 	or	al, bh			; AND DELAY
   275 00000B7F E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   276 00000B84 E957FFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
   277                              <1> 
   278                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
   279                              <1> _K500:
   280 00000B89 56                  <1> 	push	esi			; SAVE SI (esi)
   281 00000B8A FA                  <1> 	cli				; 
   282 00000B8B 8B1D[C2CC0000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
   283 00000B91 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
   284 00000B93 E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
   285 00000B98 3B1D[BECC0000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
   286 00000B9E 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
   287 00000BA0 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
   288 00000BA3 891D[C2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
   289 00000BA9 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
   290 00000BAB EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
   291                              <1> _K502:
   292 00000BAD B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
   293                              <1> _K504:
   294 00000BAF FB                  <1> 	sti				
   295 00000BB0 5E                  <1> 	pop	esi			; RECOVER SI (esi)
   296 00000BB1 E92AFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
   297                              <1> 
   298                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
   299                              <1> _K1S:
   300 00000BB6 FA                  <1> 	cli	; 03/12/2014
   301 00000BB7 8B1D[BECC0000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   302 00000BBD 3B1D[C2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   303                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
   304 00000BC3 750F                <1> 	jne	short _k1x ; 03/12/2014
   305                              <1> 	;
   306                              <1> 	; 03/12/2014
   307                              <1> 	; 28/08/2014
   308                              <1> 	; PERFORM OTHER FUNCTION ?? here !
   309                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
   310                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
   311                              <1> _K1T:                                   ; ASCII READ
   312 00000BC5 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
   313 00000BC6 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
   314                              <1> _K1U:	
   315 00000BC7 FA                  <1> 	cli				; INTERRUPTS BACK OFF
   316 00000BC8 8B1D[BECC0000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   317 00000BCE 3B1D[C2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   318                              <1> _k1x:
   319 00000BD4 53                  <1> 	push	ebx			; SAVE ADDRESS		
   320 00000BD5 9C                  <1> 	pushf				; SAVE FLAGS
   321 00000BD6 E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   322 00000BDB 8A1D[B3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   323 00000BE1 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   324 00000BE3 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
   325 00000BE6 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
   326 00000BE8 E8C9060000          <1> 	call	SND_LED1
   327 00000BED FA                  <1> 	cli				; DISABLE INTERRUPTS
   328                              <1> _K1V:
   329 00000BEE 9D                  <1> 	popf				; RESTORE FLAGS
   330 00000BEF 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
   331 00000BF0 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
   332                              <1> 	;
   333 00000BF2 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
   334 00000BF5 E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
   335 00000BFA 891D[BECC0000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
   336 00000C00 C3                  <1> 	retn				; RETURN
   337                              <1> 
   338                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
   339                              <1> _K2S:
   340 00000C01 FA                  <1> 	cli				; INTERRUPTS OFF
   341 00000C02 8B1D[BECC0000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   342 00000C08 3B1D[C2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
   343 00000C0E 668B03              <1> 	mov	ax, [ebx]
   344 00000C11 9C                  <1> 	pushf				; SAVE FLAGS
   345 00000C12 6650                <1> 	push	ax			; SAVE CODE
   346 00000C14 E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   347 00000C19 8A1D[B3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   348 00000C1F 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   349 00000C21 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
   350 00000C24 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
   351 00000C26 E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   352                              <1> _K2T:
   353 00000C2B 6658                <1> 	pop	ax			; RESTORE CODE
   354 00000C2D 9D                  <1> 	popf				; RESTORE FLAGS
   355 00000C2E FB                  <1> 	sti				; INTERRUPTS BACK ON
   356 00000C2F C3                  <1> 	retn				; RETURN
   357                              <1> 
   358                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
   359                              <1> _KIO_E_XLAT:
   360 00000C30 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   361 00000C32 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
   362 00000C34 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
   363 00000C36 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
   364 00000C38 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
   365                              <1> _KIO_E_RET:				
   366 00000C3A C3                  <1> 	retn				; GO BACK
   367                              <1> 
   368                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
   369                              <1> _KIO_S_XLAT:
   370 00000C3B 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
   371 00000C3E 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
   372 00000C40 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
   373 00000C42 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
   374 00000C44 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
   375 00000C46 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
   376 00000C48 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
   377                              <1> _kio_ret: ; 03/12/2014
   378 00000C4A F8                  <1> 	clc
   379 00000C4B C3                  <1> 	retn
   380                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   381                              <1> _KIO_S1:				
   382 00000C4C B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
   383                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   384 00000C4E C3                  <1> 	retn
   385                              <1> _KIO_S2:		
   386 00000C4F 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
   387 00000C52 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
   388 00000C54 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   389 00000C56 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
   390 00000C58 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   391 00000C5A 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
   392 00000C5C EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
   393                              <1> _KIO_S3:
   394 00000C5E 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
   395                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
   396 00000C60 75E8                <1> 	jne	short _kio_ret
   397 00000C62 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   398 00000C64 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
   399 00000C66 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
   400                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
   401                              <1> _KIO_USE:
   402                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
   403 00000C68 C3                  <1> 	retn				; RETURN	
   404                              <1> _KIO_DIS:
   405 00000C69 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
   406 00000C6A C3                  <1> 	retn				; RETURN
   407                              <1> 
   408                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
   409                              <1> _K4:    
   410 00000C6B 43                  <1> 	inc     ebx
   411 00000C6C 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
   412 00000C6D 3B1D[BACC0000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
   413                              <1>         ;jne    short _K5               ; NO, CONTINUE
   414 00000C73 7206                <1> 	jb	short _K5
   415 00000C75 8B1D[B6CC0000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
   416                              <1> _K5:
   417 00000C7B C3                  <1> 	retn
   418                              <1> 
   419                              <1> ; 20/02/2015
   420                              <1> ; 05/12/2014
   421                              <1> ; 26/08/2014
   422                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
   423                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
   424                              <1> ;
   425                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
   426                              <1> ; rombios source code (06/10/1985)
   427                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
   428                              <1> 
   429                              <1> ; EQUATES (IBM PC-XT-286 BIOS, 1986, 'POSQEQU.INC')
   430                              <1> 
   431                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
   432                              <1> ENA_KBD		equ	0AEh		; ENABLE KEYBOARD COMMAND
   433                              <1> DIS_KBD		equ	0ADh		; DISABLE KEYBOARD COMMAND
   434                              <1> SHUT_CMD	equ	0FEh		; CAUSE A SHUTDOWN COMMAND
   435                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   436                              <1> STATUS_PORT	equ	064h		; 8042 STATUS PORT
   437                              <1> INPT_BUF_FULL	equ	00000010b 	; 1 = +INPUT BUFFER FULL
   438                              <1> PORT_A		equ	060h		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   439                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
   440                              <1> KB_ACK		equ	0FAh		; ACKNOWLEDGE PROM TRANSMISSION
   441                              <1> KB_RESEND	equ	0FEh		; RESEND REQUEST
   442                              <1> KB_OVER_RUN	equ	0FFh		; OVER RUN SCAN CODE
   443                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
   444                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
   445                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
   446                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
   447                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
   448                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
   449                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
   450                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
   451                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
   452                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
   453                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
   454                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
   455                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
   456                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
   457                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
   458                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
   459                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
   460                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
   461                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
   462                              <1> F11_M		equ	87		; F11 KEY MAKE
   463                              <1> F12_M		equ	88		; F12 KEY MAKE
   464                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
   465                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
   466                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
   467                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
   468                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
   469                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
   470                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
   471                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
   472                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
   473                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
   474                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
   475                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
   476                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
   477                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
   478                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
   479                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
   480                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
   481                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
   482                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
   483                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
   484                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
   485                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
   486                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
   487                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
   488                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
   489                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
   490                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
   491                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
   492                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
   493                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
   494                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
   495                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
   496                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
   497                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
   498                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
   499                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
   500                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
   501                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
   502                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
   503                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
   504                              <1> ;
   505                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
   506                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
   507                              <1> INTA00		equ	020h		; 8259 PORT
   508                              <1> 
   509                              <1> 
   510                              <1> kb_int:
   511                              <1> 
   512                              <1> ; 17/10/2015 ('ctrlbrk') 
   513                              <1> ; 05/12/2014
   514                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-)
   515                              <1> ; 26/08/2014
   516                              <1> ;
   517                              <1> ; 03/06/86  KEYBOARD BIOS
   518                              <1> ;
   519                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
   520                              <1> ;										;
   521                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
   522                              <1> ;										;
   523                              <1> ;--------------------------------------------------------------------------------
   524                              <1> 
   525                              <1> KB_INT_1:
   526 00000C7C FB                  <1> 	sti				; ENABLE INTERRUPTS
   527                              <1> 	;push	ebp
   528 00000C7D 50                  <1> 	push	eax
   529 00000C7E 53                  <1> 	push	ebx
   530 00000C7F 51                  <1> 	push	ecx
   531 00000C80 52                  <1> 	push	edx
   532 00000C81 56                  <1> 	push	esi
   533 00000C82 57                  <1> 	push	edi
   534 00000C83 1E                  <1> 	push	ds
   535 00000C84 06                  <1> 	push	es
   536 00000C85 FC                  <1> 	cld				; FORWARD DIRECTION
   537 00000C86 66B81000            <1> 	mov	ax, KDATA
   538 00000C8A 8ED8                <1> 	mov	ds, ax
   539 00000C8C 8EC0                <1> 	mov	es, ax
   540                              <1> 	;
   541                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
   542 00000C8E B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
   543 00000C90 E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
   544 00000C95 FA                  <1> 	cli				; DISABLE INTERRUPTS
   545 00000C96 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
   546                              <1> KB_INT_01:
   547 00000C9B E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
   548 00000C9D A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
   549 00000C9F E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
   550                              <1> 	;
   551                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
   552 00000CA1 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
   553                              <1> 	;
   554                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
   555                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
   556                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
   557                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
   558                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
   559                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
   560                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
   561                              <1> 	;				; EXÝT HANDLES HARDWARE EOI AND ENABLE		
   562                              <1> 	;
   563                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
   564                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
   565 00000CA3 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
   566 00000CA4 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
   567 00000CA6 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
   568                              <1> 	;
   569                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
   570 00000CA8 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
   571 00000CAA 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
   572                              <1> 	;
   573                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
   574 00000CAC FA                  <1> 	cli				; DISABLE INTERRUPTS
   575 00000CAD 800D[B3CC0000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
   576 00000CB4 E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
   577                              <1> 	;
   578                              <1> 	;-----	RESEND THE LAST BYTE
   579                              <1> KB_INT_4:
   580 00000CB9 FA                  <1> 	cli				; DISABLE INTERRUPTS
   581 00000CBA 800D[B3CC0000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
   582 00000CC1 E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
   583                              <1> 	;
   584                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
   585                              <1> KB_INT_2:
   586 00000CC6 6650                <1> 	push 	ax			; SAVE DATA IN
   587 00000CC8 E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   588 00000CCD 8A1D[B3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   589 00000CD3 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   590 00000CD5 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
   591 00000CD8 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
   592 00000CDA E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   593                              <1> UP0:
   594 00000CDF 6658                <1> 	pop	ax			; RESTORE DATA IN
   595                              <1> ;------------------------------------------------------------------------
   596                              <1> ;	START OF KEY PROCESSING						;
   597                              <1> ;------------------------------------------------------------------------
   598 00000CE1 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
   599                              <1> 	;
   600                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
   601 00000CE3 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
   602 00000CE5 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
   603                              <1> 	;
   604                              <1> K16:	
   605 00000CEB 8A3D[B4CC0000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
   606                              <1> 	;
   607                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
   608 00000CF1 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
   609 00000CF4 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
   610 00000CF6 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
   611 00000CF8 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
   612 00000CFA 7507                <1> 	jne	short RST_RD_ID
   613 00000CFC 800D[B4CC0000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   614                              <1> RST_RD_ID:
   615 00000D03 8025[B4CC0000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
   616                              <1>         ;jmp    short ID_EX		; AND EXIT
   617 00000D0A E924020000          <1> 	jmp	K26
   618                              <1> 	;
   619                              <1> TST_ID_2:
   620 00000D0F 8025[B4CC0000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
   621 00000D16 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
   622 00000D18 7419                <1>         je	short KX_BIT		; JUMP IF SO
   623 00000D1A 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
   624                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
   625 00000D1C 0F8511020000        <1> 	jne	K26
   626                              <1> 	;
   627                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
   628 00000D22 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
   629 00000D25 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
   630 00000D27 800D[B1CC0000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
   631 00000D2E E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
   632                              <1> KX_BIT:
   633 00000D33 800D[B4CC0000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
   634 00000D3A E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
   635                              <1> 	;
   636                              <1> NOT_ID:
   637 00000D3F 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
   638 00000D41 750C                <1> 	jne	short TEST_E1
   639 00000D43 800D[B4CC0000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
   640                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
   641 00000D4A E9EB010000          <1> 	jmp	K26A	
   642                              <1> TEST_E1:	
   643 00000D4F 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
   644 00000D51 750C                <1> 	jne	short NOT_HC
   645 00000D53 800D[B4CC0000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
   646 00000D5A E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
   647                              <1> 	;
   648                              <1> NOT_HC:
   649 00000D5F 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
   650 00000D61 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
   651 00000D64 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
   652                              <1> 	;
   653 00000D66 BF[9ECB0000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
   654 00000D6B AE                  <1> 	scasb
   655 00000D6C 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
   656 00000D72 AE                  <1> 	scasb
   657 00000D73 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
   658                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
   659 00000D75 E9B9010000          <1> 	jmp	K26
   660                              <1> 	;
   661                              <1> NOT_LC_E0:
   662 00000D7A F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
   663 00000D7D 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
   664 00000D7F B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
   665 00000D84 BF[9CCB0000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
   666 00000D89 F2AE                <1> 	repne	scasb			; CHECK IT
   667                              <1> 	;je	short EXIT		; THROW AWAY IF SO
   668 00000D8B 0F84A9010000        <1> 	je	K26A			
   669                              <1> 	;
   670 00000D91 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
   671                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
   672 00000D93 0F859A010000        <1> 	jne	K26
   673 00000D99 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
   674                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
   675 00000D9C 0F8591010000        <1> 	jnz	K26
   676                              <1>         ; 20/02/2015 
   677 00000DA2 F605[B2CC0000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
   678                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
   679 00000DA9 0F8584010000        <1> 	jnz	K26
   680 00000DAF E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
   681                              <1> 	;
   682                              <1> 	;-----	TEST FOR SYSTEM KEY
   683                              <1> T_SYS_KEY:
   684 00000DB4 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
   685 00000DB6 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
   686                              <1> 	;
   687 00000DB8 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
   688 00000DBB 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
   689                              <1> 	;
   690 00000DBD F605[B2CC0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
   691                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
   692 00000DC4 0F8569010000        <1> 	jnz     K26			
   693                              <1> 	;
   694 00000DCA 800D[B2CC0000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
   695 00000DD1 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   696 00000DD3 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   697                              <1> 					; INTERRUPT-RETURN-NO-EOI
   698 00000DD5 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   699 00000DD7 E862040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   700                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
   701                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
   702                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   703                              <1> 	;INT	15H			; USER INTERRUPT	
   704 00000DDC E965010000          <1>         jmp     K27A                    ; END PROCESSING
   705                              <1> 	;
   706                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
   707                              <1> 	;
   708                              <1> K16C:
   709 00000DE1 8025[B2CC0000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
   710 00000DE8 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   711 00000DEA E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
   712                              <1> 					; INTERRUPT-RETURN-NO-EOI
   713                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   714                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
   715                              <1> 	;
   716                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
   717                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   718                              <1> 	;INT	15H			; USER INTERRUPT
   719                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
   720                              <1> 	;
   721 00000DEC E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
   722                              <1> 	;
   723                              <1> 	;-----	TEST FOR SHIFT KEYS
   724                              <1> K16A:
   725 00000DF1 8A1D[B1CC0000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   726 00000DF7 BF[98CB0000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
   727 00000DFC B908000000          <1> 	mov	ecx, _K6L		; LENGTH
   728 00000E01 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
   729 00000E03 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
   730 00000E05 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
   731                              <1> 	;
   732                              <1> 	;------	SHIFT KEY FOUND
   733                              <1> K17:
   734 00000E0B 81EF[99CB0000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   735 00000E11 8AA7[A0CB0000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
   736 00000E17 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
   737 00000E19 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
   738 00000E1B 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
   739                              <1> 	;
   740                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
   741                              <1> K17C:
   742 00000E21 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
   743 00000E24 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
   744                              <1> 	;
   745                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
   746 00000E26 0825[B1CC0000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
   747 00000E2C A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
   748                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
   749 00000E2E 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
   750                              <1> K17D:
   751 00000E34 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
   752 00000E37 740B                <1> 	jz 	short K17E		; NO, JUMP
   753 00000E39 0825[B4CC0000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
   754 00000E3F E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
   755                              <1> K17E:
   756 00000E44 D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
   757 00000E46 0825[B2CC0000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
   758 00000E4C E9E2000000          <1> 	jmp	K26
   759                              <1> 	;
   760                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
   761                              <1> K18:					; SHIFT-TOGGLE
   762 00000E51 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
   763                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
   764 00000E54 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
   765                              <1> K18A:
   766 00000E5A 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
   767 00000E5C 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
   768 00000E5E F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
   769                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
   770 00000E61 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
   771                              <1> K18B:
   772 00000E67 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
   773 00000E6A 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
   774                              <1> K19:	
   775 00000E6C F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
   776 00000E6F 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
   777 00000E71 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
   778 00000E74 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
   779                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
   780 00000E76 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
   781 00000E78 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
   782                              <1> K21:					; MIGHT BE NUMERIC
   783 00000E7D F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
   784 00000E80 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
   785                              <1> 	;
   786                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
   787 00000E82 8425[B2CC0000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
   788 00000E88 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
   789                              <1> K22A:
   790 00000E8E 0825[B2CC0000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   791 00000E94 3025[B1CC0000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
   792                              <1> 	;
   793                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
   794 00000E9A F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
   795 00000E9D 7409                <1> 	jz	short K22B		; GO IF NOT
   796                              <1> 	;
   797 00000E9F 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
   798 00000EA1 E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
   799 00000EA6 6658                <1> 	pop	ax			; RESTORE SCAN CODE
   800                              <1> K22B:
   801 00000EA8 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
   802 00000EAA 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
   803 00000EB0 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
   804 00000EB2 E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
   805                              <1> 	;
   806                              <1> 	;-----	BREAK SHIFT FOUND
   807                              <1> K23:					; BREAK-SHIFT-FOUND
   808 00000EB7 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
   809 00000EBA F6D4                <1> 	not	ah			; INVERT MASK
   810 00000EBC 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
   811 00000EBE 2025[B1CC0000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
   812 00000EC4 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
   813 00000EC7 7730                <1> 	ja	short K23D		; NO, ALL DONE
   814                              <1> 	;
   815 00000EC9 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
   816 00000ECC 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
   817 00000ECE 2025[B4CC0000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
   818 00000ED4 EB08                <1> 	jmp	short K23B		; CONTINUE
   819                              <1> K23A:
   820 00000ED6 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
   821 00000ED8 2025[B2CC0000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
   822                              <1> K23B:
   823 00000EDE 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
   824 00000EE0 A0[B4CC0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
   825 00000EE5 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
   826 00000EE7 0A05[B2CC0000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALÞT & CTL FLAGS
   827 00000EED D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
   828 00000EEF 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
   829 00000EF1 0805[B1CC0000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
   830 00000EF7 88E0                <1> 	mov	al, ah
   831                              <1> K23D:
   832 00000EF9 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
   833 00000EFB 7536                <1> 	jne	short K26		; INTERRUPT RETURN
   834                              <1> 	;	
   835                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
   836 00000EFD A0[B5CC0000]        <1> 	mov	al, [ALT_INPUT]
   837 00000F02 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   838 00000F04 8825[B5CC0000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
   839 00000F0A 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
   840 00000F0C 7425                <1> 	je	short K26		; INTERRUPT_RETURN
   841                              <1>         ; 29/01/2016
   842                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
   843 00000F0E E9D0020000          <1> 	jmp	_K60
   844                              <1> 	;
   845                              <1> K24:					; BREAK-TOGGLE
   846 00000F13 2025[B2CC0000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
   847 00000F19 EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
   848                              <1> 	;
   849                              <1> 	;-----	TEST FOR HOLD STATE
   850                              <1> 					; AL, AH = SCAN CODE
   851                              <1> K25:					; NO-SHIFT-FOUND
   852 00000F1B 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
   853 00000F1D 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
   854 00000F1F F605[B2CC0000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
   855 00000F26 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
   856 00000F28 3C45                <1> 	cmp	al, NUM_KEY
   857 00000F2A 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
   858 00000F2C 8025[B2CC0000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   859                              <1> 	;
   860                              <1> K26:
   861 00000F33 8025[B4CC0000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
   862                              <1> K26A:					; INTERRUPT-RETURN
   863 00000F3A FA                  <1> 	cli				; TURN OFF INTERRUPTS
   864 00000F3B B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   865 00000F3D E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   866                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
   867 00000F3F B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   868 00000F41 E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   869                              <1> K27A:
   870 00000F46 FA                  <1> 	cli				; DISABLE INTERRUPTS
   871 00000F47 07                  <1> 	pop	es			; RESTORE REGISTERS
   872 00000F48 1F                  <1> 	pop	ds
   873 00000F49 5F                  <1> 	pop	edi
   874 00000F4A 5E                  <1> 	pop	esi
   875 00000F4B 5A                  <1> 	pop	edx
   876 00000F4C 59                  <1> 	pop	ecx
   877 00000F4D 5B                  <1> 	pop	ebx
   878 00000F4E 58                  <1> 	pop	eax
   879                              <1> 	;pop	ebp
   880 00000F4F CF                  <1> 	iret				; RETURN
   881                              <1> 
   882                              <1> 	;-----	NOT IN	HOLD STATE
   883                              <1> K28:					; NO-HOLD-STATE
   884 00000F50 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
   885 00000F52 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
   886                              <1> 	;
   887 00000F54 F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
   888                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
   889 00000F57 0F84F1000000        <1>         jz      K38
   890                              <1> 	;
   891 00000F5D F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
   892 00000F60 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
   893                              <1> 	 ;28/02/2015
   894 00000F62 F605[B2CC0000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
   895                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
   896 00000F69 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
   897                              <1>         ;				; DUE TO PRESSING SYSREQ	
   898                              <1> ;K28A:	jmp	short K38
   899                              <1> 	;
   900                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
   901                              <1> K29:					; TEST-RESET
   902 00000F6F F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
   903 00000F72 740B                <1> 	jz	short K31		; NO_RESET
   904 00000F74 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
   905 00000F76 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
   906                              <1> 	;
   907                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
   908                              <1>  	; 26/08/2014
   909                              <1> cpu_reset:
   910                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
   911                              <1> 	; Send FEh (system reset command) to the keyboard controller.
   912 00000F78 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
   913 00000F7A E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
   914                              <1> khere:
   915 00000F7C F4                  <1> 	hlt				; WAIT FOR 80286 RESET
   916 00000F7D EBFD                <1> 	jmp 	short khere		; INSURE HALT
   917                              <1> 
   918                              <1> 	;
   919                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
   920                              <1> K31:					; NO-RESET
   921 00000F7F 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
   922 00000F81 7507                <1> 	jne	short K311		; NOT THERE
   923 00000F83 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
   924 00000F85 E948020000          <1>         jmp     K57                     ; BUFFER_FILL
   925                              <1> K311:
   926 00000F8A 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
   927 00000F8C 7509                <1> 	jne	short K312		; NOT THERE
   928 00000F8E 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
   929 00000F92 E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
   930                              <1> K312:
   931 00000F97 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
   932 00000F99 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
   933 00000F9F 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
   934 00000FA1 0F849A000000        <1>         je      K37B                    ; GO PROCESS
   935                              <1> 	;
   936                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
   937                              <1> K32:					; ALT-KEY-PAD
   938 00000FA7 BF[74CB0000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
   939 00000FAC B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
   940 00000FB1 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
   941 00000FB3 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
   942 00000FB5 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
   943 00000FB8 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
   944 00000FBE 81EF[75CB0000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   945 00000FC4 A0[B5CC0000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
   946 00000FC9 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
   947 00000FCB F6E4                <1> 	mul	ah
   948 00000FCD 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
   949 00000FD0 A2[B5CC0000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
   950                              <1> ;K32A:
   951 00000FD5 E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
   952                              <1> 	;
   953                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
   954                              <1> K33:					; NO-ALT-KEYPAD
   955 00000FDA C605[B5CC0000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
   956 00000FE1 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
   957 00000FE6 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
   958 00000FE8 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
   959                              <1> 	;
   960                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
   961                              <1> K34:					; ALT-TOP-ROW
   962 00000FEA 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
   963 00000FEC 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
   964 00000FEE 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
   965 00000FF0 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
   966 00000FF2 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
   967 00000FF5 EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   968                              <1> 	;
   969                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
   970                              <1> K35:					; ALT-FUNCTION
   971 00000FF7 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
   972 00000FF9 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
   973 00000FFB 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
   974 00000FFD 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
   975 00000FFF 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
   976 00001002 EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   977                              <1> K35A:
   978 00001004 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
   979 00001007 7422                <1> 	jz	short K37		; NO, JUMP
   980 00001009 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
   981 0000100B 7509                <1>         jne     short K35B              ; NOT THERE
   982 0000100D 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
   983 00001011 E9BC010000          <1> 	jmp	K57			; BUFFER FILL
   984                              <1> K35B:
   985 00001016 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
   986 00001018 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
   987 0000101A 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
   988                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
   989 0000101C 0F8511FFFFFF        <1>         jne     K26
   990 00001022 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
   991 00001026 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
   992                              <1> K37:
   993 0000102B 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
   994 0000102D 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
   995 0000102F 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
   996                              <1>         ;ja	short K32A		; IF SO, IGNORE
   997 00001031 0F87FCFEFFFF        <1>         ja      K26
   998 00001037 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
   999                              <1> K37A:
  1000 0000103A B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  1001 0000103C E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  1002                              <1> K37B:
  1003 00001041 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  1004 00001043 E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  1005                              <1> K37C:
  1006 00001048 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  1007 0000104A 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  1008 0000104C EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  1009                              <1> 	;
  1010                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  1011                              <1> K38:					; NOT-ALT-SHIFT
  1012                              <1> 					; BL STILL HAS SHIFT FLAGS
  1013 0000104E F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  1014                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  1015 00001051 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  1016                              <1> 	;
  1017                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  1018                              <1> 	;-----	TEST FOR BREAK
  1019                              <1> K38A:
  1020 00001057 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  1021 00001059 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  1022 0000105B F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1023 0000105E 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  1024 00001060 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1025 00001063 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  1026                              <1> K38B:
  1027 00001065 8B1D[BECC0000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  1028 0000106B 891D[C2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx
  1029 00001071 C605[B0CC0000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  1030                              <1> 	;
  1031                              <1> 	;-----	ENABLE KEYBOARD
  1032 00001078 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1033 0000107A E8BF010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1034                              <1> 	;
  1035                              <1> 	; CTRL+BREAK code here !!!
  1036                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  1037                              <1> 	; 17/10/2015	
  1038 0000107F E8A92F0000          <1> 	call	ctrlbrk ; control+break subroutine
  1039                              <1> 	;
  1040 00001084 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  1041 00001087 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  1042                              <1> 	;
  1043                              <1> 	;-----	TEST FOR PAUSE
  1044                              <1> K39:					; NO_BREAK
  1045 0000108C F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1046 0000108F 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  1047 00001091 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  1048 00001093 7533                <1> 	jne	short K41		; NO-PAUSE
  1049                              <1> K39P:
  1050 00001095 800D[B2CC0000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  1051                              <1> 	;
  1052                              <1> 	;-----	ENABLE KEYBOARD
  1053 0000109C B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1054 0000109E E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1055                              <1> K39A:
  1056 000010A3 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  1057 000010A5 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  1058                              <1> 	;
  1059                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  1060 000010A7 803D[E6CC0000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  1061 000010AE 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  1062 000010B0 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  1063 000010B4 A0[E7CC0000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  1064 000010B9 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  1065                              <1> 	;
  1066                              <1> K40:					; PAUSE-LOOP
  1067 000010BA F605[B2CC0000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  1068 000010C1 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  1069                              <1> 	;
  1070 000010C3 E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  1071                              <1>         ;
  1072                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  1073                              <1> K41:					; NO-PAUSE
  1074 000010C8 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  1075 000010CA 7513                <1> 	jne	short K42		; NOT-KEY-55
  1076 000010CC F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1077 000010CF 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  1078 000010D1 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1079 000010D4 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  1080                              <1> K41A:	
  1081 000010D6 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  1082 000010DA E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  1083                              <1> 	;
  1084                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  1085                              <1> K42:					; NOT-KEY-55
  1086 000010DF 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  1087 000010E1 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  1088 000010E3 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  1089 000010E5 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  1090 000010E7 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  1091 000010EA 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  1092 000010EC 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  1093 000010F0 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  1094                              <1> K42A: 
  1095                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1096 000010F5 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  1097                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  1098                              <1> 	;;jb	K56 ; 20/02/2015
  1099                              <1> 	;;jmp	K64 ; 20/02/2015
  1100                              <1> K42B:
  1101 000010F7 BB[A8CB0000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1102 000010FC 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  1103 00001102 E9B9000000          <1> 	jmp	K64	
  1104                              <1>         ;
  1105                              <1> 	;-----	NOT IN CONTROL SHIFT
  1106                              <1> K44:					; NOT-CTL-SHIFT
  1107 00001107 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  1108 00001109 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  1109 0000110B F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  1110 0000110E 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  1111 00001110 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  1112 00001113 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  1113 00001115 EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1114                              <1> K44A:
  1115 00001117 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  1116 0000111A 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1117                              <1> 	;
  1118                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  1119                              <1> K44B:
  1120 0000111C B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1121 0000111E E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1122 00001123 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  1123 00001125 E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  1124                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  1125                              <1> 	;PUSH 	BP			; SAVE POINTER
  1126                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  1127                              <1> 	;POP	BP			; RESTORE POINTER
  1128 00001127 8025[B4CC0000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  1129 0000112E E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  1130                              <1> 	;
  1131                              <1> 	;-----	HANDLE IN-CORE KEYS
  1132                              <1> K45:					; NOT-PRINT-SCREEN
  1133 00001133 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  1134 00001135 7734                <1> 	ja	short K46		; JUMP IF NOT
  1135 00001137 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  1136 00001139 7505                <1> 	jne	short K45A		; NO, JUMP
  1137 0000113B F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  1138 0000113E 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  1139                              <1> K45A:
  1140 00001140 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  1141 00001145 BF[7ECB0000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  1142 0000114A F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  1143                              <1> 		; 20/02/2015
  1144 0000114C 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  1145                              <1> 	;
  1146 0000114E F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  1147 00001151 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  1148                              <1> K45B:
  1149 00001153 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1150 00001156 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  1151                              <1> 					; NO, LOWERCASE
  1152                              <1> K45C:
  1153 00001158 BB[00CC0000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  1154 0000115D EB51                <1> 	jmp	short K56	
  1155                              <1> K45D:					; ALMOST-CAPS-STATE
  1156 0000115F F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  1157 00001162 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  1158                              <1> K45E:
  1159 00001164 BB[58CC0000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  1160 00001169 EB45                <1> K45F:	jmp	short K56
  1161                              <1> 	;
  1162                              <1> 	;-----	TEST FOR KEYS F1 - F10
  1163                              <1> K46:					; NOT IN-CORE AREA
  1164 0000116B 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  1165                              <1> 	;ja	short K47		; JUMP IF NOT
  1166                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  1167 0000116D 7635                <1> 	jna	short K53		
  1168                              <1> 	;
  1169                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  1170                              <1> K47:					; NOT F1 - F10
  1171 0000116F 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  1172 00001171 772D                <1> 	ja	short K52		; JUMP IF NOT
  1173                              <1> 	;
  1174                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  1175                              <1> K48:
  1176 00001173 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  1177 00001175 74ED                <1> 	je	short K45E		; GO TRANSLATE
  1178 00001177 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  1179 00001179 74E9                <1> 	je	short K45E		; GO TRANSLATE
  1180 0000117B F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  1181 0000117E 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  1182                              <1> 	;		
  1183 00001180 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  1184 00001183 7514                <1> 	jnz	short K50		; TEST FOR SURE
  1185 00001185 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1186                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  1187 00001188 75DA                <1> 	jnz	short K45E
  1188                              <1> 	;
  1189                              <1> 	;-----	BASE CASE FOR KEYPAD
  1190                              <1> K49:					
  1191 0000118A 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  1192 0000118C 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  1193 0000118E B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  1194 00001190 EB40                <1> 	jmp	short K57		; BUFFER FILL
  1195                              <1> K49A:
  1196 00001192 BB[00CC0000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  1197 00001197 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  1198                              <1> 	;
  1199                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  1200                              <1> K50:					; ALMOST-NUM-STATE
  1201 00001199 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  1202 0000119C 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  1203 0000119E EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  1204                              <1> 	;
  1205                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  1206                              <1> K52:					; NOT A NUMPAD KEY
  1207 000011A0 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  1208                              <1> 	;jne	short K53		; JUMP IF NOT
  1209                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  1210 000011A2 74AF                <1> 	je	short K45B		
  1211                              <1> 	;
  1212                              <1> 	;-----	MUST BE F11 OR F12 
  1213                              <1> K53:					; F1 - F10 COME HERE, TOO
  1214 000011A4 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  1215 000011A7 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  1216                              <1> 		; 20/02/2015 
  1217 000011A9 BB[58CC0000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  1218 000011AE EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  1219                              <1> 	;
  1220                              <1> 	;-----	TRANSLATE THE CHARACTER
  1221                              <1> K56:					; TRANSLATE-CHAR
  1222 000011B0 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1223 000011B2 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  1224 000011B3 F605[B4CC0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1225 000011BA 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1226 000011BC B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  1227 000011BE EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  1228                              <1> 	;
  1229                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  1230                              <1> K64:					; TRANSLATE-SCAN-ORGD
  1231 000011C0 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1232 000011C2 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  1233 000011C3 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  1234 000011C5 B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  1235 000011C7 F605[B4CC0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1236 000011CE 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1237 000011D0 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  1238                              <1> 	;
  1239                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  1240                              <1> K57:					; BUFFER_FILL
  1241 000011D2 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  1242                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  1243 000011D4 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  1244 000011DA 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  1245                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  1246 000011DD 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  1247                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  1248                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  1249                              <1> 
  1250                              <1> _K60: ; 29/01/2016
  1251 000011E3 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  1252 000011E6 721F                <1> 	jb	short K61
  1253 000011E8 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  1254 000011EB 771A                <1> 	ja	short K61
  1255                              <1> 	;
  1256 000011ED 8A1D[B8D20000]      <1> 	mov	bl, [ACTIVE_PAGE]
  1257 000011F3 80C368              <1> 	add	bl, 68h
  1258 000011F6 38E3                <1> 	cmp	bl, ah
  1259 000011F8 740D                <1> 	je	short K61
  1260 000011FA 6650                <1> 	push	ax
  1261 000011FC 88E0                <1> 	mov	al, ah
  1262 000011FE 2C68                <1> 	sub	al, 68h
  1263 00001200 E8A6020000          <1> 	call	set_active_page
  1264 00001205 6658                <1> 	pop	ax
  1265                              <1> K61:					; NOT-CAPS-STATE
  1266 00001207 8B1D[C2CC0000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  1267 0000120D 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  1268 0000120F E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  1269 00001214 3B1D[BECC0000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  1270 0000121A 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  1271 0000121C 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  1272 0000121F 891D[C2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  1273 00001225 E909FDFFFF          <1> 	jmp	K26
  1274                              <1> 	;;cli				; TURN OFF INTERRUPTS
  1275                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  1276                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  1277                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1278                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  1279                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  1280                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  1281                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  1282                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  1283                              <1> 	;;jmp   K27                    
  1284                              <1> 	;
  1285                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  1286                              <1> K62:
  1287 0000122A B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  1288 0000122C E620                <1> 	out	INTA00, al
  1289 0000122E 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  1290 00001232 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  1291 00001234 E893050000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  1292 00001239 E901FDFFFF          <1> 	jmp     K27			; EXIT   
  1293                              <1> 
  1294                              <1> SHIP_IT:
  1295                              <1> 	;---------------------------------------------------------------------------------
  1296                              <1> 	; SHIP_IT
  1297                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1298                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  1299                              <1> 	;---------------------------------------------------------------------------------
  1300                              <1> 	;
  1301 0000123E 6650                <1> 	push	ax			; SAVE DATA TO SEND
  1302                              <1> 
  1303                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  1304 00001240 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  1305                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  1306 00001241 B900000100          <1> 	mov	ecx, 10000h			
  1307                              <1> S10:
  1308 00001246 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  1309 00001248 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  1310 0000124A E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  1311                              <1> 
  1312 0000124C 6658                <1> 	pop	ax			; GET DATA TO SEND
  1313 0000124E E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  1314 00001250 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  1315 00001251 C3                  <1> 	retn				; RETURN TO CALLER
  1316                              <1> 
  1317                              <1> SND_DATA:
  1318                              <1> 	; ---------------------------------------------------------------------------------
  1319                              <1> 	; SND_DATA
  1320                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1321                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  1322                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  1323                              <1> 	; ---------------------------------------------------------------------------------
  1324                              <1> 	;
  1325 00001252 6650                <1> 	push	ax			; SAVE REGISTERS
  1326 00001254 6653                <1> 	push	bx
  1327 00001256 51                  <1> 	push	ecx
  1328 00001257 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  1329 00001259 B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  1330                              <1> SD0:
  1331 0000125B FA                  <1> 	cli				; DISABLE INTERRUPTS
  1332 0000125C 8025[B3CC0000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  1333                              <1> 	;
  1334                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  1335 00001263 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  1336                              <1> SD5:
  1337 00001268 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  1338 0000126A A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  1339 0000126C E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  1340                              <1> 	;
  1341 0000126E 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  1342 00001270 E660                <1> 	out	PORT_A, al		; SEND BYTE
  1343 00001272 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1344                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  1345 00001273 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  1346                              <1> SD1:
  1347 00001278 F605[B3CC0000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  1348 0000127F 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  1349 00001281 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  1350                              <1> SD2:
  1351 00001283 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  1352 00001285 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  1353 00001287 800D[B3CC0000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  1354 0000128E EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  1355                              <1> SD3:
  1356 00001290 F605[B3CC0000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  1357 00001297 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  1358                              <1> SD4:	
  1359 00001299 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  1360 0000129A 665B                <1> 	pop	bx
  1361 0000129C 6658                <1> 	pop	ax
  1362 0000129E C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  1363                              <1> 
  1364                              <1> SND_LED:
  1365                              <1> 	; ---------------------------------------------------------------------------------
  1366                              <1> 	; SND_LED
  1367                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  1368                              <1> 	;
  1369                              <1> 	;----------------------------------------------------------------------------------
  1370                              <1> 	;
  1371 0000129F FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1372 000012A0 F605[B3CC0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1373 000012A7 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1374                              <1> 	;
  1375 000012A9 800D[B3CC0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1376 000012B0 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  1377 000012B2 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  1378 000012B4 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  1379                              <1> SND_LED1:
  1380 000012B6 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1381 000012B7 F605[B3CC0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1382 000012BE 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1383                              <1> 	;
  1384 000012C0 800D[B3CC0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1385                              <1> SL0:
  1386 000012C7 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  1387 000012C9 E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1388 000012CE FA                  <1> 	cli
  1389 000012CF E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  1390 000012D4 8025[B3CC0000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1391 000012DB 0805[B3CC0000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1392 000012E1 F605[B3CC0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1393 000012E8 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  1394                              <1> 	;
  1395 000012EA E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1396 000012EF FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1397 000012F0 F605[B3CC0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1398 000012F7 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  1399                              <1> SL2:
  1400 000012F9 B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  1401 000012FB E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1402 00001300 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1403                              <1> SL3:
  1404 00001301 8025[B3CC0000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  1405                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  1406 00001308 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1407 00001309 C3                  <1> 	retn				; RETURN TO CALLER
  1408                              <1> 
  1409                              <1> MAKE_LED:
  1410                              <1> 	;---------------------------------------------------------------------------------
  1411                              <1> 	; MAKE_LED
  1412                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  1413                              <1> 	;	THE MODE INDICATORS.
  1414                              <1> 	;---------------------------------------------------------------------------------
  1415                              <1> 	;
  1416                              <1> 	;push 	cx			; SAVE CX
  1417 0000130A A0[B1CC0000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  1418 0000130F 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  1419                              <1> 	;mov	cl, 4			; SHIFT COUNT
  1420                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  1421 00001311 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  1422 00001314 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  1423                              <1> 	;pop	cx
  1424 00001316 C3                  <1> 	retn				; RETURN TO CALLER
  1425                              <1> 
  1426                              <1> ; % include 'kybdata.s'   ; KEYBOARD DATA
  1427                              <1> 
  1428                              <1> 
  1429                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  1654                                  
  1655                                  %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/05/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 31H (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 00001317 9C                  <1> 	pushfd
    35 00001318 0E                  <1> 	push 	cs
    36 00001319 E851000000          <1> 	call 	VIDEO_IO_1
    37 0000131E 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 0000131F [C0130000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   191 00001323 [58140000]          <1> 	dd	SET_CTYPE
   192 00001327 [70140000]          <1> 	dd	SET_CPOS
   193 0000132B [7A140000]          <1> 	dd	READ_CURSOR
   194 0000132F [D1130000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
   195 00001333 [A1140000]          <1> 	dd	ACT_DISP_PAGE
   196 00001337 [1A150000]          <1> 	dd	SCROLL_UP
   197 0000133B [04160000]          <1> 	dd	SCROLL_DOWN
   198 0000133F [57160000]          <1> 	dd	READ_AC_CURRENT
   199 00001343 [85160000]          <1> 	dd	WRITE_AC_CURRENT
   200 00001347 [98160000]          <1> 	dd	WRITE_C_CURRENT
   201 0000134B [D1130000]          <1> 	dd	VIDEO_RETURN	; SET_COLOR
   202 0000134F [D1130000]          <1> 	dd	VIDEO_RETURN	; WRITE_DOT
   203 00001353 [D1130000]          <1> 	dd	VIDEO_RETURN	; READ_DOT
   204 00001357 [DE160000]          <1> 	dd	WRITE_TTY
   205 0000135B [AD130000]          <1> 	dd	VIDEO_STATE
   206 0000135F [D1130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   207 00001363 [D1130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   208 00001367 [D1130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   209 0000136B [D1130000]          <1> 	dd	VIDEO_RETURN	; WRITE_STRING
   210                              <1> M1L	EQU	$ - M1
   211                              <1> 
   212                              <1> ; 12/05/2016
   213                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   214                              <1> int31h:  ; Video BIOS
   215                              <1> 
   216                              <1> ; BH = Video page number
   217                              <1> ; BL = Color/Attribute
   218                              <1> ; AH = Function number
   219                              <1> ; AL = Character
   220                              <1> 
   221                              <1> VIDEO_IO_1:
   222 0000136F FB                  <1> 	sti				; INTERRUPTS BACK ON
   223 00001370 FC                  <1> 	cld				; SET DIRECTION FORWARD
   224 00001371 80FC14              <1> 	cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
   225 00001374 7326                <1> 	jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
   226                              <1> 
   227 00001376 06                  <1> 	push	es
   228 00001377 1E                  <1> 	push	ds			; SAVE WORK AND PARAMETER REGISTERS
   229 00001378 52                  <1> 	push	edx
   230 00001379 51                  <1> 	push	ecx
   231 0000137A 53                  <1> 	push	ebx
   232 0000137B 56                  <1> 	push	esi
   233 0000137C 57                  <1> 	push	edi
   234 0000137D 55                  <1> 	push	ebp
   235 0000137E 66BE1000            <1> 	mov	si, KDATA 		; POINT DS: TO DATA SEGMENT
   236 00001382 8EDE                <1> 	mov	ds, si
   237 00001384 8EC6                <1> 	mov	es, si
   238 00001386 BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
   239 0000138B A3[04E00000]        <1> 	mov	[video_eax], eax ; 12/05/2016 
   240                              <1> 	; 23/03/2016
   241 00001390 C0E402              <1> 	shl	ah, 2  ; dword		; TIMES 2 FOR WORD TABLE LOOKUP
   242 00001393 0FB6F4              <1> 	movzx	esi, ah			; MOVE OFFSET INTO LOOK UP REGISTER (SI)
   243                              <1> 	;mov	ah, [CRT_MODE]		; MOVE CURRENT MODE INTO (AH) REGISTER
   244                              <1> 
   245 00001396 FFA6[1F130000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
   246                              <1> 
   247                              <1> M4:					;	COMMAND NOT VALID
   248 0000139C CF                  <1> 	iret				; DO NOTHING IF NOT IN VALID RANGE
   249                              <1> 
   250                              <1> 
   251                              <1> ; 02/09/2014 (Retro UNIX 386 v1)
   252                              <1> ;
   253                              <1> ; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   254                              <1> 
   255                              <1> set_mode_3:  	; will be called from 'write_tty' 
   256 0000139D 53                  <1> 	push	ebx
   257 0000139E 52                  <1> 	push	edx
   258 0000139F 50                  <1> 	push	eax
   259 000013A0 57                  <1> 	push	edi
   260 000013A1 51                  <1> 	push	ecx
   261 000013A2 E838000000          <1> 	call	set_txt_mode
   262 000013A7 59                  <1> 	pop	ecx
   263 000013A8 5F                  <1> 	pop	edi
   264 000013A9 58                  <1> 	pop	eax
   265 000013AA 5A                  <1> 	pop	edx
   266 000013AB 5B                  <1> 	pop	ebx
   267 000013AC C3                  <1> 	retn
   268                              <1> 
   269                              <1> VIDEO_STATE:
   270                              <1> 	; 12/05/2016
   271                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   272                              <1> 
   273                              <1> ;---------------------------------------------------
   274                              <1> ; VIDEO STATE
   275                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
   276                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
   277                              <1> ;  AL = CURRENT VIDEO MODE
   278                              <1> ;  BH = CURRENT ACTIVE PAGE
   279                              <1> ;---------------------------------------------------
   280                              <1> 
   281                              <1> 	;mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
   282 000013AD B480                <1> 	mov	ah, 80h
   283 000013AF A0[E6CC0000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
   284                              <1> 	;movzx	esi, al
   285                              <1> 	;mov	ah, [esi+M6] 
   286                              <1> 	; BH = active page
   287 000013B4 8A3D[B8D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
   288 000013BA 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
   289 000013BB 5F                  <1> 	pop	edi
   290 000013BC 5E                  <1> 	pop	esi
   291 000013BD 59                  <1> 	pop	ecx		; DISCARD SAVED BX
   292 000013BE EB1A                <1> 	jmp	short M15	; RETURN TO CALLER
   293                              <1> 
   294                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
   295                              <1> SET_MODE:
   296                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
   297                              <1> 	;	valid video mode: 03h only!
   298                              <1> 	;	(VGA modes will be selected with another routine)
   299                              <1> 	;
   300                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
   301                              <1> 
   302                              <1> ;------------------------------------------------------
   303                              <1> ; SET MODE					      :
   304                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
   305                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
   306                              <1> ; INPUT						      :
   307                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
   308                              <1> ; OUTPUT					      :
   309                              <1> ;	NONE					      :
   310                              <1> ;------------------------------------------------------
   311                              <1> 
   312 000013C0 FE05[0BE00000]      <1> 	inc 	byte [set_mode_clear] ; 29/05/2016
   313                              <1> 
   314 000013C6 E814000000          <1> 	call	set_txt_mode
   315                              <1> 
   316 000013CB FE0D[0BE00000]      <1> 	dec	byte [set_mode_clear] ; 29/05/2016
   317                              <1> 
   318                              <1> ; 12/05/2016
   319                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   320                              <1> 
   321                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   322                              <1> 
   323                              <1> VIDEO_RETURN:
   324 000013D1 A1[04E00000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   325                              <1> _video_return:
   326 000013D6 5D                  <1> 	pop	ebp
   327 000013D7 5F                  <1> 	pop	edi
   328 000013D8 5E                  <1> 	pop	esi
   329 000013D9 5B                  <1> 	pop	ebx
   330                              <1> M15:	; VIDEO_RETURN_C
   331 000013DA 59                  <1> 	pop	ecx
   332 000013DB 5A                  <1> 	pop	edx
   333 000013DC 1F                  <1> 	pop	ds
   334 000013DD 07                  <1> 	pop	es	; RECOVER SEGMENTS
   335 000013DE CF                  <1> 	iret		; ALL DONE
   336                              <1> 
   337                              <1> ; 29/05/2016
   338                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   339                              <1> set_txt_mode:
   340                              <1> 	;mov	dx, 03D4h 	; address of color card
   341 000013DF B003                <1> 	mov	al, 3
   342                              <1> ;M8:
   343 000013E1 A2[E6CC0000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
   344 000013E6 B029                <1> 	mov	al, 29h
   345                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
   346 000013E8 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
   347                              <1> 	;push	dx  		; save port value
   348                              <1> 	;add	dx, 4		; point to control register
   349 000013EA 66BAD803            <1> 	mov	dx, 3D8h
   350 000013EE EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
   351                              <1> 	;pop	dx
   352                              <1> ;M9:
   353 000013EF BB[E8CC0000]        <1> 	mov	ebx, video_params ; initialization table
   354 000013F4 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
   355 000013F8 86E0                <1> 	xchg 	ah, al
   356 000013FA 66A3[A6D20000]      <1> 	mov	[CURSOR_MODE], ax ; save cursor mode
   357 00001400 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
   358                              <1> 	
   359                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
   360 00001402 B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
   361                              <1> M10:			;  initialization loop
   362 00001407 88E0                <1> 	mov	al, ah 	; get 6845 register number
   363 00001409 EE                  <1> 	out	dx, al
   364 0000140A 6642                <1> 	inc	dx      ; point to data port
   365 0000140C FEC4                <1> 	inc	ah	; next register value
   366 0000140E 8A03                <1> 	mov	al, [ebx] ; get table value
   367 00001410 EE                  <1> 	out	dx, al	; out to chip
   368 00001411 43                  <1> 	inc	ebx	; next in table
   369 00001412 664A                <1> 	dec	dx	; back to pointer register
   370 00001414 E2F1                <1> 	loop	M10	; do the whole table
   371                              <1> 
   372                              <1> 	; 29/05/2016
   373                              <1> 	; TRDOS 386 (INT 31h) VIDEO interrupt will reset
   374                              <1> 	; ACTIVE PAGE to 0 and then video page 0 will be cleared.
   375                              <1> 	; But, if 'set_txt_mode' will be called by 'write_tty'
   376                              <1> 	; ('set_mode_3'), active video page will not be reset and
   377                              <1> 	; also it will not be cleared.
   378                              <1> 	;  
   379 00001416 380D[0BE00000]      <1> 	cmp	byte [set_mode_clear], cl ; 0
   380 0000141C 761F                <1> 	jna	short _M11
   381                              <1> 	;
   382                              <1> ;-----	FILL REGEN AREA WITH BLANK
   383 0000141E 6631C0              <1> 	xor	ax, ax  
   384 00001421 66A3[A4D20000]      <1> 	mov	[CRT_START], ax  ; start address saved in global
   385 00001427 A2[B8D20000]        <1> 	mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
   386 0000142C B900200000          <1> 	mov	ecx, 8192 ; number of words in color card
   387                              <1> 	; black background, light gray characeter color, space character
   388 00001431 66B82007            <1> 	mov	ax, 0720h ; fill char for alpha - attribute
   389                              <1> ;M13:			  ; clear buffer
   390 00001435 BF00800B00          <1> 	mov	edi, 0B8000h ; [crt_base]
   391 0000143A F366AB              <1> 	rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   392                              <1> _M11:
   393                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
   394                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
   395                              <1> 			 ; prepare to output to video enable port
   396                              <1> 	;add	dx,4	 ; point to the mode control gerister
   397 0000143D 66BAD803            <1> 	mov	dx, 3D8h
   398                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
   399 00001441 B029                <1> 	mov	al, 29h
   400 00001443 EE                  <1> 	out	dx, al	 ; set video enable port
   401                              <1> 
   402                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
   403                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
   404                              <1> 	;
   405                              <1> 	;mov	byte [CRT_COLS], 80h ; initialize number of columns count
   406                              <1> 	;
   407                              <1> ;-----	SET CURSOR POSITIONS
   408                              <1> 	;mov	word [CRT_LEN], 80*25*2
   409 00001444 BF[A8D20000]        <1> 	mov	edi, CURSOR_POSN
   410 00001449 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
   411 0000144E 31C0                <1> 	xor	eax, eax
   412 00001450 F3AB                <1> 	rep 	stosd	; fill with zeroes
   413                              <1> 
   414                              <1> ;-----	SET UP OVERSCAN REGISTER
   415 00001452 6642                <1> 	inc	dx	; set overscan port to a default
   416 00001454 B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
   417                              <1> ;M14:
   418 00001456 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
   419                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
   420                              <1> 
   421                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   422 00001457 C3                  <1> 	retn
   423                              <1> 
   424                              <1> SET_CTYPE:
   425                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   426 00001458 E805000000          <1> 	call	_set_ctype
   427 0000145D E96FFFFFFF          <1>         jmp     VIDEO_RETURN
   428                              <1> 
   429                              <1> _set_ctype:
   430                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
   431                              <1> 	;
   432                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   433                              <1> 
   434                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
   435                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
   436                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
   437                              <1> 	;     OR NO CURSOR AT ALL
   438                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
   439                              <1> 
   440                              <1> ;------------------------------------------------
   441                              <1> ; SET_CTYPE
   442                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
   443                              <1> ; INPUT
   444                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
   445                              <1> ; OUTPUT	
   446                              <1> ;	NONE
   447                              <1> ;------------------------------------------------
   448                              <1> 
   449 00001462 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
   450 00001464 66890D[A6D20000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
   451                              <1> 	;call	m16	; output cx register
   452                              <1> 	;retn
   453 0000146B E92E030000          <1>         jmp     m16
   454                              <1> 
   455                              <1> SET_CPOS:
   456                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   457 00001470 E8FE020000          <1> 	call	_set_cpos
   458 00001475 E957FFFFFF          <1>         jmp     VIDEO_RETURN
   459                              <1> 
   460                              <1> READ_CURSOR:
   461                              <1> 	; 12/05/2016
   462                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   463                              <1> 	;
   464                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   465                              <1> 
   466                              <1> ;------------------------------------------------------
   467                              <1> ; READ_CURSOR
   468                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
   469                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
   470                              <1> ; INPUT
   471                              <1> ;	BH - PAGE OF CURSOR
   472                              <1> ; OUTPUT
   473                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
   474                              <1> ;	CX - CURRENT CURSOR MODE
   475                              <1> ;------------------------------------------------------
   476                              <1> 
   477                              <1> 	; BH = Video page number (0 to 7)
   478                              <1> 	
   479 0000147A E815000000          <1> 	call	get_cpos
   480 0000147F 0FB70D[A6D20000]    <1> 	movzx	ecx, word [CURSOR_MODE]
   481                              <1> 
   482 00001486 5D                  <1> 	pop	ebp
   483 00001487 5F                  <1> 	pop	edi
   484 00001488 5E                  <1> 	pop	esi
   485 00001489 5B                  <1> 	pop	ebx
   486 0000148A 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
   487 0000148B 58                  <1> 	pop	eax
   488 0000148C A1[04E00000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   489 00001491 1F                  <1> 	pop	ds
   490 00001492 07                  <1> 	pop	es
   491 00001493 CF                  <1> 	iret
   492                              <1> 
   493                              <1> get_cpos:
   494                              <1> 	; 12/05/2016
   495                              <1> 	; 16/01/2016
   496                              <1> 	; BH = Video page number (0 to 7)
   497                              <1> 	;
   498 00001494 D0E7                <1> 	shl	bh, 1 ; WORD OFFSET
   499 00001496 0FB6F7              <1> 	movzx	esi, bh 
   500 00001499 0FB796[A8D20000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
   501 000014A0 C3                  <1> 	retn
   502                              <1> 
   503                              <1> ACT_DISP_PAGE:
   504                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   505                              <1> 	;
   506                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   507                              <1> 	;
   508                              <1> ;-----------------------------------------------------
   509                              <1> ; ACT_DISP_PAGE
   510                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
   511                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
   512                              <1> ; INPUT
   513                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
   514                              <1> ; OUTPUT
   515                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
   516                              <1> ;-----------------------------------------------------
   517                              <1> 
   518 000014A1 E805000000          <1> 	call	set_active_page
   519 000014A6 E926FFFFFF          <1>         jmp     VIDEO_RETURN
   520                              <1> 
   521                              <1> set_active_page:   ; tty_sw
   522                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   523                              <1> 	; 30/06/2015
   524                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
   525                              <1> 	; 10/12/2013
   526                              <1> 	; 04/12/2013
   527                              <1> 	;
   528 000014AB A2[B8D20000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
   529                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
   530 000014B0 66B9A00F            <1> 	mov	cx, 25*80*2
   531                              <1> 	; 27/06/2015
   532 000014B4 0FB6D8              <1> 	movzx	ebx, al
   533                              <1> 	;
   534 000014B7 6698                <1> 	cbw	; 07/09/2014 (ah=0)
   535 000014B9 66F7E1              <1> 	mul 	cx	; display page times regen length
   536                              <1> 	; 10/12/2013
   537 000014BC 66A3[A4D20000]      <1> 	mov	[CRT_START], ax ; save start address for later
   538 000014C2 6689C1              <1> 	mov	cx, ax ; start address to cx
   539                              <1> 	;sar	cx, 1
   540 000014C5 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
   541 000014C8 B40C                <1> 	mov	ah, 12	; 6845 register for start address
   542 000014CA E8CF020000          <1> 	call	m16
   543                              <1> 	;sal	bx, 1
   544                              <1> 	; 01/09/2014
   545 000014CF D0E3                <1> 	shl	bl, 1	; *2 for word offset
   546 000014D1 81C3[A8D20000]      <1> 	add	ebx, CURSOR_POSN
   547 000014D7 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
   548                              <1> 	; 16/01/2016
   549                              <1> 	;call	m18
   550                              <1> 	;retn
   551 000014DA E9AB020000          <1> 	jmp	m18
   552                              <1> 
   553                              <1> position:
   554                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   555                              <1> 	; 27/06/2015
   556                              <1> 	; 02/09/2014
   557                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   558                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
   559                              <1> 	;
   560                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   561                              <1> 	;
   562                              <1> ;-----------------------------------------
   563                              <1> ; POSITION
   564                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
   565                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
   566                              <1> ; INPUT
   567                              <1> ;	AX = ROW, COLUMN POSITION
   568                              <1> ; OUTPUT
   569                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
   570                              <1> ;-----------------------------------------
   571                              <1> 
   572                              <1> 	; DX = ROW, COLUMN POSITION
   573                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
   574 000014DF 31C0                <1> 	xor	eax, eax ; 02/09/2014
   575 000014E1 B050                <1> 	mov	al, 80   ; determine bytes to row	
   576 000014E3 F6E6                <1> 	mul	dh	 ; row value
   577 000014E5 30F6                <1> 	xor	dh, dh   ; 0	
   578 000014E7 6601D0              <1> 	add	ax, dx	 ; add column value to the result
   579 000014EA 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
   580                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
   581 000014ED C3                  <1> 	retn
   582                              <1> 
   583                              <1> find_position:
   584                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   585                              <1> 	; 27/06/2015
   586                              <1> 	; 07/09/2014
   587                              <1> 	; 02/09/2014
   588                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   589                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   590 000014EE 0FB6CF              <1> 	movzx	ecx, bh ; video page number
   591 000014F1 89CE                <1> 	mov	esi, ecx
   592 000014F3 66D1E6              <1> 	shl	si, 1
   593 000014F6 668B96[A8D20000]    <1> 	mov	dx, [esi + CURSOR_POSN]
   594 000014FD 740A                <1> 	jz	short p21
   595 000014FF 6631F6              <1> 	xor	si, si
   596                              <1> p20:
   597                              <1> 	;add	si, [CRT_LEN]
   598 00001502 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
   599 00001507 E2F9                <1> 	loop	p20
   600                              <1> p21:
   601 00001509 6621D2              <1> 	and	dx, dx
   602 0000150C 7407                <1> 	jz	short p22
   603 0000150E E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
   604 00001513 01C6                <1> 	add	esi, eax ; add location to start of regen page
   605                              <1> p22:	
   606                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
   607                              <1> 	;mov	dx, 03D4h ; I/O address of color card
   608                              <1> 	;add	dx, 6	; point at status port
   609 00001515 66BADA03            <1> 	mov	dx, 03DAh ; status port
   610                              <1> 	; cx = 0
   611 00001519 C3                  <1> 	retn
   612                              <1> 
   613                              <1> SCROLL_UP:
   614                              <1> 	; 12/05/2016
   615                              <1> 	; 30/01/2016
   616                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   617                              <1> 	; 07/09/2014
   618                              <1> 	; 02/09/2014
   619                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
   620                              <1> 	; 04/04/2014
   621                              <1> 	; 04/12/2013
   622                              <1> 	;
   623                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   624                              <1> 	;
   625                              <1> ;----------------------------------------------
   626                              <1> ; SCROLL UP
   627                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
   628                              <1> ;	ON THE SCREEN
   629                              <1> ; INPUT
   630                              <1> ;	(AH) = CURRENT CRT MODE
   631                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
   632                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
   633                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
   634                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
   635                              <1> ;	(DS) = DATA SEGMENT
   636                              <1> ;	(ES) = REGEN BUFFER SEGMENT
   637                              <1> ; OUTPUT
   638                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
   639                              <1> ;--------------------------------------------
   640                              <1> 
   641 0000151A E805000000          <1> 	call	_scroll_up
   642 0000151F E9ADFEFFFF          <1>         jmp     VIDEO_RETURN
   643                              <1> 
   644                              <1> _scroll_up:  ; from 'write_tty'
   645                              <1> 	;
   646                              <1> 	; cl = left upper column
   647                              <1> 	; ch = left upper row
   648                              <1> 	; dl = right lower column
   649                              <1> 	; dh = right lower row
   650                              <1> 	;
   651                              <1> 	; al = line count 
   652                              <1> 	; bl = attribute to be used on blanked line	
   653                              <1> 	; bh = video page number (0 to 7)
   654                              <1> 
   655 00001524 E870000000          <1> 	call	test_line_count ; 16/01/2016
   656                              <1> 
   657                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
   658                              <1> 	;cmp	ah, 4
   659                              <1>  	;jb	short n1
   660                              <1> 
   661                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
   662                              <1> 	;jne	GRAPHICS_UP
   663                              <1> n1:
   664 00001529 88DC                <1> 	mov	ah, bl ; attribute
   665 0000152B 6650                <1> 	push	ax ; *
   666                              <1> 	;mov 	esi, [CRT_BASE]
   667 0000152D BE00800B00          <1>         mov     esi, 0B8000h  
   668 00001532 3A3D[B8D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
   669 00001538 750B                <1> 	jne	short n2
   670                              <1> 	;
   671 0000153A 66A1[A4D20000]      <1>         mov     ax, [CRT_START]
   672 00001540 6601C6              <1>         add     si, ax
   673 00001543 EB0F                <1>         jmp     short n4
   674                              <1> n2:
   675 00001545 20FF                <1>         and     bh, bh
   676 00001547 740B                <1> 	jz	short n4
   677 00001549 88F8                <1> 	mov	al, bh
   678                              <1> n3:
   679                              <1>         ;add    si, [CRT_LEN]
   680                              <1>         ;add    esi, 80*25*2 
   681 0000154B 6681C6A00F          <1>         add     si, 80*25*2
   682 00001550 FEC8                <1>         dec	al
   683 00001552 75F7                <1> 	jnz	short n3
   684                              <1> n4:	
   685 00001554 E853000000          <1> 	call	scroll_position ; 16/01/2016
   686 00001559 741D                <1>         jz      short n6 
   687                              <1> 
   688 0000155B 01CE                <1>         add     esi, ecx ; from address for scroll
   689 0000155D 88F5                <1> 	mov	ch, dh  ; #rows in block
   690 0000155F 28C5                <1> 	sub	ch, al	; #rows to be moved
   691                              <1> n5:
   692 00001561 E886000000          <1> 	call	n10 ; 16/01/2016
   693                              <1> 	
   694                              <1>         ;push	ecx
   695                              <1> 	;mov	cl, [CRT_COLS] 
   696                              <1> 	;add	cl, cl
   697                              <1>         ;mov	ecx, 80*2
   698                              <1> 	;add	esi, ecx  ; next line
   699                              <1>         ;add	edi, ecx
   700                              <1> 	;pop	ecx
   701                              <1> 
   702 00001566 81C6A0000000        <1> 	add     esi, 80*2 ; next line
   703 0000156C 81C7A0000000        <1> 	add     edi, 80*2
   704 00001572 FECD                <1> 	dec	ch	 ; count of lines to move
   705 00001574 75EB                <1> 	jnz	short n5 ; row loop
   706                              <1> 	; ch = 0
   707 00001576 88C6                <1> 	mov	dh, al	 ; #rows	
   708                              <1> n6:
   709                              <1> 	; attribute in ah
   710 00001578 B020                <1> 	mov	al, ' '	 ; fill with blanks
   711                              <1> n7:
   712 0000157A E87A000000          <1> 	call	n11 ; 16/01/2016
   713                              <1> 
   714                              <1> 	;push	ecx
   715                              <1> 	;mov	cl, [CRT_COLS]
   716                              <1> 	;add	cl, cl
   717                              <1>         ;mov	ecx, 80*2
   718                              <1>  	;add	edi, ecx
   719                              <1> 	;pop	ecx
   720                              <1> 
   721 0000157F 81C7A0000000        <1> 	add     edi, 80*2
   722 00001585 FECE                <1> 	dec	dh
   723 00001587 75F1                <1> 	jnz	short n7
   724                              <1> 	;
   725 00001589 3A3D[B8D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
   726 0000158F 7507                <1> 	jne	short n8
   727                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   728 00001591 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   729 00001593 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   730 00001597 EE                  <1> 	out	dx, al
   731                              <1> n8:
   732 00001598 C3                  <1> 	retn
   733                              <1> 
   734                              <1> 
   735                              <1> test_line_count:
   736                              <1> 	; 12/05/2016
   737                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   738                              <1> 	; 07/09/2014 (scroll_up)
   739 00001599 08C0                <1> 	or	al, al
   740 0000159B 740E                <1> 	jz	short al_set2
   741 0000159D 6652                <1> 	push	dx
   742 0000159F 28EE                <1> 	sub	dh, ch  ; subtract upper row from lower row number
   743 000015A1 FEC6                <1> 	inc	dh	; adjust difference by 1
   744 000015A3 38C6                <1> 	cmp	dh, al 	; line count = amount of rows in window?
   745 000015A5 7502                <1> 	jne	short al_set1 ; if not the we're all set
   746 000015A7 30C0                <1> 	xor	al, al	; otherwise set al to zero
   747                              <1> al_set1:
   748 000015A9 665A                <1> 	pop	dx
   749                              <1> al_set2:
   750 000015AB C3                  <1> 	retn
   751                              <1> 
   752                              <1> scroll_position:
   753                              <1> 	; 30/01/2016
   754                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   755                              <1> 	; 07/09/2014 (scroll_up)
   756                              <1> 
   757 000015AC 6652                <1> 	push	dx
   758 000015AE 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
   759 000015B1 E829FFFFFF          <1> 	call	position
   760 000015B6 01C6                <1> 	add	esi, eax
   761 000015B8 89F7                <1> 	mov	edi, esi
   762 000015BA 665A                <1> 	pop	dx	; lower right position in DX
   763 000015BC 6629CA              <1> 	sub	dx, cx
   764 000015BF FEC6                <1> 	inc	dh	; dh = #rows 
   765 000015C1 FEC2                <1> 	inc	dl	; dl = #cols in block
   766 000015C3 59                  <1> 	pop	ecx 	; return address
   767 000015C4 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
   768 000015C6 51                  <1> 	push	ecx	; return address
   769 000015C7 0FB7C8              <1> 	movzx	ecx, ax
   770                              <1> 	;mov	ah, [CRT_COLS]
   771 000015CA B450                <1> 	mov	ah, 80
   772 000015CC F6E4                <1> 	mul	ah	; determine offset to from address
   773 000015CE 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
   774                              <1> 	;
   775 000015D1 6650                <1> 	push	ax	; offset 
   776 000015D3 6652                <1> 	push	dx
   777                              <1> 	;
   778                              <1> 	; 04/04/2014
   779 000015D5 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
   780                              <1> n9:                      ; wait_display_enable
   781 000015D9 EC                  <1>         in      al, dx   ; get port
   782 000015DA A808                <1> 	test	al, RVRT ; wait for vertical retrace	
   783 000015DC 74FB                <1> 	jz	short n9 ; wait_display_enable
   784 000015DE B025                <1> 	mov	al, 25h
   785 000015E0 B2D8                <1> 	mov	dl, 0D8h ; address control port
   786 000015E2 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
   787 000015E3 665A                <1> 	pop	dx	; #rows, #cols
   788 000015E5 6658                <1>        	pop	ax	; offset
   789 000015E7 6691                <1> 	xchg	ax, cx	; 
   790                              <1> 	; ecx = offset, al = line count, ah = attribute
   791                              <1> 	;
   792 000015E9 08C0                <1> 	or	al, al
   793 000015EB C3                  <1> 	retn
   794                              <1> n10:
   795                              <1> 	; Move rows
   796 000015EC 88D1                <1> 	mov	cl, dl	; get # of cols to move
   797 000015EE 56                  <1> 	push	esi
   798 000015EF 57                  <1> 	push	edi	; save start address
   799                              <1> n10r:
   800 000015F0 66A5                <1> 	movsw		; move that line on screen
   801 000015F2 FEC9                <1> 	dec	cl
   802 000015F4 75FA                <1>         jnz     short n10r
   803 000015F6 5F                  <1> 	pop	edi
   804 000015F7 5E                  <1> 	pop	esi	; recover addresses
   805 000015F8 C3                  <1> 	retn
   806                              <1> n11:
   807                              <1> 	; Clear rows
   808                              <1>                 	; dh =  #rows
   809 000015F9 88D1                <1>         mov	cl, dl	; get # of cols to clear
   810 000015FB 57                  <1>         push    edi     ; save address
   811                              <1> n11r:
   812 000015FC 66AB                <1>         stosw           ; store fill character
   813 000015FE FEC9                <1> 	dec	cl
   814 00001600 75FA                <1>         jnz     short n11r
   815 00001602 5F                  <1>         pop     edi     ; recover address
   816 00001603 C3                  <1> 	retn
   817                              <1> 
   818                              <1> SCROLL_DOWN:
   819                              <1> 	; 12/05/2016
   820                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   821                              <1> 	;
   822                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   823                              <1> 
   824                              <1> ;------------------------------------------
   825                              <1> ; SCROLL DOWN
   826                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
   827                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
   828                              <1> ;	WITH A DEFINED CHARACTER
   829                              <1> ; INPUT
   830                              <1> ;	(AH) = CURRENT CRT MODE
   831                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
   832                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
   833                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
   834                              <1> ;	(BH) = FILL CHARACTER
   835                              <1> ;	(DS) = DATA SEGMENT
   836                              <1> ;	(ES) = REGEN SEGMENT
   837                              <1> ; OUTPUT
   838                              <1> ;	NONE -- SCREEN IS SCROLLED
   839                              <1> ;------------------------------------------
   840                              <1> 
   841                              <1> 	; cl = left upper column
   842                              <1> 	; ch = left upper row
   843                              <1> 	; dl = right lower column
   844                              <1> 	; dh = right lower row
   845                              <1> 	;
   846                              <1> 	; al = line count 
   847                              <1> 	; bl = attribute to be used on blanked line	
   848                              <1> 	; bh = video page number (0 to 7)
   849                              <1> 
   850                              <1> 	; !!!!
   851 00001604 FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
   852                              <1> 	; !!!!
   853 00001605 E88FFFFFFF          <1> 	call	test_line_count ; 16/01/2016
   854                              <1> 	
   855                              <1> 	;mov	ah, [CRT_MODE] ; current video mode
   856                              <1> 	;cmp	ah, 4
   857                              <1>  	;jb	short n12
   858                              <1> 
   859                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
   860                              <1> 	;jne	GRAPHICS_DOWN
   861                              <1> 
   862                              <1> n12:			; CONTINUE_DOWN
   863 0000160A 88DC                <1> 	mov	ah, bl
   864 0000160C 6650                <1> 	push	ax	; * ; save attribute in ah
   865 0000160E 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
   866 00001611 E896FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
   867 00001616 741D                <1> 	jz	short n14
   868 00001618 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
   869 0000161A 88F5                <1> 	mov	ch, dh  ; #rows in block
   870 0000161C 28C5                <1> 	sub	ch, al	; #rows to be moved
   871                              <1> n13:
   872 0000161E E8C9FFFFFF          <1> 	call	n10	; MOVE ONE ROW
   873                              <1> 
   874                              <1> 	;push	ecx
   875                              <1> 	;mov	cl, [CRT_COLS] 
   876                              <1> 	;add	cl, cl
   877                              <1>         ;mov	ecx, 80*2
   878                              <1> 	;sub	esi, ecx  ; next line
   879                              <1>         ;sub	edi, ecx
   880                              <1>         ;pop	ecx
   881                              <1> 	
   882 00001623 81EEA0000000        <1> 	sub     esi, 80*2  ; next line
   883 00001629 81EFA0000000        <1>         sub     edi, 80*2
   884 0000162F FECD                <1> 	dec	ch	 ; count of lines to move
   885 00001631 75EB                <1> 	jnz	short n13 ; row loop
   886                              <1> 	; ch = 0
   887 00001633 88C6                <1> 	mov	dh, al	 ; #rows
   888                              <1> n14:
   889                              <1> 	; attribute in ah
   890 00001635 B020                <1> 	mov	al, ' '	 ; fill with blanks
   891                              <1> n15:
   892 00001637 E8BDFFFFFF          <1> 	call	n11 ; 16/01/2016
   893                              <1> 
   894                              <1> 	;push	ecx
   895                              <1> 	;mov	cl, [CRT_COLS]
   896                              <1> 	;add	cl, cl
   897                              <1>         ;mov	ecx, 80*2
   898                              <1> 	;sub	edi, ecx
   899                              <1>         ;pop	ecx
   900                              <1> 
   901 0000163C 81EFA0000000        <1> 	sub	edi, 80*2
   902 00001642 FECE                <1> 	dec	dh
   903 00001644 75F1                <1> 	jnz	short n15
   904                              <1> 	;
   905 00001646 3A3D[B8D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
   906 0000164C 7507                <1> 	jne	short n16
   907                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   908 0000164E B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   909 00001650 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   910 00001654 EE                  <1> 	out	dx, al
   911                              <1> n16:
   912                              <1> 	; !!!!
   913 00001655 FC                  <1> 	cld		; Clear direction flag !
   914                              <1> 	; !!!!
   915 00001656 C3                  <1> 	retn
   916                              <1> 
   917                              <1> READ_AC_CURRENT:
   918                              <1> 	; 12/05/2016
   919                              <1> 	; 18/01/2016
   920                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   921                              <1> 	;
   922                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   923                              <1> 	;
   924                              <1> 
   925 00001657 E805000000          <1> 	call	_read_ac_current
   926                              <1> 	; 12/05/2016
   927                              <1>         ;jmp     VIDEO_RETURN
   928 0000165C E975FDFFFF          <1> 	jmp	_video_return
   929                              <1> 
   930                              <1> ;------------------------------------------------------------------------
   931                              <1> ; READ_AC_CURRENT							:
   932                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
   933                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
   934                              <1> ; INPUT									:
   935                              <1> ;	(AH) = CURRENT CRT MODE						:
   936                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
   937                              <1> ;	(DS) = DATA SEGMENT						:
   938                              <1> ;	(ES) = REGEN SEGMENT						:
   939                              <1> ; OUTPUT								:
   940                              <1> ;	(AL) = CHARACTER READ						:
   941                              <1> ;	(AH) = ATTRIBUTE READ						:
   942                              <1> ;------------------------------------------------------------------------
   943                              <1> 
   944                              <1> _read_ac_current:
   945                              <1> 	; 12/05/2016 
   946                              <1> 	; 18/01/2016
   947                              <1> p10:
   948 00001661 E888FEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
   949                              <1> 	;
   950                              <1> 	; esi = regen location
   951                              <1> 	; dx = status port
   952                              <1> 	;
   953                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
   954                              <1> 	;
   955                              <1> p11:			; wait for horizontal retrace is low or vertical
   956 00001666 FB                  <1> 	sti		; enable interrupts first
   957 00001667 3A3D[B8D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
   958 0000166D 750C                <1> 	jne	short p14 
   959 0000166F FA                  <1> 	cli 		; block interrupts for single loop
   960 00001670 EC                  <1> 	in	al, dx	; get status from the adapter
   961 00001671 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
   962 00001673 75F1                <1> 	jnz	short p11 ; wait until it is
   963                              <1> p12:			;  wait for either retrace high
   964 00001675 EC                  <1> 	in	al, dx ; get status again
   965 00001676 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
   966 00001678 74FB                <1> 	jz	short p12 ; wait until either retrace active
   967 0000167A FB                  <1> 	sti
   968                              <1> p14:
   969 0000167B 81C600800B00        <1> 	add	esi, 0B8000h 
   970 00001681 668B06              <1> 	mov	ax, [esi]
   971                              <1> 
   972 00001684 C3                  <1> 	retn	; 18/01/2016
   973                              <1> 
   974                              <1> WRITE_AC_CURRENT:
   975                              <1> 	; 12/05/2016
   976                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   977                              <1> 	;
   978                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   979                              <1> 	;
   980                              <1> ;----------------------------------------------------------------
   981                              <1> ; WRITE_AC_CURRENT						:
   982                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
   983                              <1> ;	AT THE CURRENT CURSOR POSITION				:
   984                              <1> ; INPUT								:
   985                              <1> ;	(AH) = CURRENT CRT MODE					:
   986                              <1> ;	(BH) = DISPLAY PAGE					:
   987                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   988                              <1> ;	(AL) = CHAR TO WRITE					:
   989                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
   990                              <1> ;	(DS) = DATA SEGMENT					:
   991                              <1> ;	(ES) = REGEN SEGMENT					:
   992                              <1> ; OUTPUT							:
   993                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   994                              <1> ;----------------------------------------------------------------
   995                              <1> 
   996 00001685 E821000000          <1> 	call	_write_c_current
   997                              <1> 
   998 0000168A 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
   999 0000168D 889E[F8CC0000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  1000                              <1> 
  1001 00001693 E939FDFFFF          <1>         jmp     VIDEO_RETURN
  1002                              <1> 
  1003                              <1> WRITE_C_CURRENT:
  1004                              <1> 	; 12/05/2016
  1005                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1006                              <1> 	;
  1007                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1008                              <1> 	;
  1009                              <1> 
  1010                              <1> 	;and	bh, 7 ; video page number (<= 7)
  1011 00001698 0FB6F7              <1> 	movzx	esi, bh	
  1012 0000169B 8A9E[F8CC0000]      <1> 	mov	bl, [esi+chr_attrib]
  1013                              <1> 
  1014 000016A1 E805000000          <1> 	call	_write_c_current
  1015 000016A6 E926FDFFFF          <1>         jmp     VIDEO_RETURN
  1016                              <1> 
  1017                              <1> ;----------------------------------------------------------------
  1018                              <1> ; WRITE_C_CURRENT						:
  1019                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
  1020                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
  1021                              <1> ; INPUT								:
  1022                              <1> ;	(AH) = CURRENT CRT MODE					:
  1023                              <1> ;	(BH) = DISPLAY PAGE					:
  1024                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  1025                              <1> ;	(AL) = CHAR TO WRITE					:
  1026                              <1> ;	(DS) = DATA SEGMENT					:
  1027                              <1> ;	(ES) = REGEN SEGMENT					:
  1028                              <1> ; OUTPUT							:
  1029                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  1030                              <1> ;----------------------------------------------------------------
  1031                              <1> 
  1032                              <1> _write_c_current:  ; from 'write_tty'
  1033                              <1> 	; 12/05/2016
  1034                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1035                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1036                              <1> 	; 18/01/2014
  1037                              <1> 	; 04/12/2013
  1038                              <1> 	;
  1039                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1040                              <1> 	;
  1041                              <1> 
  1042 000016AB FA                  <1> 	cli		
  1043                              <1> 	; al = character
  1044                              <1> 	; bl = color/attribute
  1045                              <1> 	; bh = video page
  1046 000016AC 6652                <1> 	push	dx
  1047 000016AE 88DC                <1> 	mov	ah, bl ; color/attribute (12/05/2016)
  1048 000016B0 6650                <1> 	push	ax	; save character & attribute/color
  1049 000016B2 E837FEFFFF          <1> 	call 	find_position  ; get regen location and port address
  1050                              <1> 	; esi = regen location
  1051                              <1> 	; dx = status port
  1052                              <1> 	;
  1053                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  1054                              <1> 	;
  1055                              <1> p41:			; wait for horizontal retrace is low or vertical
  1056 000016B7 FB                  <1> 	sti		; enable interrupts first
  1057 000016B8 3A3D[B8D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
  1058 000016BE 7510                <1> 	jne	short p44 
  1059 000016C0 FA                  <1> 	cli 		; block interrupts for single loop
  1060 000016C1 EC                  <1> 	in	al, dx	; get status from the adapter
  1061 000016C2 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  1062 000016C4 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  1063 000016C6 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1064 000016C8 75ED                <1> 	jnz	short p41 ; wait until it is
  1065                              <1> p42:			;  wait for either retrace high
  1066 000016CA EC                  <1> 	in	al, dx ; get status again
  1067 000016CB A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1068 000016CD 74FB                <1> 	jz	short p42 ; wait until either retrace active
  1069                              <1> p43:	
  1070 000016CF FB                  <1> 	sti
  1071                              <1> p44:
  1072 000016D0 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  1073 000016D2 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  1074                              <1> 				; Retro UNIX 386 v1 feature only!
  1075 000016D8 668906              <1> 	mov	[esi], ax
  1076 000016DB 665A                <1> 	pop	dx
  1077 000016DD C3                  <1> 	retn
  1078                              <1> 
  1079                              <1> ; 12/05/2016
  1080                              <1> ; 18/01/2016
  1081                              <1> ; 16/01/2016 - TRDOS 386 (TRDOS v2.0)
  1082                              <1> ; 30/06/2015
  1083                              <1> ; 27/06/2015
  1084                              <1> ; 11/03/2015
  1085                              <1> ; 02/09/2014
  1086                              <1> ; 30/08/2014
  1087                              <1> ; VIDEO FUNCTIONS
  1088                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1089                              <1> 
  1090                              <1> WRITE_TTY:
  1091                              <1> 	; 13/05/2016
  1092                              <1> 	; 12/05/2016
  1093                              <1> 	; 30/01/2016
  1094                              <1> 	; 18/01/2016
  1095                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1096                              <1> 	; 13/08/2015
  1097                              <1> 	; 02/09/2014
  1098                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1099                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1100                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1101                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1102                              <1> 	;
  1103                              <1> 	; INPUT -> AL = Character to be written
  1104                              <1> 	;	   BL = Color (Forecolor, Backcolor)
  1105                              <1> 	;	   BH = Video Page (0 to 7)
  1106                              <1> 
  1107                              <1> 	; 13/05/2016
  1108 000016DE E805000000          <1> 	call	_write_tty
  1109 000016E3 E9E9FCFFFF          <1> 	jmp	VIDEO_RETURN
  1110                              <1> 
  1111                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1112                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1113                              <1> 
  1114                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1115                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1116                              <1> ;
  1117                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1118                              <1> ;
  1119                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1120                              <1> ;										:
  1121                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1122                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1123                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1124                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1125                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1126                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1127                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1128                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1129                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1130                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1131                              <1> ;   THE 0 COLOR IS USED.							:
  1132                              <1> ;   ENTRY --									:
  1133                              <1> ;     (AH) = CURRENT CRT MODE							:
  1134                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1135                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1136                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1137                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1138                              <1> ;   EXIT -- 									:
  1139                              <1> ;     ALL REGISTERS SAVED							:
  1140                              <1> ;--------------------------------------------------------------------------------
  1141                              <1> 
  1142                              <1> _write_tty:	; 13/05/2016
  1143                              <1> 
  1144 000016E8 FA                  <1> 	cli
  1145                              <1> 	;
  1146                              <1> 	; 01/09/2014
  1147 000016E9 803D[E6CC0000]03    <1> 	cmp	byte [CRT_MODE], 3
  1148 000016F0 7405                <1> 	je	short m3
  1149                              <1> 	;
  1150 000016F2 E8A6FCFFFF          <1> 	call	set_mode_3 ; 16/01/2016
  1151                              <1> m3:
  1152 000016F7 0FB6F7              <1> 	movzx 	esi, bh ; 12/05/2016
  1153 000016FA 66D1E6              <1> 	shl	si, 1
  1154 000016FD 81C6[A8D20000]      <1> 	add	esi, CURSOR_POSN
  1155 00001703 668B16              <1> 	mov	dx, [esi]
  1156                              <1> 	;
  1157                              <1> 	; dx now has the current cursor position
  1158                              <1> 	;
  1159 00001706 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  1160 00001708 762F                <1> 	jbe	short u8
  1161                              <1> 	;
  1162                              <1> 	; write the char to the screen
  1163                              <1> u0:	
  1164                              <1> 	; al = character
  1165                              <1> 	; bl = attribute/color
  1166                              <1> 	; bh = video page number (0 to 7)
  1167                              <1> 	;
  1168 0000170A E89CFFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  1169                              <1> 	;
  1170                              <1> 	; position the cursor for next char
  1171 0000170F FEC2                <1> 	inc	dl		; next column
  1172                              <1> 	;cmp	dl, [CRT_COLS]
  1173 00001711 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  1174 00001714 755D                <1>         jne     _set_cpos
  1175 00001716 B200                <1> 	mov	dl, 0		; column = 0
  1176                              <1> u10:				; (line feed found)
  1177 00001718 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1178 0000171B 7218                <1> 	jb 	short u6
  1179                              <1> 	;
  1180                              <1> 	; scroll required
  1181                              <1> u1:	
  1182                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1183 0000171D E851000000          <1> 	call	_set_cpos
  1184                              <1> 	;
  1185                              <1> 	; determine value to fill with during scroll
  1186                              <1> u2:
  1187                              <1> 	; bh = video page number
  1188                              <1> 	;
  1189 00001722 E83AFFFFFF          <1> 	call _read_ac_current ; 18/01/2016
  1190                              <1> 	;
  1191                              <1> 	; al = character, ah = attribute
  1192                              <1> 	; bh = video page number 	
  1193                              <1> u3:
  1194                              <1> 	;;mov	ax, 0601h 	; scroll one line
  1195                              <1> 	;;sub	cx, cx		; upper left corner
  1196                              <1> 	;;mov	dh, 25-1 	; lower right row
  1197                              <1> 	;;;mov	dl, [CRT_COLS]
  1198                              <1> 	;mov	dl, 80		; lower right column	
  1199                              <1> 	;;dec	dl
  1200                              <1> 	;;mov	dl, 79
  1201                              <1> 
  1202                              <1> 	;;call	scroll_up	; 04/12/2013
  1203                              <1> 	;;; 11/03/2015
  1204                              <1> 	; 02/09/2014
  1205                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  1206                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  1207                              <1> 	; 11/03/2015
  1208 00001727 6629C9              <1> 	sub	cx, cx
  1209 0000172A 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  1210                              <1> 	;
  1211 0000172E B001                <1> 	mov	al, 1		; scroll 1 line up
  1212                              <1> 		; ah = attribute
  1213                              <1> 	;mov	bl, al ; 12/05/2016
  1214 00001730 E9EFFDFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  1215                              <1> ;u4:
  1216                              <1> 	;;int	10h		; video-call return
  1217                              <1> 				; scroll up the screen
  1218                              <1> 				; tty return
  1219                              <1> ;u5:
  1220                              <1> 	;retn			; return to the caller
  1221                              <1> 
  1222                              <1> u6:				; set-cursor-inc
  1223 00001735 FEC6                <1> 	inc	dh		; next row
  1224                              <1> 				; set cursor
  1225                              <1> ;u7:					
  1226                              <1> 	;;mov	ah, 02h
  1227                              <1> 	;;jmp	short u4 	; establish the new cursor
  1228                              <1> 	;call	_set_cpos
  1229                              <1> 	;jmp 	short u5
  1230 00001737 EB3A                <1> 	jmp     _set_cpos
  1231                              <1> 
  1232                              <1> 	; check for control characters
  1233                              <1> u8:
  1234 00001739 7436                <1> 	je	short u9
  1235 0000173B 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  1236 0000173D 74D9                <1> 	je	short u10
  1237 0000173F 3C07                <1> 	cmp	al, 07h 	; is it a bell
  1238 00001741 747A                <1> 	je	short u11
  1239 00001743 3C08                <1> 	cmp	al, 08h		; is it a backspace
  1240                              <1> 	;jne	short u0
  1241 00001745 7422                <1> 	je	short bs	; 12/12/2013
  1242                              <1> 	; 12/12/2013 (tab stop)
  1243 00001747 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  1244 00001749 75BF                <1> 	jne	short u0
  1245 0000174B 88D0                <1> 	mov	al, dl
  1246 0000174D 6698                <1> 	cbw
  1247 0000174F B108                <1> 	mov	cl, 8
  1248 00001751 F6F1                <1> 	div	cl
  1249 00001753 28E1                <1> 	sub	cl, ah
  1250                              <1> ts:
  1251                              <1> 	; 02/09/2014
  1252                              <1> 	; 01/09/2014
  1253 00001755 B020                <1> 	mov	al, 20h
  1254                              <1> tsloop:
  1255 00001757 6651                <1> 	push	cx
  1256 00001759 6650                <1> 	push	ax
  1257                              <1> 	;mov	bh, [ACTIVE_PAGE]
  1258 0000175B E897FFFFFF          <1> 	call	m3
  1259 00001760 6658                <1> 	pop	ax  ; ah = attribute/color
  1260 00001762 6659                <1> 	pop	cx
  1261 00001764 FEC9                <1> 	dec	cl
  1262 00001766 75EF                <1> 	jnz	short tsloop
  1263 00001768 C3                  <1> 	retn
  1264                              <1> bs:	
  1265                              <1> 	; back space found
  1266                              <1> 
  1267 00001769 08D2                <1> 	or	dl, dl 		; is it already at start of line
  1268                              <1> 	;je	short u7 	; set_cursor
  1269 0000176B 7406                <1> 	jz	short _set_cpos
  1270 0000176D 664A                <1> 	dec	dx     		; no -- just move it back
  1271                              <1> 	;jmp	short u7
  1272 0000176F EB02                <1> 	jmp	short _set_cpos
  1273                              <1> 
  1274                              <1> 	; carriage return found
  1275                              <1> u9:
  1276 00001771 B200                <1> 	mov	dl, 0 		; move to first column
  1277                              <1> 	;jmp	short u7
  1278                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  1279                              <1> 
  1280                              <1> 	; line feed found
  1281                              <1> ;u10:
  1282                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  1283                              <1> ;	jne	short u6 	; no, just set the cursor
  1284                              <1> ;       jmp     u1              ; yes, scroll the screen
  1285                              <1> 
  1286                              <1> _set_cpos:
  1287                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1288                              <1> 	; 27/06/2015
  1289                              <1> 	; 01/09/2014
  1290                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1291                              <1> 	;
  1292                              <1> 	; 04/12/2013 - 12/12/2013 (Retro UNIX 8086 v1) 
  1293                              <1> 	;
  1294                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1295                              <1> 	;
  1296                              <1> ;----------------------------------------------
  1297                              <1> ; SET_CPOS
  1298                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  1299                              <1> ;	NEW X-Y VALUES PASSED
  1300                              <1> ; INPUT
  1301                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  1302                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  1303                              <1> ; OUTPUT
  1304                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  1305                              <1> ;----------------------------------------------
  1306                              <1> 	;
  1307 00001773 BE[A8D20000]        <1> 	mov	esi, CURSOR_POSN
  1308 00001778 0FB6C7              <1>         movzx   eax, bh	; BH = video page number
  1309                              <1> ;	or	al, al
  1310                              <1> ;	jz	short _set_cpos_0
  1311 0000177B D0E0                <1>         shl     al, 1   ; word offset
  1312 0000177D 01C6                <1>         add     esi, eax
  1313                              <1> ;_set_cpos_0:
  1314 0000177F 668916              <1> 	mov	[esi], dx ; save the pointer
  1315 00001782 383D[B8D20000]      <1> 	cmp	[ACTIVE_PAGE], bh
  1316 00001788 7532                <1> 	jne	short m17
  1317                              <1> 	;call	m18	; CURSOR SET
  1318                              <1> ;m17:			; SET_CPOS_RETURN
  1319                              <1> 	; 01/09/2014
  1320                              <1> ;	retn
  1321                              <1> 		; DX  = row/column
  1322                              <1> m18:
  1323 0000178A E850FDFFFF          <1> 	call	position ; determine location in regen buffer	
  1324 0000178F 668B0D[A4D20000]    <1> 	mov	cx, [CRT_START]
  1325 00001796 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  1326                              <1> 			; to the start address (offset) for this page
  1327 00001799 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  1328 0000179C B40E                <1> 	mov	ah, 14	; register number for cursor
  1329                              <1> 	;call	m16	; output value to the 6845	
  1330                              <1> 	;retn
  1331                              <1> 
  1332                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  1333                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  1334                              <1> m16:
  1335 0000179E FA                  <1> 	cli
  1336                              <1> 	;mov	dx, [addr_6845] ; address register
  1337 0000179F 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  1338 000017A3 88E0                <1> 	mov	al, ah	; get value
  1339 000017A5 EE                  <1> 	out	dx, al	; register set
  1340 000017A6 6642                <1> 	inc	dx	; data register
  1341 000017A8 EB00                <1> 	jmp	$+2	; i/o delay
  1342 000017AA 88E8                <1> 	mov	al, ch	; data
  1343 000017AC EE                  <1> 	out	dx, al	
  1344 000017AD 664A                <1> 	dec	dx	
  1345 000017AF 88E0                <1> 	mov	al, ah
  1346 000017B1 FEC0                <1> 	inc	al	; point to other data register
  1347 000017B3 EE                  <1> 	out	dx, al	; set for second register
  1348 000017B4 6642                <1> 	inc	dx
  1349 000017B6 EB00                <1> 	jmp	$+2	; i/o delay
  1350 000017B8 88C8                <1> 	mov	al, cl	; second data value
  1351 000017BA EE                  <1> 	out	dx, al
  1352 000017BB FB                  <1> 	sti
  1353                              <1> m17:
  1354 000017BC C3                  <1> 	retn
  1355                              <1> 
  1356                              <1> beeper: 
  1357                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1358                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1359                              <1> 	; 18/01/2014
  1360                              <1> 	; 03/12/2013
  1361                              <1> 	; bell found
  1362                              <1> u11:
  1363 000017BD FB                  <1> 	sti
  1364 000017BE 3A3D[B8D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
  1365 000017C4 7551                <1> 	jne	short u12	; Do not sound the beep 
  1366                              <1> 				; if it is not written on the active page
  1367 000017C6 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  1368 000017CA B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  1369                              <1> 	;call	beep		; sound the pod bell
  1370                              <1> 	;jmp	short u5 	; tty_return
  1371                              <1> 	;retn
  1372                              <1> 	
  1373                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  1374                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  1375                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  1376                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  1377                              <1> 
  1378                              <1> beep:
  1379                              <1> 	; 07/02/2015
  1380                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1381                              <1> 	; 18/01/2014
  1382                              <1> 	; 03/12/2013
  1383                              <1> 	;
  1384                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  1385                              <1> 	;
  1386                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  1387                              <1> 	;
  1388                              <1> 	; ENTRY:
  1389                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  1390                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  1391                              <1> 	; EXIT:				:
  1392                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  1393                              <1> 
  1394 000017CC 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  1395 000017CD FA                  <1> 	cli			; block interrupts during update
  1396 000017CE B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  1397 000017D0 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  1398 000017D2 EB00                <1> 	jmp	$+2		; I/O delay
  1399 000017D4 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  1400 000017D6 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  1401 000017D8 EB00                <1> 	jmp	$+2		; I/O delay
  1402 000017DA 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  1403 000017DC E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  1404 000017DE E461                <1> 	in	al, PORT_B	; get current setting of port
  1405 000017E0 88C4                <1> 	mov	ah, al		; save that setting
  1406 000017E2 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  1407 000017E4 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  1408                              <1> 	;popf	; 18/01/2014
  1409 000017E6 FB                  <1> 	sti
  1410                              <1> g7:				; 1/64 second per count (bl)
  1411 000017E7 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  1412 000017EC E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  1413 000017F1 FECB                <1> 	dec	bl		; (bl) length count expired?
  1414 000017F3 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  1415                              <1> 	;
  1416                              <1> 	;pushf			; save interrupt status
  1417 000017F5 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  1418 000017F6 E461                <1> 	in	al, PORT_B	; get current port value
  1419                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  1420 000017F8 0CFC                <1>         or      al, ~(GATE2+SPK2)
  1421 000017FA 20C4                <1>         and	ah, al		; someone turned them off during beep
  1422 000017FC 88E0                <1> 	mov	al, ah		; recover value of port
  1423                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  1424 000017FE 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  1425 00001800 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  1426                              <1> 	;popf			; restore interrupt flag state
  1427 00001802 FB                  <1> 	sti
  1428 00001803 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  1429 00001808 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  1430                              <1> 	;pushf			; save interrupt status
  1431 0000180D FA                  <1> 	cli			; block interrupts during update
  1432 0000180E E461                <1> 	in	al, PORT_B	; get current port value in case	
  1433 00001810 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  1434 00001812 08E0                <1> 	or	al, ah		; recover value of port_b
  1435 00001814 E661                <1> 	out	PORT_B, al	; restore speaker status
  1436 00001816 9D                  <1> 	popf			; restore interrupt flag state
  1437                              <1> u12:	
  1438 00001817 C3                  <1> 	retn
  1439                              <1> 
  1440                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  1441                              <1> 
  1442                              <1> WAITF:
  1443                              <1> waitf:
  1444                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1445                              <1> 	; 03/12/2013
  1446                              <1> 	;
  1447                              <1> ;	push ax			; save work register (ah)	
  1448                              <1> ;waitf1:
  1449                              <1> 				; use timer 1 output bits
  1450                              <1> ;	in	al, PORT_B	; read current counter output status
  1451                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  1452                              <1> ;	cmp	al, ah		; did it just change
  1453                              <1> ;	je	short waitf1	; wait for a change in output line
  1454                              <1> ;	;
  1455                              <1> ;	mov	ah, al		; save new lflag state
  1456                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  1457                              <1> ;	;
  1458                              <1> ;	pop	ax		; restore (ah)
  1459                              <1> ;	retn			; return (cx)=0
  1460                              <1> 
  1461                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  1462                              <1> ; 17/12/2014 (dsectrm2.s)
  1463                              <1> ; WAITF
  1464                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  1465                              <1> ;
  1466                              <1> ;---WAITF-----------------------------------------------------------------------
  1467                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  1468                              <1> ; ENTRY:
  1469                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  1470                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  1471                              <1> ; EXIT:
  1472                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  1473                              <1> ;	(CX) = 0	
  1474                              <1> ;-------------------------------------------------------------------------------
  1475                              <1> 
  1476                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  1477                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  1478                              <1> 
  1479                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  1480 00001818 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  1481                              <1> 	; 16/12/2014
  1482                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  1483 0000181A D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  1484                              <1> ;17/12/2014	
  1485                              <1> ;WAITF1:
  1486                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  1487                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  1488                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  1489                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  1490                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  1491                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  1492                              <1> 	;
  1493                              <1> 	; 17/12/2014
  1494                              <1> 	;
  1495                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  1496                              <1> 	;
  1497                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  1498                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  1499                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  1500                              <1> WR_STATE_0:
  1501 0000181C E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1502 0000181E A810                <1> 	TEST	AL,010H
  1503 00001820 74FA                <1> 	JZ	SHORT WR_STATE_0
  1504                              <1> WR_STATE_1:
  1505 00001822 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1506 00001824 A810                <1> 	TEST	AL,010H
  1507 00001826 75FA                <1> 	JNZ	SHORT WR_STATE_1
  1508 00001828 E2F2                <1>         LOOP    WR_STATE_0
  1509                              <1> 	;
  1510 0000182A 6658                <1> 	POP	AX			; RESTORE (AH)
  1511 0000182C C3                  <1> 	RETn				; (CX) = 0
  1512                              <1> 
  1513                              <1> ; % include 'vidata.s' ; VIDEO DATA
  1514                              <1> 
  1515                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1656                                  
  1657                                  setup_rtc_int:
  1658                                  ; source: http://wiki.osdev.org/RTC
  1659 0000182D FA                      	cli		; disable interrupts
  1660                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  1661                                  	; in order to change this ...
  1662                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  1663                                  	; (rate must be above 2 and not over 15)
  1664                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  1665 0000182E B08A                    	mov	al, 8Ah 
  1666 00001830 E670                    	out	70h, al ; set index to register A, disable NMI
  1667 00001832 90                      	nop
  1668 00001833 E471                    	in	al, 71h ; get initial value of register A
  1669 00001835 88C4                    	mov 	ah, al
  1670 00001837 80E4F0                  	and	ah, 0F0h
  1671 0000183A B08A                    	mov	al, 8Ah 
  1672 0000183C E670                    	out	70h, al ; reset index to register A
  1673 0000183E 88E0                    	mov	al, ah
  1674 00001840 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1675 00001842 E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1676                                  	; enable RTC interrupt
  1677 00001844 B08B                    	mov	al, 8Bh ;
  1678 00001846 E670                    	out	70h, al ; select register B and disable NMI
  1679 00001848 90                      	nop
  1680 00001849 E471                    	in	al, 71h ; read the current value of register B
  1681 0000184B 88C4                    	mov	ah, al  ;
  1682 0000184D B08B                    	mov 	al, 8Bh ;
  1683 0000184F E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1684 00001851 88E0                    	mov	al, ah  ;
  1685 00001853 0C40                    	or	al, 40h ;
  1686 00001855 E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1687 00001857 FB                      	sti
  1688 00001858 C3                      	retn
  1689                                  
  1690                                  ; Write memory information
  1691                                  ; 29/01/2016
  1692                                  ; 06/11/2014
  1693                                  ; 14/08/2015 
  1694                                  memory_info:	
  1695 00001859 A1[8CD20000]            	mov	eax, [memory_size] ; in pages
  1696 0000185E 50                      	push	eax
  1697 0000185F C1E00C                  	shl	eax, 12		   ; in bytes
  1698 00001862 BB0A000000              	mov	ebx, 10
  1699 00001867 89D9                    	mov	ecx, ebx	   ; 10
  1700 00001869 BE[91CE0000]            	mov	esi, mem_total_b_str	
  1701 0000186E E8BD000000              	call	bintdstr
  1702 00001873 58                      	pop	eax
  1703 00001874 B107                    	mov	cl, 7
  1704 00001876 BE[B5CE0000]            	mov	esi, mem_total_p_str
  1705 0000187B E8B0000000              	call	bintdstr	
  1706                                  	; 14/08/2015
  1707 00001880 E8C8000000              	call	calc_free_mem
  1708                                  	; edx = calculated free pages
  1709                                  	; ecx = 0
  1710 00001885 A1[90D20000]            	mov 	eax, [free_pages]
  1711 0000188A 39D0                    	cmp	eax, edx ; calculated free mem value 
  1712                                  		; and initial free mem value are same or not?
  1713 0000188C 751D                    	jne 	short pmim ; print mem info with '?' if not
  1714 0000188E 52                      	push 	edx ; free memory in pages	
  1715                                  	;mov 	eax, edx
  1716 0000188F C1E00C                  	shl	eax, 12 ; convert page count
  1717                                  			; to byte count
  1718 00001892 B10A                    	mov	cl, 10
  1719 00001894 BE[D5CE0000]            	mov	esi, free_mem_b_str
  1720 00001899 E892000000              	call	bintdstr
  1721 0000189E 58                      	pop	eax
  1722 0000189F B107                    	mov	cl, 7
  1723 000018A1 BE[F9CE0000]            	mov	esi, free_mem_p_str
  1724 000018A6 E885000000              	call	bintdstr
  1725                                  pmim:
  1726 000018AB BE[7FCE0000]            	mov	esi, msg_memory_info
  1727                                  	;
  1728 000018B0 B407                    	mov	ah, 07h ; Black background, 
  1729                                  			; light gray forecolor
  1730                                  print_kmsg: ; 29/01/2016
  1731 000018B2 8825[B9D20000]          	mov	[ccolor], ah
  1732                                  pkmsg_loop:
  1733 000018B8 AC                      	lodsb
  1734 000018B9 08C0                    	or	al, al
  1735 000018BB 7410                    	jz	short pkmsg_ok
  1736 000018BD 56                      	push	esi
  1737                                  	; 13/05/2016
  1738 000018BE 0FB61D[B9D20000]        	movzx	ebx, byte [ccolor]
  1739                                  			; Video page 0 (bh=0)
  1740 000018C5 E81EFEFFFF              	call	_write_tty
  1741 000018CA 5E                      	pop	esi
  1742 000018CB EBEB                    	jmp	short pkmsg_loop
  1743                                  pkmsg_ok:
  1744 000018CD C3                      	retn
  1745                                  
  1746                                  ; Convert binary number to hexadecimal string
  1747                                  ; 10/05/2015  
  1748                                  ; dsectpm.s (28/02/2015)
  1749                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  1750                                  ; 01/12/2014
  1751                                  ; 25/11/2014
  1752                                  ;
  1753                                  bytetohex:
  1754                                  	; INPUT ->
  1755                                  	; 	AL = byte (binary number)
  1756                                  	; OUTPUT ->
  1757                                  	;	AX = hexadecimal string
  1758                                  	;
  1759 000018CE 53                      	push	ebx
  1760 000018CF 31DB                    	xor	ebx, ebx
  1761 000018D1 88C3                    	mov	bl, al
  1762 000018D3 C0EB04                  	shr	bl, 4
  1763 000018D6 8A9B[20190000]          	mov	bl, [ebx+hexchrs] 	 	
  1764 000018DC 86D8                    	xchg	bl, al
  1765 000018DE 80E30F                  	and	bl, 0Fh
  1766 000018E1 8AA3[20190000]          	mov	ah, [ebx+hexchrs] 
  1767 000018E7 5B                      	pop	ebx	
  1768 000018E8 C3                      	retn
  1769                                  
  1770                                  wordtohex:
  1771                                  	; INPUT ->
  1772                                  	; 	AX = word (binary number)
  1773                                  	; OUTPUT ->
  1774                                  	;	EAX = hexadecimal string
  1775                                  	;
  1776 000018E9 53                      	push	ebx
  1777 000018EA 31DB                    	xor	ebx, ebx
  1778 000018EC 86E0                    	xchg	ah, al
  1779 000018EE 6650                    	push	ax
  1780 000018F0 88E3                    	mov	bl, ah
  1781 000018F2 C0EB04                  	shr	bl, 4
  1782 000018F5 8A83[20190000]          	mov	al, [ebx+hexchrs] 	 	
  1783 000018FB 88E3                    	mov	bl, ah
  1784 000018FD 80E30F                  	and	bl, 0Fh
  1785 00001900 8AA3[20190000]          	mov	ah, [ebx+hexchrs]
  1786 00001906 C1E010                  	shl	eax, 16
  1787 00001909 6658                    	pop	ax
  1788 0000190B 5B                      	pop	ebx
  1789 0000190C EBC0                    	jmp	short bytetohex
  1790                                  	;mov	bl, al
  1791                                  	;shr	bl, 4
  1792                                  	;mov	bl, [ebx+hexchrs] 	 	
  1793                                  	;xchg	bl, al	 	
  1794                                  	;and	bl, 0Fh
  1795                                  	;mov	ah, [ebx+hexchrs] 
  1796                                  	;pop	ebx	
  1797                                  	;retn
  1798                                  
  1799                                  dwordtohex:
  1800                                  	; INPUT ->
  1801                                  	; 	EAX = dword (binary number)
  1802                                  	; OUTPUT ->
  1803                                  	;	EDX:EAX = hexadecimal string
  1804                                  	;
  1805 0000190E 50                      	push	eax
  1806 0000190F C1E810                  	shr	eax, 16
  1807 00001912 E8D2FFFFFF              	call	wordtohex
  1808 00001917 89C2                    	mov	edx, eax
  1809 00001919 58                      	pop	eax
  1810 0000191A E8CAFFFFFF              	call	wordtohex
  1811 0000191F C3                      	retn
  1812                                  
  1813                                  ; 10/05/2015
  1814                                  hex_digits:
  1815                                  hexchrs:
  1816 00001920 303132333435363738-     	db '0123456789ABCDEF'
  1816 00001929 39414243444546     
  1817                                  
  1818                                  ; Convert binary number to decimal/numeric string
  1819                                  ; 06/11/2014
  1820                                  ; Temporary Code
  1821                                  ;
  1822                                  
  1823                                  bintdstr:
  1824                                  	; EAX = binary number
  1825                                  	; ESI = decimal/numeric string address
  1826                                  	; EBX = divisor (10)
  1827                                  	; ECX = string length (<=10)
  1828 00001930 01CE                    	add	esi, ecx
  1829                                  btdstr0:
  1830 00001932 4E                      	dec	esi
  1831 00001933 31D2                    	xor	edx, edx
  1832 00001935 F7F3                    	div	ebx
  1833 00001937 80C230                  	add	dl, 30h
  1834 0000193A 8816                    	mov	[esi], dl
  1835 0000193C FEC9                    	dec	cl
  1836 0000193E 740C                    	jz	btdstr2
  1837 00001940 09C0                    	or	eax, eax
  1838 00001942 75EE                    	jnz	short btdstr0
  1839                                  btdstr1:
  1840 00001944 4E                      	dec	esi
  1841 00001945 C60620                          mov     byte [esi], 20h ; blank space
  1842 00001948 FEC9                    	dec	cl
  1843 0000194A 75F8                    	jnz	short btdstr1
  1844                                  btdstr2:
  1845 0000194C C3                      	retn
  1846                                  
  1847                                  ; Calculate free memory pages on M.A.T.
  1848                                  ; 06/11/2014
  1849                                  ; Temporary Code
  1850                                  ;
  1851                                  
  1852                                  calc_free_mem:
  1853 0000194D 31D2                    	xor	edx, edx
  1854                                  	;xor	ecx, ecx
  1855 0000194F 668B0D[A0D20000]        	mov	cx, [mat_size] ; in pages
  1856 00001956 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  1857 00001959 BE00001000              	mov	esi, MEM_ALLOC_TBL
  1858                                  cfm0:
  1859 0000195E AD                      	lodsd
  1860 0000195F 51                      	push	ecx
  1861 00001960 B920000000              	mov	ecx, 32
  1862                                  cfm1:
  1863 00001965 D1E8                    	shr	eax, 1
  1864 00001967 7301                    	jnc	short cfm2
  1865 00001969 42                      	inc	edx
  1866                                  cfm2:
  1867 0000196A E2F9                    	loop	cfm1
  1868 0000196C 59                      	pop	ecx
  1869 0000196D E2EF                    	loop	cfm0
  1870 0000196F C3                      	retn
  1871                                  
  1872                                  %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/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> ; 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 00001970 9C                  <1> 	pushfd
    31 00001971 0E                  <1> 	push 	cs
    32 00001972 E809000000          <1> 	call 	DISKETTE_IO_1
    33 00001977 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> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
   204                              <1> ; 10/12/2014
   205                              <1> ;
   206                              <1> ;int40h:
   207                              <1> ;	pushf
   208                              <1> ;	push 	cs
   209                              <1> ;	;cli
   210                              <1> ;	call 	DISKETTE_IO_1
   211                              <1> ;	retn
   212                              <1> 
   213                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
   214                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
   215                              <1> ;
   216                              <1> 
   217                              <1> ;-- INT13H ---------------------------------------------------------------------
   218                              <1> ; DISKETTE I/O
   219                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
   220                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
   221                              <1> ; INPUT
   222                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
   223                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
   224                              <1> ;		ON ALL DRIVES
   225                              <1> ;------------------------------------------------------------------------------- 
   226                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
   227                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
   228                              <1> ;-------------------------------------------------------------------------------
   229                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
   230                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   231                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
   232                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
   233                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
   234                              <1> ;		320/360	320/360	    0-39
   235                              <1> ;		320/360	1.2M	    0-39
   236                              <1> ;		1.2M	1.2M	    0-79
   237                              <1> ;		720K	720K	    0-79
   238                              <1> ;		1.44M	1.44M	    0-79	
   239                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
   240                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
   241                              <1> ;		320/360	320/360	     1-8/9
   242                              <1> ;		320/360	1.2M	     1-8/9
   243                              <1> ;		1.2M	1.2M	     1-15
   244                              <1> ;		720K	720K	     1-9
   245                              <1> ;		1.44M	1.44M	     1-18		
   246                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
   247                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
   248                              <1> ;		320/360	320/360	        8/9
   249                              <1> ;		320/360	1.2M	        8/9
   250                              <1> ;		1.2M	1.2M		15
   251                              <1> ;		720K	720K		9
   252                              <1> ;		1.44M	1.44M		18
   253                              <1> ;
   254                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
   255                              <1> ;
   256                              <1> ;-------------------------------------------------------------------------------
   257                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
   258                              <1> ;-------------------------------------------------------------------------------
   259                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
   260                              <1> ;-------------------------------------------------------------------------------
   261                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
   262                              <1> ;-------------------------------------------------------------------------------
   263                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
   264                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
   265                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
   266                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
   267                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
   268                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
   269                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
   270                              <1> ;		READ/WRITE ACCESS.
   271                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
   272                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
   273                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
   274                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
   275                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
   276                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
   277                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
   278                              <1> ;
   279                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
   280                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
   281                              <1> ;		---------------------------------------------
   282                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
   283                              <1> ;		---------------------------------------------
   284                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
   285                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
   286                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
   287                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
   288                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
   289                              <1> ;		---------------------------------------------
   290                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
   291                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
   292                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
   293                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
   294                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
   295                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
   296                              <1> ;-------------------------------------------------------------------------------
   297                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
   298                              <1> ;	REGISTERS
   299                              <1> ;	  INPUT
   300                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   301                              <1> ;	     ** 27/05/2016 - TRDOS 386 (TRDOS v2.0) **	
   302                              <1> ;            ** EBX = Buffer address for floppy disk parameters table **
   303                              <1> ;	  OUTPUT
   304                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
   305                              <1> ; 	    *** TRDOS 386 note: floppy disk parameter table (16 bytes)
   306                              <1> ;	    will be returned to user in EBX, buffer address *** 27/05/2016 ***		
   307                              <1> ;					
   308                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
   309                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   310                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   311                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
   312                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
   313                              <1> ;	    (BH) - 0
   314                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
   315                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
   316                              <1> ;	    (AX) - 0
   317                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
   318                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
   319                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
   320                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
   321                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
   322                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
   323                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
   324                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
   325                              <1> ;-------------------------------------------------------------------------------
   326                              <1> ;	(AH)= 15H  READ DASD TYPE
   327                              <1> ;	OUTPUT REGISTERS
   328                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
   329                              <1> ;		00 - DRIVE NOT PRESENT	
   330                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
   331                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
   332                              <1> ;		03 - RESERVED (FIXED DISK)
   333                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   334                              <1> ;-------------------------------------------------------------------------------
   335                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
   336                              <1> ;	OUTPUT REGISTERS
   337                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
   338                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
   339                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   340                              <1> ;-------------------------------------------------------------------------------
   341                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
   342                              <1> ;	INPUT REGISTERS
   343                              <1> ;	(AL) -	00 - NOT USED	
   344                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
   345                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
   346                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
   347                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
   348                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
   349                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
   350                              <1> ;-------------------------------------------------------------------------------
   351                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
   352                              <1> ;	INPUT REGISTERS
   353                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
   354                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   355                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   356                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
   357                              <1> ;	OUTPUT REGISTERS:
   358                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
   359                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
   360                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
   361                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
   362                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
   363                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
   364                              <1> ;-------------------------------------------------------------------------------
   365                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
   366                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
   367                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
   368                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
   369                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
   370                              <1> ;		CHANGE ERROR CODE
   371                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
   372                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
   373                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
   374                              <1> ;
   375                              <1> ; DATA VARIABLE -- @DISK_POINTER
   376                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
   377                              <1> ;-------------------------------------------------------------------------------
   378                              <1> ; OUTPUT FOR ALL FUNCTIONS
   379                              <1> ;	AH = STATUS OF OPERATION
   380                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
   381                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
   382                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
   383                              <1> ;		TYPE AH=(15)).
   384                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
   385                              <1> ;	FOR READ/WRITE/VERIFY
   386                              <1> ;		DS,BX,DX,CX PRESERVED
   387                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
   388                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
   389                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
   390                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
   391                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
   392                              <1> ;-------------------------------------------------------------------------------
   393                              <1> ;
   394                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
   395                              <1> ;
   396                              <1> ;   -----------------------------------------------------------------
   397                              <1> ;   |       |       |       |       |       |       |       |       |
   398                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
   399                              <1> ;   |       |       |       |       |       |       |       |       |
   400                              <1> ;   -----------------------------------------------------------------
   401                              <1> ;	|	|	|	|	|	|	|	|
   402                              <1> ;	|	|	|	|	|	-----------------
   403                              <1> ;	|	|	|	|	|		|
   404                              <1> ;	|	|	|	|    RESERVED		|
   405                              <1> ;	|	|	|	|		  PRESENT STATE
   406                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
   407                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
   408                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
   409                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
   410                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
   411                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
   412                              <1> ;	|	|	|	|	110: RESERVED
   413                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
   414                              <1> ;	|	|	|	|
   415                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
   416                              <1> ;	|	|	|
   417                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
   418                              <1> ;	|	|			DRIVE)
   419                              <1> ;	|	|
   420                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
   421                              <1> ;
   422                              <1> ;						00: 500 KBS
   423                              <1> ;						01: 300 KBS
   424                              <1> ;						10: 250 KBS
   425                              <1> ;						11: RESERVED
   426                              <1> ;
   427                              <1> ;
   428                              <1> ;-------------------------------------------------------------------------------
   429                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
   430                              <1> ;-------------------------------------------------------------------------------
   431                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
   432                              <1> ;-------------------------------------------------------------------------------
   433                              <1> 
   434                              <1> struc MD
   435 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   436 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   437 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   438 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
   439 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
   440 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
   441 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
   442 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
   443 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
   444 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
   445 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
   446 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
   447 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
   448                              <1> endstruc
   449                              <1> 
   450                              <1> BIT7OFF	EQU	7FH
   451                              <1> BIT7ON	EQU	80H
   452                              <1> 
   453                              <1> ;;int13h: ; 16/02/2015
   454                              <1> ;; 16/02/2015 - 21/02/2015
   455                              <1> int40h:
   456 00001978 9C                  <1> 	pushfd
   457 00001979 0E                  <1> 	push 	cs
   458 0000197A E801000000          <1> 	call 	DISKETTE_IO_1
   459 0000197F C3                  <1> 	retn	
   460                              <1> 
   461                              <1> DISKETTE_IO_1:
   462                              <1> 
   463 00001980 FB                  <1> 	STI				; INTERRUPTS BACK ON
   464 00001981 55                  <1> 	PUSH	eBP			; USER REGISTER
   465 00001982 57                  <1> 	PUSH	eDI			; USER REGISTER
   466 00001983 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   467 00001984 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   468 00001985 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   469 00001986 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
   470                              <1> 					; [BP]   = SECTOR #
   471                              <1> 					; [BP+1] = TRACK #
   472                              <1> 					; [BP+2] = BUFFER OFFSET
   473                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
   474                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
   475                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
   476                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
   477                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
   478                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
   479                              <1> 					; BH/[BP+3] = 0
   480                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
   481                              <1> 					; DH/[BP+5] = MAX HEAD #
   482                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
   483 00001988 06                  <1> 	push	es ; 06/02/2015	
   484 00001989 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   485 0000198A 56                  <1> 	PUSH	eSI			; USER REGISTERS
   486                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
   487                              <1> 	;mov	cx, cs
   488                              <1> 	;mov	ds, cx
   489 0000198B 66B91000            <1> 	mov	cx, KDATA
   490 0000198F 8ED9                <1>         mov     ds, cx
   491 00001991 8EC1                <1>         mov     es, cx
   492                              <1> 
   493                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   494 00001993 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4  ; 18/02/2015
   495 00001996 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   496 00001998 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   497                              <1> OK_FUNC:
   498 0000199A 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   499 0000199D 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   500 0000199F 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   501 000019A2 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   502 000019A4 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   503 000019A7 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   504 000019A9 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   505                              <1> OK_DRV:
   506 000019AB 31C9                <1> 	xor	ecx, ecx
   507                              <1> 	;mov	esi, ecx ; 08/02/2015
   508 000019AD 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   509 000019AF 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   510                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   511                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   512 000019B1 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   513 000019B4 BB[EC190000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   514 000019B9 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   515 000019BB 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   516 000019BD 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   517 000019BF 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   518 000019C2 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   519                              <1> 	;
   520                              <1> 	; 11/12/2014
   521 000019C5 8815[81CD0000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   522                              <1> 	;
   523 000019CB 8A25[12D30000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   524 000019D1 C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
   525                              <1> 
   526                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
   527                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
   528                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
   529                              <1> ;
   530                              <1> ;		DI	: DRIVE #
   531                              <1> ;		SI-HI	: HEAD #
   532                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
   533                              <1> ;		ES	: BUFFER SEGMENT
   534                              <1> ;		[BP]	: SECTOR #
   535                              <1> ;		[BP+1]	: TRACK #
   536                              <1> ;		[BP+2]	: BUFFER OFFSET
   537                              <1> ;
   538                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
   539                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
   540                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
   541                              <1> ;	SPECIFIC ERROR CODE.
   542                              <1> ;
   543                              <1> 					; (AH) = @DSKETTE_STATUS
   544 000019D8 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   545 000019DA 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   546 000019DB 1F                  <1> 	POP	DS
   547 000019DC 07                  <1> 	pop	es	; 06/02/2015
   548 000019DD 59                  <1> 	POP	eCX
   549 000019DE 5B                  <1> 	POP	eBX
   550 000019DF 5A                  <1> 	POP	eDX
   551 000019E0 5F                  <1> 	POP	eDI
   552 000019E1 89E5                <1> 	MOV	eBP, eSP
   553 000019E3 50                  <1> 	PUSH	eAX
   554 000019E4 9C                  <1> 	PUSHFd
   555 000019E5 58                  <1> 	POP	eAX
   556                              <1> 	;MOV	[BP+6], AX
   557 000019E6 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   558 000019E9 58                  <1> 	POP	eAX
   559 000019EA 5D                  <1> 	POP	eBP
   560 000019EB CF                  <1> 	IRETd
   561                              <1> 
   562                              <1> ;-------------------------------------------------------------------------------
   563                              <1> ; DW --> dd (06/02/2015)
   564 000019EC [501A0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   565 000019F0 [C91A0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   566 000019F4 [DA1A0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   567 000019F8 [EB1A0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   568 000019FC [FC1A0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   569 00001A00 [0D1B0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   570 00001A04 [921B0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   571 00001A08 [921B0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   572 00001A0C [9F1B0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   573 00001A10 [921B0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   574 00001A14 [921B0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   575 00001A18 [921B0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   576 00001A1C [921B0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   577 00001A20 [921B0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   578 00001A24 [921B0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   579 00001A28 [921B0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   580 00001A2C [921B0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   581 00001A30 [921B0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   582 00001A34 [921B0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   583 00001A38 [921B0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   584 00001A3C [921B0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   585 00001A40 [721C0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   586 00001A44 [9D1C0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   587 00001A48 [D71C0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   588 00001A4C [5A1D0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
   589                              <1> FNC_TAE EQU     $                       ; END
   590                              <1> 
   591                              <1> ;-------------------------------------------------------------------------------
   592                              <1> ; DISK_RESET	(AH = 00H)	
   593                              <1> ;		RESET THE DISKETTE SYSTEM.
   594                              <1> ;
   595                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   596                              <1> ;-------------------------------------------------------------------------------
   597                              <1> DSK_RESET:
   598 00001A50 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   599 00001A54 FA                  <1> 	CLI				; NO INTERRUPTS
   600 00001A55 A0[10D30000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   601 00001A5A 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   602 00001A5C C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   603                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   604 00001A5F 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   605 00001A61 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   606 00001A62 C605[0FD30000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
   607                              <1> 	;JMP	$+2			; WAIT FOR I/O
   608                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
   609                              <1> 					;      PULSE WIDTH)
   610                              <1> 	; 19/12/2014
   611                              <1> 	NEWIODELAY
   611 00001A69 E6EB                <2>  out 0ebh,al
   612                              <1> 
   613                              <1> 	; 17/12/2014 
   614                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   615 00001A6B B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   616                              <1> wdw1:
   617                              <1> 	NEWIODELAY   ; 27/02/2015
   617 00001A70 E6EB                <2>  out 0ebh,al
   618 00001A72 E2FC                <1> 	loop	wdw1
   619                              <1> 	;
   620 00001A74 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   621 00001A76 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   622                              <1> 	; 16/12/2014
   623                              <1> 	IODELAY
   623 00001A77 EB00                <2>  jmp short $+2
   623 00001A79 EB00                <2>  jmp short $+2
   624                              <1> 	;
   625                              <1> 	;STI				; ENABLE THE INTERRUPTS
   626 00001A7B E8370C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   627 00001A80 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   628 00001A82 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   629                              <1> NXT_DRV:
   630 00001A86 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   631 00001A88 B8[BE1A0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   632 00001A8D 50                  <1> 	PUSH	eAX			; "
   633 00001A8E B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   634 00001A90 E8150B0000          <1> 	CALL	NEC_OUTPUT
   635 00001A95 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   636 00001A96 E84C0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   637 00001A9B 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   638 00001A9D 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   639 00001A9F 3A0D[13D30000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   640 00001AA5 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   641 00001AA7 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   642 00001AA9 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   643 00001AAC 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   644                              <1> 	;
   645 00001AAE E864030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   646                              <1> RESBAC:
   647 00001AB3 E818090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   648 00001AB8 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   649 00001ABB 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   650 00001ABD C3                  <1> 	RETn		
   651                              <1> DR_POP_ERR:
   652 00001ABE 6659                <1> 	POP	CX			; CLEAR STACK
   653                              <1> DR_ERR:
   654 00001AC0 800D[12D30000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   655 00001AC7 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
   656                              <1> 
   657                              <1> ;-------------------------------------------------------------------------------
   658                              <1> ; DISK_STATUS	(AH = 01H)
   659                              <1> ;	DISKETTE STATUS.
   660                              <1> ;
   661                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
   662                              <1> ;
   663                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
   664                              <1> ;-------------------------------------------------------------------------------
   665                              <1> DSK_STATUS:
   666 00001AC9 8825[12D30000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   667 00001ACF E8FC080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   668 00001AD4 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   669 00001AD7 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   670 00001AD9 C3                  <1> 	RETn		
   671                              <1> 
   672                              <1> ;-------------------------------------------------------------------------------
   673                              <1> ; DISK_READ	(AH = 02H)	
   674                              <1> ;	DISKETTE READ.
   675                              <1> ;
   676                              <1> ; ON ENTRY:	DI	: DRIVE #
   677                              <1> ;		SI-HI	: HEAD #
   678                              <1> ;		SI-LOW	: # OF SECTORS
   679                              <1> ;		ES	: BUFFER SEGMENT
   680                              <1> ;		[BP]	: SECTOR #
   681                              <1> ;		[BP+1]	: TRACK #
   682                              <1> ;		[BP+2]	: BUFFER OFFSET
   683                              <1> ;
   684                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   685                              <1> ;-------------------------------------------------------------------------------
   686                              <1> 
   687                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   688                              <1> 
   689                              <1> DSK_READ:
   690 00001ADA 8025[10D30000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   691 00001AE1 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   692 00001AE5 E837040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   693 00001AEA C3                  <1> 	RETn
   694                              <1> 
   695                              <1> ;-------------------------------------------------------------------------------
   696                              <1> ; DISK_WRITE	(AH = 03H)
   697                              <1> ;	DISKETTE WRITE.
   698                              <1> ;
   699                              <1> ; ON ENTRY:	DI	: DRIVE #
   700                              <1> ;		SI-HI	: HEAD #
   701                              <1> ;		SI-LOW	: # OF SECTORS
   702                              <1> ;		ES	: BUFFER SEGMENT
   703                              <1> ;		[BP]	: SECTOR #
   704                              <1> ;		[BP+1]	: TRACK #
   705                              <1> ;		[BP+2]	: BUFFER OFFSET
   706                              <1> ;
   707                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   708                              <1> ;-------------------------------------------------------------------------------
   709                              <1> 
   710                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   711                              <1> 
   712                              <1> DSK_WRITE:
   713 00001AEB 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   714 00001AEF 800D[10D30000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   715 00001AF6 E826040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   716 00001AFB C3                  <1> 	RETn
   717                              <1> 
   718                              <1> ;-------------------------------------------------------------------------------
   719                              <1> ; DISK_VERF	(AH = 04H)
   720                              <1> ;	DISKETTE VERIFY.
   721                              <1> ;
   722                              <1> ; ON ENTRY:	DI	: DRIVE #
   723                              <1> ;		SI-HI	: HEAD #
   724                              <1> ;		SI-LOW	: # OF SECTORS
   725                              <1> ;		ES	: BUFFER SEGMENT
   726                              <1> ;		[BP]	: SECTOR #
   727                              <1> ;		[BP+1]	: TRACK #
   728                              <1> ;		[BP+2]	: BUFFER OFFSET
   729                              <1> ;
   730                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   731                              <1> ;-------------------------------------------------------------------------------
   732                              <1> DSK_VERF:
   733 00001AFC 8025[10D30000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   734 00001B03 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   735 00001B07 E815040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   736 00001B0C C3                  <1> 	RETn
   737                              <1> 
   738                              <1> ;-------------------------------------------------------------------------------
   739                              <1> ; DISK_FORMAT	(AH = 05H)
   740                              <1> ;	DISKETTE FORMAT.
   741                              <1> ;
   742                              <1> ; ON ENTRY:	DI	: DRIVE #
   743                              <1> ;		SI-HI	: HEAD #
   744                              <1> ;		SI-LOW	: # OF SECTORS
   745                              <1> ;		ES	: BUFFER SEGMENT
   746                              <1> ;		[BP]	: SECTOR #
   747                              <1> ;		[BP+1]	: TRACK #
   748                              <1> ;		[BP+2]	: BUFFER OFFSET
   749                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
   750                              <1> ;
   751                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   752                              <1> ;-------------------------------------------------------------------------------
   753                              <1> DSK_FORMAT:
   754 00001B0D E84E030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   755 00001B12 E84A050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   756 00001B17 800D[10D30000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   757 00001B1E E892050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   758 00001B23 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   759 00001B25 E8ED020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   760 00001B2A E8F8050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   761 00001B2F 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   762 00001B31 E8CF050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   763                              <1> FM_WR:
   764 00001B36 E885060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   765 00001B3B 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   766 00001B3D B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   767 00001B3F E8E2060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   768 00001B44 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   769 00001B46 B8[821B0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   770 00001B4B 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   771 00001B4C B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   772 00001B4E E851090000          <1> 	CALL	GET_PARM
   773 00001B53 E8520A0000          <1> 	CALL	NEC_OUTPUT
   774 00001B58 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   775 00001B5A E845090000          <1> 	CALL	GET_PARM
   776 00001B5F E8460A0000          <1> 	CALL	NEC_OUTPUT
   777 00001B64 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   778 00001B66 E839090000          <1> 	CALL	GET_PARM
   779 00001B6B E83A0A0000          <1> 	CALL	NEC_OUTPUT
   780 00001B70 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   781 00001B72 E82D090000          <1> 	CALL	GET_PARM
   782 00001B77 E82E0A0000          <1> 	CALL	NEC_OUTPUT
   783 00001B7C 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   784 00001B7D E822070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   785                              <1> FM_DON:
   786 00001B82 E80A030000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   787 00001B87 E844080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   788 00001B8C 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   789 00001B8F 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   790 00001B91 C3                  <1> 	RETn
   791                              <1> 
   792                              <1> ;-------------------------------------------------------------------------------
   793                              <1> ; FNC_ERR
   794                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
   795                              <1> ;	SET BAD COMMAND IN STATUS.
   796                              <1> ;
   797                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   798                              <1> ;-------------------------------------------------------------------------------
   799                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
   800 00001B92 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   801 00001B95 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   802 00001B97 8825[12D30000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   803 00001B9D F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   804 00001B9E C3                  <1> 	RETn
   805                              <1> 
   806                              <1> ; 28/05/2016
   807                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v.2.0)
   808                              <1> ;-------------------------------------------------------------------------------
   809                              <1> ; DISK_PARMS	(AH = 08H)	
   810                              <1> ;	READ DRIVE PARAMETERS.
   811                              <1> ;
   812                              <1> ; ON ENTRY:	DI : DRIVE #
   813                              <1> ;		; 27/05/2016
   814                              <1> ;		EBX = Buffer Address for floppy disk parameters table (16 bytes)
   815                              <1> ;
   816                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
   817                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
   818                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
   819                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
   820                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
   821                              <1> ;		BH/[BP+3] = 0
   822                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
   823                              <1> ;		DH/[BP+5] = MAX HEAD #
   824                              <1> ;	     ** 27/05/2016 - TRDOS 386 (TRDOS v2.0) **	
   825                              <1> ;            ** EBX = Buffer address for floppy disk parameters table **
   826                              <1> ;		;DI/[BP+6] = OFFSET TO DISK_BASE
   827                              <1> ;		;ES        = SEGMENT OF DISK_BASE
   828                              <1> ;
   829                              <1> ;		AX        = 0
   830                              <1> ;
   831                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
   832                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
   833                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
   834                              <1> ;		       CALLER.
   835                              <1> ;-------------------------------------------------------------------------------
   836                              <1> DSK_PARMS:
   837 00001B9F E8BC020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
   838                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
   839                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
   840                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
   841                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
   842                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
   843                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
   844                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
   845                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
   846                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
   847 00001BA4 29D2                <1> 	sub	edx, edx
   848 00001BA6 66A1[8ECD0000]      <1> 	mov     ax, [fd0_type]
   849 00001BAC 6621C0              <1> 	and     ax, ax
   850 00001BAF 0F8485000000        <1>         jz      NON_DRV
   851 00001BB5 FEC2                <1> 	inc     dl
   852 00001BB7 20E4                <1> 	and     ah, ah
   853 00001BB9 7402                <1> 	jz      short STO_DL
   854 00001BBB FEC2                <1> 	inc     dl
   855                              <1> STO_DL:
   856                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   857 00001BBD 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   858 00001BC0 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   859 00001BC4 7777                <1> 	JA	short NON_DRV1		; DRIVE INVALID
   860                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   861 00001BC6 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   862 00001BCA E8CC080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
   863                              <1> 	;;20/02/2015
   864                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
   865                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
   866 00001BCF 740F                <1> 	JZ	short CHK_EST		; JUMP IF SO
   867 00001BD1 E816020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   868 00001BD6 7208                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
   869                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
   870                              <1>         ;mov	[ebp+4], al ; 06/02/2015
   871 00001BD8 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   872 00001BDB 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   873 00001BDE EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   874                              <1> CHK_EST:
   875 00001BE0 8AA7[1FD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   876 00001BE6 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   877 00001BE9 7452                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   878                              <1> USE_EST:
   879 00001BEB 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   880 00001BEE 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   881 00001BF1 756B                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
   882                              <1> 
   883                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
   884                              <1> 
   885 00001BF3 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   886 00001BF5 E8F2010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   887 00001BFA 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   888 00001BFD 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   889 00001C00 F687[1FD30000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   890 00001C07 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
   891                              <1> 
   892                              <1> ;-----	IT IS 1.44 MB DRIVE
   893                              <1> 
   894                              <1> PARM144:
   895 00001C09 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   896 00001C0B E8DC010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   897 00001C10 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   898 00001C13 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   899                              <1> STO_CX:
   900 00001C16 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
   901                              <1> ES_DI:
   902                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
   903                              <1> 	;mov	[ebp+12], ebx ; 06/02/2015
   904                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
   905                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   906                              <1> 	;
   907                              <1> 	; 28/05/2016
   908                              <1> 	; 27/05/2016
   909                              <1> 	; return floppy disk parameters table to user
   910                              <1> 	; in user's buffer, which is pointed by EBX
   911                              <1> 	;
   912 00001C19 57                  <1> 	push	edi
   913 00001C1A 8B7D04              <1> 	mov	edi, [ebp+4]  		; ebx (input), user's buffer address
   914 00001C1D 0FB6C0              <1> 	movzx	eax, al
   915 00001C20 894504              <1>         mov	[ebp+4], eax   ; ebx	; drive type (for floppy drives)
   916 00001C23 89DE                <1> 	mov	esi, ebx 		; floppy disk parameter table (16 bytes)
   917 00001C25 B910000000          <1> 	mov	ecx, 16 ; 16 bytes
   918 00001C2A E82BA10000          <1>         call    transfer_to_user_buffer ; trdosk6.s (16/05/2016)
   919 00001C2F 5F                  <1> 	pop	edi	
   920                              <1> DP_OUT:
   921 00001C30 E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   922 00001C35 6631C0              <1> 	XOR	AX,AX			; CLEAR
   923 00001C38 F8                  <1> 	CLC
   924 00001C39 C3                  <1> 	RETn
   925                              <1> 
   926                              <1> ;-----	NO DRIYE PRESENT HANDLER
   927                              <1> 
   928                              <1> NON_DRV:
   929                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
   930 00001C3A 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   931                              <1> NON_DRV1:
   932 00001C3D 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   933 00001C42 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
   934                              <1> 
   935                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
   936                              <1> 	
   937 00001C44 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   938 00001C49 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   939 00001C4C B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   940 00001C4E F9                  <1> 	STC
   941 00001C4F C3                  <1> 	RETn
   942                              <1> 
   943                              <1> NON_DRV2:
   944                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   945 00001C50 31C0                <1> 	xor	eax, eax	
   946 00001C52 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   947                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   948 00001C56 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   949                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   950 00001C59 89450C              <1> 	mov	[ebp+12], eax
   951                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   952 00001C5C EBD2                <1> 	JMP	SHORT DP_OUT
   953                              <1> 
   954                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
   955                              <1> 
   956                              <1> USE_EST2:
   957 00001C5E B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   958 00001C60 E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   959 00001C65 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   960 00001C68 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   961 00001C6B 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   962 00001C6E 74A6                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   963 00001C70 EB97                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
   964                              <1> 
   965                              <1> ;-------------------------------------------------------------------------------
   966                              <1> ; DISK_TYPE (AH = 15H)	
   967                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
   968                              <1> ;
   969                              <1> ;  ON ENTRY:	DI = DRIVE #
   970                              <1> ;
   971                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
   972                              <1> ;-------------------------------------------------------------------------------
   973                              <1> DSK_TYPE:
   974 00001C72 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   975 00001C77 8A87[1FD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
   976 00001C7D 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
   977 00001C7F 7418                <1> 	JZ	short NO_DRV
   978 00001C81 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
   979 00001C83 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
   980 00001C85 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
   981 00001C87 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
   982                              <1> DT_BACK:
   983 00001C89 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
   984 00001C8B E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   985 00001C90 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
   986 00001C92 F8                  <1> 	CLC				; NO ERROR
   987 00001C93 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   988 00001C96 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   989 00001C98 C3                  <1> 	RETn
   990                              <1> NO_DRV:	
   991 00001C99 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
   992 00001C9B EBEC                <1> 	JMP	SHORT DT_BACK
   993                              <1> 
   994                              <1> ;-------------------------------------------------------------------------------
   995                              <1> ; DISK_CHANGE	(AH = 16H)
   996                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
   997                              <1> ;
   998                              <1> ; ON ENTRY:	DI = DRIVE #
   999                              <1> ;
  1000                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  1001                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  1002                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  1003                              <1> ;-------------------------------------------------------------------------------
  1004                              <1> DSK_CHANGE:
  1005 00001C9D E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1006 00001CA2 8A87[1FD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  1007 00001CA8 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  1008 00001CAA 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  1009 00001CAC A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  1010 00001CAE 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  1011                              <1> DC0:
  1012 00001CB0 E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  1013 00001CB5 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  1014                              <1> 
  1015 00001CB7 C605[12D30000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  1016                              <1> 
  1017 00001CBE E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1018 00001CC3 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1019 00001CC8 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  1020 00001CCB 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1021 00001CCD C3                  <1> 	RETn
  1022                              <1> DC_NON:
  1023 00001CCE 800D[12D30000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  1024 00001CD5 EBE7                <1> 	JMP	SHORT FINIS
  1025                              <1> 
  1026                              <1> ;-------------------------------------------------------------------------------
  1027                              <1> ; FORMAT_SET	(AH = 17H)
  1028                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  1029                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  1030                              <1> ;
  1031                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  1032                              <1> ;		DI     = DRIVE #
  1033                              <1> ;
  1034                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  1035                              <1> ;		AH = @DSKETTE_STATUS
  1036                              <1> ;		CY = 1 IF ERROR
  1037                              <1> ;-------------------------------------------------------------------------------
  1038                              <1> FORMAT_SET:
  1039 00001CD7 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1040 00001CDC 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1041 00001CDE 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1042 00001CE1 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1043 00001CE3 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1044 00001CE6 80A7[1FD30000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1045 00001CED 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1046 00001CEF 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1047 00001CF1 808F[1FD30000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1048 00001CF8 EB48                <1> 	JMP	SHORT S0
  1049                              <1> 
  1050                              <1> NOT_320:
  1051 00001CFA E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1052 00001CFF 803D[12D30000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1053 00001D06 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1054                              <1> S3:
  1055 00001D08 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1056 00001D0A 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1057 00001D0C 808F[1FD30000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1058 00001D13 EB2D                <1> 	JMP	SHORT S0
  1059                              <1> 
  1060                              <1> NOT_320_12:
  1061 00001D15 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1062 00001D17 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1063 00001D19 808F[1FD30000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1064 00001D20 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1065                              <1> 
  1066                              <1> NOT_12:	
  1067 00001D22 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1068 00001D24 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1069                              <1> 
  1070 00001D26 F687[1FD30000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1071 00001D2D 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1072 00001D2F B050                <1> 	MOV	AL,MED_DET+RATE_300
  1073 00001D31 F687[1FD30000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1074 00001D38 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1075                              <1> 
  1076                              <1> ASSUME:
  1077 00001D3A B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1078                              <1> 
  1079                              <1> OR_IT_IN:
  1080 00001D3C 0887[1FD30000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1081                              <1> S0:
  1082 00001D42 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1083 00001D47 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1084 00001D4C 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1085 00001D4E 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1086 00001D50 C3                  <1> 	RETn
  1087                              <1> 
  1088                              <1> FS_ERR:
  1089 00001D51 C605[12D30000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1090 00001D58 EBE8                <1> 	JMP	SHORT S0
  1091                              <1> 
  1092                              <1> ;-------------------------------------------------------------------------------
  1093                              <1> ; SET_MEDIA	(AH = 18H)
  1094                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  1095                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  1096                              <1> ;
  1097                              <1> ; ON ENTRY:
  1098                              <1> ;	[BP]	= SECTOR PER TRACK
  1099                              <1> ;	[BP+1]	= TRACK #
  1100                              <1> ;	DI	= DRIVE #
  1101                              <1> ;
  1102                              <1> ; ON EXIT:
  1103                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  1104                              <1> ;	IF NO ERROR:
  1105                              <1> ;		AH = 0
  1106                              <1> ;		CY = 0
  1107                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1108                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  1109                              <1> ;	IF ERROR:	
  1110                              <1> ;		AH = @DSKETTE_STATUS
  1111                              <1> ;		CY = 1
  1112                              <1> ;-------------------------------------------------------------------------------
  1113                              <1> SET_MEDIA:
  1114 00001D5A E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1115 00001D5F F687[1FD30000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1116 00001D66 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1117 00001D68 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1118 00001D6D 803D[12D30000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1119 00001D74 746B                <1> 	JE	short SM_RTN
  1120 00001D76 C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1121                              <1> SM_CMOS:
  1122 00001D7D E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1123                              <1> 	;;20/02/2015
  1124                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  1125                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  1126 00001D82 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1127 00001D84 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1128 00001D89 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1129 00001D8B 57                  <1> 	PUSH	eDI			; SAVE REG.
  1130 00001D8C 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1131 00001D8E B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1132                              <1> DR_SEARCH:
  1133 00001D93 8AA3[0CCD0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1134 00001D99 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1135 00001D9C 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1136 00001D9E 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1137                              <1> DR_FND:
  1138 00001DA0 8BBB[0DCD0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1139                              <1> MD_SEARCH:
  1140 00001DA6 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1141 00001DA9 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1142 00001DAC 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1143 00001DAE 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1144 00001DB1 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1145 00001DB4 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1146                              <1> NXT_MD:
  1147                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1148 00001DB6 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1149 00001DB9 E2D8                <1> 	LOOP    DR_SEARCH
  1150 00001DBB 5F                  <1> 	POP	eDI			; RESTORE REG.
  1151                              <1> MD_NOT_FND:
  1152 00001DBC C605[12D30000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1153 00001DC3 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1154                              <1> MD_FND:
  1155 00001DC5 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1156 00001DC8 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1157 00001DCA 7502                <1> 	JNE	short MD_SET
  1158 00001DCC 0C20                <1> 	OR	AL,DBL_STEP
  1159                              <1> MD_SET:
  1160                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1161 00001DCE 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1162 00001DD1 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1163 00001DD3 5F                  <1> 	POP	eDI
  1164 00001DD4 80A7[1FD30000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1165 00001DDB 0887[1FD30000]      <1> 	OR	[DSK_STATE+eDI], AL
  1166                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1167                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  1168                              <1> SM_RTN:
  1169 00001DE1 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1170 00001DE6 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1171 00001DEB C3                  <1> 	RETn
  1172                              <1> 
  1173                              <1> ;----------------------------------------------------------------
  1174                              <1> ; DR_TYPE_CHECK							:
  1175                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  1176                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  1177                              <1> ; ON ENTRY:							:
  1178                              <1> ;	AL = DRIVE TYPE						:
  1179                              <1> ; ON EXIT:							:
  1180                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  1181                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  1182                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  1183                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  1184                              <1> ; REGISTERS ALTERED: eBX						:
  1185                              <1> ;----------------------------------------------------------------		
  1186                              <1> DR_TYPE_CHECK:
  1187 00001DEC 6650                <1> 	PUSH	AX			
  1188 00001DEE 51                  <1> 	PUSH	eCX
  1189 00001DEF 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1190 00001DF1 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1191                              <1> TYPE_CHK:	
  1192 00001DF6 8AA3[0CCD0000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1193 00001DFC 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1194 00001DFE 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1195                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1196 00001E00 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1197 00001E03 E2F1                <1> 	LOOP    TYPE_CHK
  1198                              <1> 	;
  1199 00001E05 BB[6BCD0000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1200                              <1> 					; Default for GET_PARM (11/12/2014)
  1201                              <1> 	;
  1202 00001E0A F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1203 00001E0B EB06                <1> 	JMP	SHORT TYPE_RTN
  1204                              <1> DR_TYPE_VALID:
  1205 00001E0D 8B9B[0DCD0000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1206                              <1> TYPE_RTN:
  1207 00001E13 59                  <1> 	POP	eCX
  1208 00001E14 6658                <1> 	POP	AX
  1209 00001E16 C3                  <1> 	RETn	
  1210                              <1> 		
  1211                              <1> ;----------------------------------------------------------------
  1212                              <1> ; SEND_SPEC							:
  1213                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1214                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  1215                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  1216                              <1> ; ON EXIT:	NONE						:	
  1217                              <1> ; REGISTERS ALTERED: CX, DX					:
  1218                              <1> ;----------------------------------------------------------------		
  1219                              <1> SEND_SPEC:
  1220 00001E17 50                  <1> 	PUSH	eAX			; SAVE AX
  1221 00001E18 B8[3E1E0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1222 00001E1D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1223 00001E1E B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1224 00001E20 E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1225 00001E25 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1226 00001E27 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1227 00001E2C E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1228 00001E31 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1229 00001E33 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1230 00001E38 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1231 00001E3D 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1232                              <1> SPECBAC:
  1233 00001E3E 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1234 00001E3F C3                  <1> 	RETn
  1235                              <1> 
  1236                              <1> ;----------------------------------------------------------------
  1237                              <1> ; SEND_SPEC_MD							:
  1238                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1239                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  1240                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  1241                              <1> ; ON EXIT:	NONE						:	
  1242                              <1> ; REGISTERS ALTERED: AX						:
  1243                              <1> ;----------------------------------------------------------------		
  1244                              <1> SEND_SPEC_MD:
  1245 00001E40 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1246 00001E41 B8[5E1E0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1247 00001E46 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1248 00001E47 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1249 00001E49 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1250 00001E4E 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1251 00001E50 E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1252 00001E55 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1253 00001E58 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1254 00001E5D 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1255                              <1> SPEC_ESBAC:
  1256 00001E5E 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1257 00001E5F C3                  <1> 	RETn
  1258                              <1> 
  1259                              <1> ;-------------------------------------------------------------------------------
  1260                              <1> ; XLAT_NEW  
  1261                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  1262                              <1> ;	MODE TO NEW ARCHITECTURE.
  1263                              <1> ;
  1264                              <1> ; ON ENTRY:	DI = DRIVE #
  1265                              <1> ;-------------------------------------------------------------------------------
  1266                              <1> XLAT_NEW:
  1267 00001E60 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1268 00001E63 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1269 00001E65 80BF[1FD30000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1270 00001E6C 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1271 00001E6E 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1272 00001E71 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1273 00001E74 A0[1ED30000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1274 00001E79 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1275 00001E7B 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1276 00001E7D 80A7[1FD30000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1277 00001E84 0887[1FD30000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1278                              <1> XN_OUT:
  1279 00001E8A C3                  <1> 	RETn
  1280                              <1> DO_DET:
  1281 00001E8B E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1282 00001E90 C3                  <1> 	RETn
  1283                              <1> 
  1284                              <1> ;-------------------------------------------------------------------------------
  1285                              <1> ; XLAT_OLD 
  1286                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  1287                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  1288                              <1> ;
  1289                              <1> ; ON ENTRY:	DI = DRIVE
  1290                              <1> ;-------------------------------------------------------------------------------
  1291                              <1> XLAT_OLD:
  1292 00001E91 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1293                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1294 00001E94 0F8786000000        <1>         ja      XO_OUT
  1295 00001E9A 80BF[1FD30000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1296 00001EA1 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  1297                              <1> 
  1298                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  1299                              <1> 
  1300 00001EA3 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1301 00001EA6 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1302 00001EA9 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1303 00001EAB D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1304 00001EAD 8425[1ED30000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1305 00001EB3 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  1306                              <1> 
  1307                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  1308                              <1> 
  1309 00001EB5 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1310 00001EB7 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1311 00001EB9 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1312 00001EBB 2025[1ED30000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  1313                              <1> 
  1314                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  1315                              <1> 
  1316 00001EC1 8A87[1FD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1317 00001EC7 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1318 00001EC9 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1319 00001ECB 0805[1ED30000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1320                              <1> 
  1321                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1322                              <1> 
  1323                              <1> SAVE_SET:
  1324 00001ED1 8AA7[1FD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1325 00001ED7 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1326 00001ED9 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1327 00001EDC 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1328 00001EDF 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1329 00001EE1 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1330 00001EE3 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1331 00001EE6 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1332 00001EE8 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1333 00001EEB 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1334                              <1> UNKNO:
  1335 00001EED B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1336 00001EEF EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1337                              <1> CHK_144:
  1338 00001EF1 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1339                              <1> 	;;20/02/2015
  1340                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  1341 00001EF6 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1342 00001EF8 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1343 00001EFA 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1344 00001EFC B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1345 00001EFE EB0C                <1> 	JMP	SHORT TST_DET
  1346                              <1> CHK_250:
  1347 00001F00 B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1348 00001F02 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1349 00001F05 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1350 00001F07 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1351 00001F0A 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1352                              <1> TST_DET:
  1353 00001F0C F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1354 00001F0F 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1355 00001F11 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1356                              <1> AL_SET:
  1357 00001F13 80A7[1FD30000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1358 00001F1A 0887[1FD30000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1359                              <1> XO_OUT:
  1360 00001F20 C3                  <1> 	RETn
  1361                              <1> 
  1362                              <1> ;-------------------------------------------------------------------------------
  1363                              <1> ; RD_WR_VF
  1364                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  1365                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  1366                              <1> ;
  1367                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  1368                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  1369                              <1> ;
  1370                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1371                              <1> ;-------------------------------------------------------------------------------
  1372                              <1> RD_WR_VF:
  1373 00001F21 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1374 00001F23 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1375 00001F28 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1376 00001F2D 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1377                              <1> DO_AGAIN:
  1378 00001F2F 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1379 00001F31 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1380 00001F36 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1381 00001F38 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1382                              <1> RWV:
  1383 00001F3E 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1384 00001F40 8AB7[1FD30000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1385 00001F46 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1386 00001F49 E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  1387                              <1> 	;;20/02/2015
  1388                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  1389 00001F4E 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1390 00001F50 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1391 00001F52 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1392 00001F54 F687[1FD30000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1393 00001F5B 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1394 00001F5D B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1395 00001F5F EB0F                <1> 	JMP	SHORT RWV_2
  1396                              <1> RWV_1:
  1397 00001F61 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1398 00001F63 F687[1FD30000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1399 00001F6A 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1400 00001F6C B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1401 00001F6E EB04                <1> 	jmp	short rwv_3
  1402                              <1> RWV_2:
  1403 00001F70 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1404 00001F72 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1405                              <1> rwv_3:
  1406 00001F74 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1407 00001F79 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  1408                              <1> 
  1409                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  1410                              <1> 
  1411 00001F7B 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1412 00001F7C 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1413 00001F7E B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1414                              <1> RWV_DR_SEARCH:
  1415 00001F83 8AA3[0CCD0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1416 00001F89 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1417 00001F8C 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1418 00001F8E 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1419                              <1> RWV_DR_FND:
  1420 00001F90 8BBB[0DCD0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1421                              <1> RWV_MD_SEARH:
  1422 00001F96 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1423 00001F99 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  1424                              <1> RWV_NXT_MD:
  1425                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1426 00001F9B 83C305              <1> 	add	eBX, 5
  1427 00001F9E E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1428 00001FA0 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1429                              <1> 
  1430                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1431                              <1> 
  1432                              <1> RWV_ASSUME:
  1433 00001FA1 BB[2ACD0000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1434 00001FA6 F687[1FD30000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1435 00001FAD 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1436 00001FAF BB[44CD0000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1437 00001FB4 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  1438                              <1> 
  1439                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  1440                              <1> 	 			
  1441                              <1> RWV_MD_FND:
  1442 00001FB6 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1443 00001FB8 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1444                              <1> 	
  1445                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  1446                              <1> 
  1447                              <1> RWV_MD_FND1:
  1448 00001FB9 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1449 00001FBE E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1450 00001FC3 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1451 00001FC5 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1452                              <1> RWV_DBL:
  1453 00001FCA 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1454 00001FCB E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1455 00001FD0 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1456 00001FD1 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1457 00001FD3 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1458 00001FD5 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1459 00001FD7 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1460 00001FD8 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1461 00001FDD 5B                  <1> 	POP	eBX 
  1462 00001FDE 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1463 00001FE0 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1464 00001FE2 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1465 00001FE4 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1466 00001FE5 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1467 00001FEA 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1468 00001FEB 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1469 00001FED E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1470 00001FF2 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1471 00001FF4 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1472                              <1> CHK_RET:
  1473 00001FF9 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1474 00001FFE 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1475 00002000 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1476 00002002 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1477                              <1> RWV_END:
  1478 00002007 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1479 0000200C E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1480                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1481 00002011 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1482 00002013 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1483 00002018 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1484 0000201A E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1485 0000201F C3                  <1> 	RETn
  1486                              <1> 
  1487                              <1> ;-------------------------------------------------------------------------------
  1488                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1489                              <1> ;-------------------------------------------------------------------------------
  1490                              <1> SETUP_STATE:
  1491 00002020 F687[1FD30000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1492 00002027 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1493 00002029 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1494 0000202D F687[1FD30000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1495 00002034 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1496 00002036 F687[1FD30000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1497 0000203D 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1498 0000203F 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1499                              <1> AX_SET:	
  1500 00002043 80A7[1FD30000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1501 0000204A 08A7[1FD30000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1502 00002050 8025[1AD30000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1503 00002057 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1504 0000205A 0805[1AD30000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1505                              <1> J1C:	
  1506 00002060 C3                  <1> 	RETn
  1507                              <1> 
  1508                              <1> ;-------------------------------------------------------------------------------
  1509                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  1510                              <1> ;-------------------------------------------------------------------------------
  1511                              <1> FMT_INIT:
  1512 00002061 F687[1FD30000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1513 00002068 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1514 0000206A E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  1515                              <1> 	;; 20/02/2015
  1516                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  1517 0000206F 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1518 00002071 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1519                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1520 00002073 8AA7[1FD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1521 00002079 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1522 0000207C 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1523 0000207E 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1524 00002080 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1525 00002083 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1526                              <1> N_360:	
  1527 00002085 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1528 00002087 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1529                              <1> F1_RATE:
  1530 00002089 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1531 0000208C EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1532                              <1> N_12:	
  1533 0000208E FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1534 00002090 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1535 00002092 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1536 00002095 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1537 00002097 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1538 0000209A 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1539 0000209C 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1540 0000209F EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1541                              <1> N_720:
  1542 000020A1 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1543 000020A3 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1544 000020A5 EBE2                <1> 	JMP	SHORT F1_RATE
  1545                              <1> ISNT_12: 
  1546 000020A7 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1547                              <1> 
  1548                              <1> SKP_STATE:
  1549 000020AA 88A7[1FD30000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1550                              <1> F1_OUT:
  1551 000020B0 C3                  <1> 	RETn
  1552                              <1> CL_DRV:	
  1553 000020B1 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1554 000020B3 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  1555                              <1> 
  1556                              <1> ;-------------------------------------------------------------------------------
  1557                              <1> ; MED_CHANGE	
  1558                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  1559                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  1560                              <1> ;
  1561                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  1562                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  1563                              <1> ;-------------------------------------------------------------------------------
  1564                              <1> MED_CHANGE:
  1565 000020B5 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1566 000020BA 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1567 000020BC 80A7[1FD30000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  1568                              <1> 
  1569                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  1570                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  1571                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  1572                              <1> 
  1573 000020C3 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1574 000020C6 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1575 000020C8 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1576 000020CA F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1577 000020CC FA                  <1> 	CLI				; NO INTERRUPTS
  1578 000020CD 2005[10D30000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1579 000020D3 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1580 000020D4 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  1581                              <1> 
  1582                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  1583                              <1> 
  1584 000020D9 E872F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1585 000020DE B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1586 000020E0 E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1587 000020E5 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1588 000020E7 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1589 000020EC C605[12D30000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1590                              <1> OK1:
  1591 000020F3 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1592 000020F8 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1593                              <1> OK4:
  1594 000020FA C605[12D30000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1595                              <1> OK2:		
  1596 00002101 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1597 00002102 C3                  <1> 	RETn
  1598                              <1> MC_OUT:
  1599 00002103 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1600 00002104 C3                  <1> 	RETn
  1601                              <1> 
  1602                              <1> ;-------------------------------------------------------------------------------
  1603                              <1> ; SEND_RATE
  1604                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  1605                              <1> ; ON ENTRY:	DI = DRIVE #
  1606                              <1> ; ON EXIT:	NONE
  1607                              <1> ; REGISTERS ALTERED: DX
  1608                              <1> ;-------------------------------------------------------------------------------
  1609                              <1> SEND_RATE:
  1610 00002105 6650                <1> 	PUSH	AX			; SAVE REG.
  1611 00002107 8025[1AD30000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1612 0000210E 8A87[1FD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1613 00002114 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1614 00002116 0805[1AD30000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1615 0000211C C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1616 0000211F 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1617 00002123 EE                  <1> 	OUT	DX,AL
  1618 00002124 6658                <1> 	POP	AX			; RESTORE REG.
  1619 00002126 C3                  <1> 	RETn
  1620                              <1> 
  1621                              <1> ;-------------------------------------------------------------------------------
  1622                              <1> ; CHK_LASTRATE
  1623                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  1624                              <1> ; ON ENTRY:
  1625                              <1> ;	DI = DRIVE #
  1626                              <1> ; ON EXIT:
  1627                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  1628                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  1629                              <1> ; REGISTERS ALTERED: DX
  1630                              <1> ;-------------------------------------------------------------------------------
  1631                              <1> CHK_LASTRATE:
  1632 00002127 6650                <1> 	PUSH	AX			; SAVE REG
  1633 00002129 2225[1AD30000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1634 0000212F 8A87[1FD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1635 00002135 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1636 00002139 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1637                              <1> 					; ZF = 1 RATE IS THE SAME
  1638 0000213B 6658                <1> 	POP	AX			; RESTORE REG.
  1639 0000213D C3                  <1> 	RETn
  1640                              <1> 
  1641                              <1> ;-------------------------------------------------------------------------------
  1642                              <1> ; DMA_SETUP
  1643                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  1644                              <1> ;
  1645                              <1> ; ON ENTRY:	AL = DMA COMMAND
  1646                              <1> ;
  1647                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1648                              <1> ;-------------------------------------------------------------------------------
  1649                              <1> 
  1650                              <1> ; SI = Head #, # of Sectors or DASD Type
  1651                              <1> 
  1652                              <1> ; 22/08/2015
  1653                              <1> ; 08/02/2015 - Protected Mode Modification
  1654                              <1> ; 06/02/2015 - 07/02/2015
  1655                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  1656                              <1> ; (DMA Addres = Physical Address)
  1657                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  1658                              <1> ;
  1659                              <1> 
  1660                              <1> 
  1661                              <1> ; 04/02/2016 (clc)
  1662                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  1663                              <1> ; 16/12/2014 (IODELAY)
  1664                              <1> 
  1665                              <1> DMA_SETUP:
  1666                              <1> 
  1667                              <1> ;; 20/02/2015
  1668 0000213E 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1669 00002141 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1670 00002147 756E                <1> 	jnz	short dma_bnd_err_stc
  1671                              <1> 	;
  1672 00002149 6650                <1> 	push	ax			; DMA command
  1673 0000214B 52                  <1> 	push	edx			; *
  1674 0000214C B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1675 0000214E E851030000          <1> 	call	GET_PARM		; 
  1676 00002153 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1677 00002155 6689F0              <1> 	mov	ax, si			; Sector count
  1678 00002158 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1679 0000215A 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1680 0000215C 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1681 0000215F 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1682 00002162 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1683 00002164 6689C1              <1> 	mov	cx, ax
  1684 00002167 5A                  <1> 	pop	edx			; *
  1685 00002168 6658                <1> 	pop	ax
  1686 0000216A 3C42                <1> 	cmp	al, 42h
  1687 0000216C 7507                <1>         jne     short NOT_VERF
  1688 0000216E BA0000FF00          <1> 	mov	edx, 0FF0000h
  1689 00002173 EB08                <1> 	jmp	short J33
  1690                              <1> NOT_VERF:
  1691 00002175 6601CA              <1> 	add	dx, cx			; check for overflow
  1692 00002178 723E                <1> 	jc	short dma_bnd_err
  1693                              <1> 	;
  1694 0000217A 6629CA              <1> 	sub	dx, cx			; Restore start address
  1695                              <1> J33:
  1696 0000217D FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1697 0000217E E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1698                              <1> 	IODELAY				; WAIT FOR I/O
  1698 00002180 EB00                <2>  jmp short $+2
  1698 00002182 EB00                <2>  jmp short $+2
  1699 00002184 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1700 00002186 89D0                <1> 	mov	eax, edx		; Buffer address
  1701 00002188 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1702                              <1> 	IODELAY				; WAIT FOR I/O
  1702 0000218A EB00                <2>  jmp short $+2
  1702 0000218C EB00                <2>  jmp short $+2
  1703 0000218E 88E0                <1> 	MOV	AL,AH
  1704 00002190 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1705 00002192 C1E810              <1> 	shr	eax, 16
  1706                              <1> 	IODELAY				; I/O WAIT STATE
  1706 00002195 EB00                <2>  jmp short $+2
  1706 00002197 EB00                <2>  jmp short $+2
  1707 00002199 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1708                              <1> 	IODELAY
  1708 0000219B EB00                <2>  jmp short $+2
  1708 0000219D EB00                <2>  jmp short $+2
  1709 0000219F 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1710 000021A2 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1711                              <1> 	IODELAY				; WAIT FOR I/O
  1711 000021A4 EB00                <2>  jmp short $+2
  1711 000021A6 EB00                <2>  jmp short $+2
  1712 000021A8 88E0                <1> 	MOV	AL, AH
  1713 000021AA E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1714                              <1> 	IODELAY
  1714 000021AC EB00                <2>  jmp short $+2
  1714 000021AE EB00                <2>  jmp short $+2
  1715 000021B0 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1716 000021B1 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1717 000021B3 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1718                              <1> 
  1719 000021B5 F8                  <1> 	clc	; 04/02/2016
  1720 000021B6 C3                  <1> 	retn
  1721                              <1> 
  1722                              <1> dma_bnd_err_stc:
  1723 000021B7 F9                  <1> 	stc
  1724                              <1> dma_bnd_err:
  1725 000021B8 C605[12D30000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1726 000021BF C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  1727                              <1> 
  1728                              <1> ;; 16/12/2014
  1729                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1730                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1731                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1732                              <1> ;;	IODELAY
  1733                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1734                              <1> ;;	;SIODELAY
  1735                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  1736                              <1> ;;      ;JNE	short NOT_VERF		; NO
  1737                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  1738                              <1> ;;      ;JMP	SHORT J33
  1739                              <1> ;;;NOT_VERF:	
  1740                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1741                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1742                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1743                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1744                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1745                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  1746                              <1> ;;	;JNC	short J33
  1747                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1748                              <1> ;;;J33:
  1749                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  1750                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1751                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1752                              <1> ;;	IODELAY
  1753                              <1> ;;	MOV	AL,AH
  1754                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1755                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  1756                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1757                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1758                              <1> ;;	IODELAY
  1759                              <1> ;;	;AND	AL,00001111B
  1760                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1761                              <1> ;;	;SIODELAY
  1762                              <1> ;;
  1763                              <1> ;;;----- DETERMINE COUNT
  1764                              <1> ;;	sub	eax, eax ; 08/02/2015
  1765                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  1766                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  1767                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  1768                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  1769                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  1770                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  1771                              <1> ;;	CALL	GET_PARM		; "
  1772                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1773                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  1774                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  1775                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1776                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  1777                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1778                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1779                              <1> ;;	IODELAY
  1780                              <1> ;;	MOV	AL, AH
  1781                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1782                              <1> ;;	;IODELAY
  1783                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1784                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  1785                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  1786                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1787                              <1> ;;	add	ecx, eax ; 08/02/2015
  1788                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1789                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1790                              <1> ;;	SIODELAY
  1791                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1792                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  1793                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  1794                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  1795                              <1> ;;	jz	short NO_BAD
  1796                              <1> ;;dma_bnd_err:
  1797                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1798                              <1> ;;NO_BAD:
  1799                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1800                              <1> 
  1801                              <1> ;-------------------------------------------------------------------------------
  1802                              <1> ; FMTDMA_SET
  1803                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  1804                              <1> ;
  1805                              <1> ; ON ENTRY:	NOTHING REQUIRED
  1806                              <1> ;
  1807                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1808                              <1> ;-------------------------------------------------------------------------------
  1809                              <1> 
  1810                              <1> FMTDMA_SET:
  1811                              <1> ;; 20/02/2015 modification	
  1812 000021C0 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1813 000021C3 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1814 000021C9 75EC                <1> 	jnz	short dma_bnd_err_stc
  1815                              <1> 	;
  1816 000021CB 6652                <1> 	push	dx			; *
  1817 000021CD B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1818 000021CF E8D0020000          <1> 	call	GET_PARM		; "
  1819 000021D4 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1820 000021D6 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1821 000021D8 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1822 000021DC 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1823 000021DE 6689C1              <1> 	mov	cx, ax
  1824 000021E1 665A                <1> 	pop	dx			; *
  1825 000021E3 6601CA              <1> 	add	dx, cx			; check for overflow
  1826 000021E6 72D0                <1> 	jc	short dma_bnd_err
  1827                              <1> 	;
  1828 000021E8 6629CA              <1> 	sub	dx, cx			; Restore start address
  1829                              <1> 	;
  1830 000021EB B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1831 000021ED FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1832 000021EE E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1833                              <1> 	IODELAY				; WAIT FOR I/O
  1833 000021F0 EB00                <2>  jmp short $+2
  1833 000021F2 EB00                <2>  jmp short $+2
  1834 000021F4 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1835 000021F6 89D0                <1> 	mov	eax, edx		; Buffer address
  1836 000021F8 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1837                              <1> 	IODELAY				; WAIT FOR I/O
  1837 000021FA EB00                <2>  jmp short $+2
  1837 000021FC EB00                <2>  jmp short $+2
  1838 000021FE 88E0                <1> 	MOV	AL,AH
  1839 00002200 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1840 00002202 C1E810              <1> 	shr	eax, 16
  1841                              <1> 	IODELAY				; I/O WAIT STATE
  1841 00002205 EB00                <2>  jmp short $+2
  1841 00002207 EB00                <2>  jmp short $+2
  1842 00002209 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1843                              <1> 	IODELAY
  1843 0000220B EB00                <2>  jmp short $+2
  1843 0000220D EB00                <2>  jmp short $+2
  1844 0000220F 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1845 00002212 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1846                              <1> 	IODELAY				; WAIT FOR I/O
  1846 00002214 EB00                <2>  jmp short $+2
  1846 00002216 EB00                <2>  jmp short $+2
  1847 00002218 88E0                <1> 	MOV	AL, AH
  1848 0000221A E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1849                              <1> 	IODELAY
  1849 0000221C EB00                <2>  jmp short $+2
  1849 0000221E EB00                <2>  jmp short $+2
  1850 00002220 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1851 00002221 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1852 00002223 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1853 00002225 C3                  <1> 	retn
  1854                              <1> 
  1855                              <1> ;; 08/02/2015 - Protected Mode Modification
  1856                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1857                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1858                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1859                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1860                              <1> ;;	IODELAY
  1861                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1862                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1863                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1864                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1865                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1866                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1867                              <1> ;;	;JNC	short J33A
  1868                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1869                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  1870                              <1> ;;;J33A:
  1871                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  1872                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1873                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1874                              <1> ;;	IODELAY
  1875                              <1> ;;	MOV	AL,AH
  1876                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1877                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  1878                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1879                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1880                              <1> ;;	IODELAY
  1881                              <1> ;;	;AND	AL,00001111B
  1882                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1883                              <1> ;;
  1884                              <1> ;;;----- DETERMINE COUNT
  1885                              <1> ;;	sub	eax, eax ; 08/02/2015
  1886                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1887                              <1> ;;	CALL	GET_PARM		; "
  1888                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  1889                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  1890                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1891                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1892                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  1893                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1894                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1895                              <1> ;;	IODELAY
  1896                              <1> ;;	MOV	AL, AH
  1897                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1898                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1899                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  1900                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  1901                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1902                              <1> ;;	add	ecx, eax ; 08/02/2015
  1903                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1904                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1905                              <1> ;;	SIODELAY
  1906                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1907                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  1908                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  1909                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  1910                              <1> ;;	jz	short FMTDMA_OK
  1911                              <1> ;;	stc	; 20/02/2015
  1912                              <1> ;;fmtdma_bnd_err:
  1913                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1914                              <1> ;;FMTDMA_OK:
  1915                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1916                              <1> 
  1917                              <1> ;-------------------------------------------------------------------------------
  1918                              <1> ; NEC_INIT	
  1919                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  1920                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  1921                              <1> ;
  1922                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  1923                              <1> ;
  1924                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1925                              <1> ;-------------------------------------------------------------------------------
  1926                              <1> NEC_INIT:
  1927 00002226 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1928 00002228 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1929                              <1> 
  1930                              <1> ;-----	DO THE SEEK OPERATION
  1931                              <1> 
  1932 0000222D 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1933 00002230 E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1934 00002235 6658                <1> 	POP	AX			; RECOVER COMMAND
  1935 00002237 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1936 00002239 BB[57220000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1937 0000223E 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1938                              <1> 
  1939                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1940                              <1> 
  1941 0000223F E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1942 00002244 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1943 00002247 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1944 00002249 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1945 0000224C 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1946 0000224F 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1947 00002251 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1948 00002256 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1949                              <1> ER_1:
  1950 00002257 C3                  <1> 	RETn
  1951                              <1> 
  1952                              <1> ;-------------------------------------------------------------------------------
  1953                              <1> ; RWV_COM
  1954                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  1955                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  1956                              <1> ;
  1957                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  1958                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1959                              <1> ;-------------------------------------------------------------------------------
  1960                              <1> RWV_COM:
  1961 00002258 B8[A3220000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1962 0000225D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1963 0000225E 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1964 00002261 E844030000          <1> 	CALL	NEC_OUTPUT
  1965 00002266 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  1966 00002269 E83C030000          <1> 	CALL	NEC_OUTPUT
  1967 0000226E 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  1968 00002271 E834030000          <1> 	CALL	NEC_OUTPUT
  1969 00002276 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  1970 00002278 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1971 0000227D E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1972 00002282 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  1973 00002284 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1974 00002289 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1975 0000228E 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  1976                              <1> _R15:
  1977 00002291 E814030000          <1> 	CALL	NEC_OUTPUT
  1978 00002296 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  1979 00002298 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  1980 0000229D E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1981 000022A2 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  1982                              <1> ER_2:
  1983 000022A3 C3                  <1> 	RETn
  1984                              <1> 
  1985                              <1> ;-------------------------------------------------------------------------------
  1986                              <1> ; NEC_TERM
  1987                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  1988                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  1989                              <1> ;
  1990                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1991                              <1> ;-------------------------------------------------------------------------------
  1992                              <1> NEC_TERM:
  1993                              <1> 
  1994                              <1> ;-----	LET THE OPERATION HAPPEN
  1995                              <1> 
  1996 000022A4 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  1997 000022A5 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  1998 000022AA 9C                  <1> 	PUSHF
  1999 000022AB E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  2000 000022B0 724B                <1> 	JC	short SET_END_POP
  2001 000022B2 9D                  <1> 	POPF
  2002 000022B3 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  2003                              <1> 
  2004                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  2005                              <1> 
  2006 000022B5 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  2007 000022B6 BE[13D30000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  2008 000022BB AC                  <1> 	lodsb				; GET ST0
  2009 000022BC 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  2010 000022BE 7433                <1> 	JZ	short SET_END
  2011 000022C0 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  2012 000022C2 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  2013                              <1> 
  2014                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  2015                              <1> 
  2016 000022C4 AC                  <1> 	lodsb				; GET ST1
  2017 000022C5 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  2018 000022C7 B404                <1> 	MOV	AH,RECORD_NOT_FND
  2019 000022C9 7222                <1> 	JC	short J19
  2020 000022CB C0E002              <1> 	SAL	AL,2
  2021 000022CE B410                <1> 	MOV	AH,BAD_CRC
  2022 000022D0 721B                <1> 	JC	short J19
  2023 000022D2 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  2024 000022D4 B408                <1> 	MOV	AH,BAD_DMA
  2025 000022D6 7215                <1> 	JC	short J19
  2026 000022D8 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2027 000022DB B404                <1> 	MOV	AH,RECORD_NOT_FND
  2028 000022DD 720E                <1> 	JC	short J19
  2029 000022DF D0E0                <1> 	SAL	AL,1
  2030 000022E1 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2031 000022E3 7208                <1> 	JC	short J19
  2032 000022E5 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2033 000022E7 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2034 000022E9 7202                <1> 	JC	short J19
  2035                              <1> 
  2036                              <1> ;----- 	NEC MUST HAVE FAILED
  2037                              <1> J18:
  2038 000022EB B420                <1> 	MOV	AH,BAD_NEC
  2039                              <1> J19:
  2040 000022ED 0825[12D30000]      <1> 	OR	[DSKETTE_STATUS], AH
  2041                              <1> SET_END:
  2042 000022F3 803D[12D30000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2043 000022FA F5                  <1> 	CMC
  2044 000022FB 5E                  <1> 	POP	eSI
  2045 000022FC C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2046                              <1> 
  2047                              <1> SET_END_POP:
  2048 000022FD 9D                  <1> 	POPF
  2049 000022FE EBF3                <1> 	JMP	SHORT SET_END
  2050                              <1> 
  2051                              <1> ;-------------------------------------------------------------------------------
  2052                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2053                              <1> ;-------------------------------------------------------------------------------
  2054                              <1> DSTATE:
  2055 00002300 803D[12D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2056 00002307 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2057 00002309 808F[1FD30000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2058 00002310 F687[1FD30000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2059 00002317 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2060 00002319 8A87[1FD30000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2061 0000231F 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2062 00002321 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2063 00002323 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  2064                              <1> 
  2065                              <1> ;----- 	CHECK IF IT IS 1.44M
  2066                              <1> 
  2067 00002325 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2068                              <1> 	;;20/02/2015
  2069                              <1> 	;;JC	short M_12		; CMOS BAD
  2070 0000232A 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2071 0000232C 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2072 0000232E 7410                <1> 	JE	short M_12		; YES
  2073                              <1> M_720:
  2074 00002330 80A7[1FD30000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2075 00002337 808F[1FD30000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2076 0000233E EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2077                              <1> M_12:	
  2078 00002340 808F[1FD30000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2079                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2080                              <1> SETBAC:
  2081 00002347 C3                  <1> 	RETn
  2082                              <1> 
  2083                              <1> ;-------------------------------------------------------------------------------
  2084                              <1> ; RETRY	
  2085                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  2086                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  2087                              <1> ;
  2088                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  2089                              <1> ;-------------------------------------------------------------------------------
  2090                              <1> RETRY:
  2091 00002348 803D[12D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2092 0000234F 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2093 00002351 803D[12D30000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2094 00002358 743C                <1> 	JZ	short NO_RETRY
  2095 0000235A 8AA7[1FD30000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2096 00002360 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2097 00002363 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2098 00002365 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2099 00002368 8A2D[1AD30000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2100 0000236E C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2101 00002371 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2102 00002374 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2103 00002376 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  2104                              <1> 
  2105                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  2106                              <1> ;	 00000000B (500) -> 10000000B	(250)
  2107                              <1> ;	 10000000B (250) -> 01000000B	(300)
  2108                              <1> ;	 01000000B (300) -> 00000000B	(500)
  2109                              <1> 
  2110 00002378 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2111 0000237B D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2112 0000237D 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2113 00002380 80A7[1FD30000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2114                              <1> 					; RATE, DBL STEP OFF
  2115 00002387 08A7[1FD30000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2116 0000238D C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2117 00002394 F9                  <1> 	STC				; SET CARRY FOR RETRY
  2118 00002395 C3                  <1> 	RETn				; RETRY RETURN
  2119                              <1> 
  2120                              <1> NO_RETRY:
  2121 00002396 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2122 00002397 C3                  <1> 	RETn				; NO RETRY RETURN
  2123                              <1> 
  2124                              <1> ;-------------------------------------------------------------------------------
  2125                              <1> ; NUM_TRANS
  2126                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  2127                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  2128                              <1> ;
  2129                              <1> ; ON ENTRY:	[BP+1] = TRACK
  2130                              <1> ;		SI-HI  = HEAD
  2131                              <1> ;		[BP]   = START SECTOR
  2132                              <1> ;
  2133                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  2134                              <1> ;-------------------------------------------------------------------------------
  2135                              <1> NUM_TRANS:
  2136 00002398 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2137 0000239A 803D[12D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2138 000023A1 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2139 000023A3 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2140 000023A5 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2141 000023AA 8A1D[18D30000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2142 000023B0 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2143 000023B3 3A2D[17D30000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2144 000023B9 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2145 000023BB 8A2D[16D30000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2146 000023C1 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2147 000023C4 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2148 000023C6 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2149                              <1> DIF_HD:
  2150 000023C8 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2151                              <1> SAME_TRK:
  2152 000023CA 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2153 000023CD 88D8                <1> 	MOV	AL,BL			; TO AL
  2154                              <1> NT_OUT:
  2155 000023CF C3                  <1> 	RETn
  2156                              <1> 
  2157                              <1> ;-------------------------------------------------------------------------------
  2158                              <1> ; SETUP_END
  2159                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2160                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2161                              <1> ;
  2162                              <1> ; ON EXIT:
  2163                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2164                              <1> ;-------------------------------------------------------------------------------
  2165                              <1> SETUP_END:
  2166 000023D0 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2167 000023D2 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2168 000023D4 E8CB000000          <1> 	CALL	GET_PARM
  2169 000023D9 8825[11D30000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2170 000023DF 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2171 000023E1 8A25[12D30000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2172 000023E7 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2173 000023E9 7402                <1> 	JZ	short NUN_ERR		; NO ERROR
  2174 000023EB 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2175                              <1> NUN_ERR: 
  2176 000023ED 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2177 000023F0 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2178 000023F1 C3                  <1> 	RETn
  2179                              <1> 
  2180                              <1> ;-------------------------------------------------------------------------------
  2181                              <1> ; SETUP_DBL
  2182                              <1> ;	CHECK DOUBLE STEP.
  2183                              <1> ;
  2184                              <1> ; ON ENTRY :	DI = DRIVE
  2185                              <1> ;
  2186                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  2187                              <1> ;-------------------------------------------------------------------------------
  2188                              <1> SETUP_DBL:
  2189 000023F2 8AA7[1FD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2190 000023F8 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2191 000023FB 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  2192                              <1> 
  2193                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  2194                              <1> 
  2195 000023FD C605[0FD30000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2196 00002404 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2197 00002409 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2198 0000240B E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2199 00002410 E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2200 00002415 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  2201                              <1> 
  2202                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  2203                              <1> 
  2204 00002417 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2205 0000241B F687[1FD30000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2206 00002422 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2207 00002424 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  2208                              <1> 
  2209                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  2210                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  2211                              <1> ;	THEN SET DOUBLE STEP ON.
  2212                              <1> 
  2213                              <1> CNT_OK:
  2214 00002426 C605[11D30000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2215 0000242D 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2216 0000242F C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2217 00002436 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2218 00002439 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2219 0000243B C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2220 0000243E 6650                <1> 	PUSH	AX			; SAVE HEAD
  2221 00002440 E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2222 00002445 6658                <1> 	POP	AX			; RESTORE HEAD
  2223 00002447 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2224 0000244A E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2225 0000244F 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2226 00002450 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2227 00002455 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2228 00002456 6659                <1> 	POP	CX			; RESTORE COUNT
  2229 00002458 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2230 0000245A FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2231 0000245C 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2232 0000245E 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  2233                              <1> 
  2234                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  2235                              <1> 
  2236                              <1> SD_ERR:	
  2237 00002460 F9                  <1> 	STC				; SET CARRY FOR ERROR
  2238 00002461 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2239                              <1> 
  2240                              <1> DO_CHK:
  2241 00002462 8A0D[16D30000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2242 00002468 888F[23D30000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2243 0000246E D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2244 00002470 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2245 00002472 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2246 00002474 808F[1FD30000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2247                              <1> NO_DBL:
  2248 0000247B F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2249 0000247C C3                  <1> 	RETn
  2250                              <1> 
  2251                              <1> ;-------------------------------------------------------------------------------
  2252                              <1> ; READ_ID
  2253                              <1> ;	READ ID FUNCTION.
  2254                              <1> ;
  2255                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  2256                              <1> ;
  2257                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  2258                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2259                              <1> ;-------------------------------------------------------------------------------
  2260                              <1> READ_ID:
  2261 0000247D B8[9A240000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2262 00002482 50                  <1> 	PUSH	eAX
  2263 00002483 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2264 00002485 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2265 0000248A 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2266 0000248D 88C4                <1> 	MOV	AH,AL
  2267 0000248F E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2268 00002494 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2269 00002499 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2270                              <1> ER_3:
  2271 0000249A C3                  <1> 	RETn
  2272                              <1> 
  2273                              <1> ;-------------------------------------------------------------------------------
  2274                              <1> ; CMOS_TYPE
  2275                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  2276                              <1> ;
  2277                              <1> ; ON ENTRY:	DI = DRIVE #
  2278                              <1> ;
  2279                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  2280                              <1> ;-------------------------------------------------------------------------------
  2281                              <1> 
  2282                              <1> CMOS_TYPE: ; 11/12/2014
  2283 0000249B 8A87[8ECD0000]      <1> mov	al, [eDI+fd0_type]
  2284 000024A1 20C0                <1> and 	al, al ; 18/12/2014
  2285 000024A3 C3                  <1> retn
  2286                              <1> 
  2287                              <1> ;CMOS_TYPE:
  2288                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  2289                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  2290                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  2291                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  2292                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  2293                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  2294                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  2295                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  2296                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  2297                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  2298                              <1> ;TB:
  2299                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  2300                              <1> ;BAD_CM:
  2301                              <1> ;	RETn				; CY, STATUS OF READ
  2302                              <1> 
  2303                              <1> ;-------------------------------------------------------------------------------
  2304                              <1> ; GET_PARM
  2305                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  2306                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  2307                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  2308                              <1> ;	THE PARAMETER IN DL.
  2309                              <1> ;
  2310                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  2311                              <1> ;
  2312                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  2313                              <1> ;		AL,DH DESTROYED
  2314                              <1> ;-------------------------------------------------------------------------------
  2315                              <1> GET_PARM:
  2316                              <1> 	;PUSH	DS
  2317 000024A4 56                  <1> 	PUSH	eSI
  2318                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  2319                              <1>     	;MOV	DS,AX
  2320                              <1> 	;;mov	ax, cs
  2321                              <1> 	;;mov	ds, ax
  2322                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  2323 000024A5 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2324                              <1> 	;SUB	BH,BH			; BX = INDEX
  2325 000024A7 81E3FF000000        <1> 	and	ebx, 0FFh
  2326                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2327                              <1> 	;
  2328                              <1> 	; 17/12/2014
  2329 000024AD 66A1[81CD0000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2330 000024B3 38E0                <1> 	cmp	al, ah
  2331 000024B5 7425                <1> 	je	short gpndc
  2332 000024B7 A2[82CD0000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2333 000024BC 53                  <1> 	push	ebx ; 08/02/2015
  2334 000024BD 88C3                <1> 	mov	bl, al 
  2335                              <1> 	; 11/12/2014
  2336 000024BF 8A83[8ECD0000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2337                              <1> 	; 18/12/2014
  2338 000024C5 20C0                <1> 	and	al, al
  2339 000024C7 7507                <1> 	jnz	short gpdtc
  2340 000024C9 BB[6BCD0000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2341 000024CE EB05                <1>         jmp     short gpdpu
  2342                              <1> gpdtc:	
  2343 000024D0 E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2344                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2345                              <1> gpdpu:
  2346 000024D5 891D[08CD0000]      <1> 	mov	[DISK_POINTER], ebx
  2347 000024DB 5B                  <1> 	pop	ebx
  2348                              <1> gpndc:
  2349 000024DC 8B35[08CD0000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2350 000024E2 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2351 000024E5 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2352 000024E7 5E                  <1> 	POP	eSI
  2353                              <1> 	;POP	DS
  2354 000024E8 C3                  <1> 	RETn
  2355                              <1> 
  2356                              <1> ;-------------------------------------------------------------------------------
  2357                              <1> ; MOTOR_ON
  2358                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  2359                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  2360                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  2361                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  2362                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  2363                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  2364                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  2365                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  2366                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  2367                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  2368                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  2369                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  2370                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  2371                              <1> ;
  2372                              <1> ; ON ENTRY:	DI = DRIVE #
  2373                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  2374                              <1> ;-------------------------------------------------------------------------------
  2375                              <1> MOTOR_ON:
  2376 000024E9 53                  <1> 	PUSH	eBX			; SAVE REG.
  2377 000024EA E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2378 000024EF 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2379 000024F1 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2380 000024F6 E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  2381                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  2382                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  2383                              <1> M_WAIT:
  2384 000024FB B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2385 000024FD E8A2FFFFFF          <1> 	CALL	GET_PARM
  2386                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  2387                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  2388                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  2389 00002502 80FC08              <1> 	cmp	ah, 8
  2390                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2391 00002505 7702                <1> 	ja	short J13
  2392                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2393 00002507 B408                <1> 	mov	ah, 8
  2394                              <1> 
  2395                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  2396                              <1> GP2:	
  2397                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  2398                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  2399 00002509 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2400 0000250E E805F3FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2401                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2402 00002513 FECC                <1> 	dec	ah
  2403 00002515 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2404                              <1> MOT_IS_ON:
  2405 00002517 5B                  <1> 	POP	eBX			; RESTORE REG.
  2406 00002518 C3                  <1> 	RETn
  2407                              <1> 
  2408                              <1> ;-------------------------------------------------------------------------------
  2409                              <1> ; TURN_ON
  2410                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  2411                              <1> ;
  2412                              <1> ; ON ENTRY:	DI = DRIVE #
  2413                              <1> ;
  2414                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  2415                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  2416                              <1> ;		AX,BX,CX,DX DESTROYED
  2417                              <1> ;-------------------------------------------------------------------------------
  2418                              <1> TURN_ON:
  2419 00002519 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2420 0000251B 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2421 0000251D C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2422 00002520 FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2423 00002521 C605[11D30000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2424 00002528 A0[10D30000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2425 0000252D 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2426 0000252F B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2427 00002531 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  2428                              <1> 
  2429                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  2430                              <1> ;  BL = DRIVE SELECT DESIRED
  2431                              <1> ;  AH = MOTOR ON MASK DESIRED
  2432                              <1> 
  2433 00002533 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2434 00002535 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2435 00002537 8425[10D30000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2436 0000253D 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2437                              <1> 
  2438                              <1> TURN_IT_ON:
  2439 0000253F 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2440 00002541 8A3D[10D30000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2441 00002547 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2442 0000254A 8025[10D30000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2443 00002551 0825[10D30000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2444 00002557 A0[10D30000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2445 0000255C 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2446 0000255E 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2447 00002561 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2448 00002562 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2449 00002564 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2450 00002567 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2451 00002569 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2452 0000256D EE                  <1> 	OUT	DX,AL
  2453 0000256E 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2454                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2455 00002570 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2456 00002572 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2457 00002573 C3                  <1> 	RETn
  2458                              <1> 
  2459                              <1> NO_MOT_WAIT:
  2460 00002574 FB                  <1> 	sti
  2461                              <1> no_mot_w1: ; 27/02/2015
  2462 00002575 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2463                              <1> 	;STI				; INTERRUPTS BACK ON
  2464 00002576 C3                  <1> 	RETn
  2465                              <1> 
  2466                              <1> ;-------------------------------------------------------------------------------
  2467                              <1> ; HD_WAIT
  2468                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  2469                              <1> ;
  2470                              <1> ; ON ENTRY:	DI = DRIVE #
  2471                              <1> ;
  2472                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  2473                              <1> ;-------------------------------------------------------------------------------
  2474                              <1> HD_WAIT:
  2475 00002577 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2476 00002579 E826FFFFFF          <1> 	CALL	GET_PARM
  2477 0000257E 08E4                <1> 	or	ah, ah	; 17/12/2014
  2478 00002580 7519                <1> 	jnz	short DO_WAT
  2479 00002582 F605[10D30000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  2480                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  2481                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  2482                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  2483 00002589 741E                <1> 	jz	short HW_DONE
  2484 0000258B B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2485 0000258D 8A87[1FD30000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2486 00002593 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2487 00002595 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2488 00002597 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2489                              <1> ;GP3:
  2490 00002599 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  2491                              <1> ;	JMP	SHORT DO_WAT
  2492                              <1> 
  2493                              <1> ;ISNT_WRITE:
  2494                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  2495                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  2496                              <1> 
  2497                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  2498                              <1> DO_WAT:
  2499                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  2500                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  2501                              <1> J29:					; 	1 MILLISECOND LOOP
  2502                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  2503 0000259B B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2504 000025A0 E873F2FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2505                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2506 000025A5 FECC                <1> 	dec	ah
  2507 000025A7 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2508                              <1> HW_DONE:
  2509 000025A9 C3                  <1> 	RETn
  2510                              <1> 
  2511                              <1> ;-------------------------------------------------------------------------------
  2512                              <1> ; NEC_OUTPUT
  2513                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  2514                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  2515                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  2516                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  2517                              <1> ; 
  2518                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  2519                              <1> ;
  2520                              <1> ; ON EXIT:	CY = 0  SUCCESS
  2521                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  2522                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  2523                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  2524                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  2525                              <1> ;		AX,CX,DX DESTROYED
  2526                              <1> ;-------------------------------------------------------------------------------
  2527                              <1> 
  2528                              <1> ; 09/12/2014 [Erdogan Tan] 
  2529                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  2530                              <1> ; Diskette Drive Controller Status Register (3F4h)
  2531                              <1> ;	This read only register facilitates the transfer of data between
  2532                              <1> ;	the system microprocessor and the controller.
  2533                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  2534                              <1> ;	  with the system micrprocessor.
  2535                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  2536                              <1> ;	  the transfer is to the controller.
  2537                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  2538                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  2539                              <1> ; Bit 3 - Reserved.
  2540                              <1> ; Bit 2 - Reserved.
  2541                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2542                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2543                              <1> 
  2544                              <1> ; Data Register (3F5h)
  2545                              <1> ; This read/write register passes data, commands and parameters, and provides
  2546                              <1> ; diskette status information.
  2547                              <1>   		
  2548                              <1> NEC_OUTPUT:
  2549                              <1> 	;PUSH	BX			; SAVE REG.
  2550 000025AA 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2551                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  2552                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  2553                              <1> 	; 16/12/2014
  2554                              <1> 	; waiting for (max.) 0.5 seconds
  2555                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  2556                              <1> 	;
  2557                              <1> 	; 17/12/2014
  2558                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  2559                              <1> 	;
  2560                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  2561                              <1> 	;		go on.
  2562                              <1> 	;INPUT:
  2563                              <1> 	;	AH=Mask for isolation bits.
  2564                              <1> 	;	AL=pattern to look for.
  2565                              <1> 	;	DX=Port to test for
  2566                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2567                              <1> 	;	     (normally 30 microseconds per period.)
  2568                              <1> 	;
  2569                              <1> 	;WFP_SHORT:  
  2570                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  2571                              <1> 	;
  2572                              <1> 
  2573                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  2574                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  2575 000025AE B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  2576                              <1> ;
  2577                              <1> ;WFPS_OUTER_LP:
  2578                              <1> ;	;
  2579                              <1> ;WFPS_CHECK_PORT:
  2580                              <1> J23:
  2581 000025B3 EC                  <1> 	IN	AL,DX			; GET STATUS
  2582 000025B4 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2583 000025B6 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2584 000025B8 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2585                              <1> WFPS_HI:
  2586 000025BA E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2587 000025BC A810                <1> 	TEST	AL,010H			; transition on memory
  2588 000025BE 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2589                              <1> WFPS_LO:
  2590 000025C0 E461                <1> 	IN	AL, PORT_B		; SYS1
  2591 000025C2 A810                <1> 	TEST	AL,010H
  2592 000025C4 74FA                <1> 	JZ	SHORT WFPS_LO
  2593                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2594 000025C6 E2EB                <1> 	loop	J23	; 27/02/2015
  2595                              <1> ;	;
  2596                              <1> ;	dec	bl
  2597                              <1> ;	jnz	short WFPS_OUTER_LP
  2598                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  2599                              <1> ;J23:
  2600                              <1> ;	IN	AL,DX			; GET STATUS
  2601                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2602                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2603                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  2604                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  2605                              <1> 	;DEC	BL			; DECREMENT COUNTER
  2606                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  2607                              <1>    
  2608                              <1> 	;;27/02/2015
  2609                              <1> 	;16/12/2014
  2610                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  2611                              <1> 	;;jb	short J23
  2612                              <1> 
  2613                              <1> ;WFPS_TIMEOUT:
  2614                              <1> 
  2615                              <1> ;-----	FALL THRU TO ERROR RETURN
  2616                              <1> 
  2617 000025C8 800D[12D30000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2618                              <1> 	;POP	BX			; RESTORE REG.
  2619 000025CF 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2620 000025D0 F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2621 000025D1 C3                  <1> 	RETn
  2622                              <1> 
  2623                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2624                              <1> 
  2625                              <1> J27:	
  2626 000025D2 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2627 000025D4 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2628 000025D6 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2629                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2630                              <1> 	; 27/02/2015
  2631 000025D7 9C                  <1> 	PUSHF				; SAVE FLAGS
  2632 000025D8 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2633 000025DD E836F2FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2634 000025E2 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2635                              <1> 	;POP	BX			; RESTORE REG
  2636 000025E3 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  2637                              <1> 
  2638                              <1> ;-------------------------------------------------------------------------------
  2639                              <1> ; SEEK
  2640                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  2641                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  2642                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  2643                              <1> ;
  2644                              <1> ; ON ENTRY:	DI = DRIVE #
  2645                              <1> ;		CH = TRACK #
  2646                              <1> ;
  2647                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2648                              <1> ;		AX,BX,CX DX DESTROYED
  2649                              <1> ;-------------------------------------------------------------------------------
  2650                              <1> SEEK:
  2651 000025E4 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2652 000025E6 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2653 000025E8 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2654 000025EA D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2655 000025EC 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2656 000025EE 8405[0FD30000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2657 000025F4 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2658                              <1> 
  2659 000025F6 0805[0FD30000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2660 000025FC E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2661 00002601 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2662                              <1> 
  2663                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2664                              <1> 
  2665 00002603 C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2666 0000260A E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2667 0000260F 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2668                              <1> 
  2669                              <1> AFT_RECAL:
  2670 00002611 C687[23D30000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2671 00002618 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2672 0000261A 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  2673                              <1> 
  2674                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  2675                              <1> 
  2676 0000261C F687[1FD30000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2677 00002623 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2678 00002625 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2679                              <1> 
  2680 00002627 3AAF[23D30000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2681 0000262D 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2682                              <1> 
  2683 0000262F BA[62260000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2684 00002634 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2685 00002635 88AF[23D30000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2686 0000263B B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2687 0000263D E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2688 00002642 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2689 00002644 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2690 00002646 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2691 0000264B 8AA7[23D30000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2692 00002651 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2693 00002656 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  2694                              <1> 
  2695                              <1> ;-----	WAIT FOR HEAD SETTLE
  2696                              <1> 
  2697                              <1> DO_WAIT:
  2698 0000265B 9C                  <1> 	PUSHF				; SAVE STATUS
  2699 0000265C E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2700 00002661 9D                  <1> 	POPF				; RESTORE STATUS
  2701                              <1> RB:
  2702                              <1> NEC_ERR:
  2703                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  2704                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  2705 00002662 C3                  <1> 	RETn				; RETURN TO CALLER
  2706                              <1> 
  2707                              <1> ;-------------------------------------------------------------------------------
  2708                              <1> ; RECAL
  2709                              <1> ;	RECALIBRATE DRIVE
  2710                              <1> ;
  2711                              <1> ; ON ENTRY:	DI = DRIVE #
  2712                              <1> ;
  2713                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  2714                              <1> ;-------------------------------------------------------------------------------
  2715                              <1> RECAL:
  2716 00002663 6651                <1> 	PUSH	CX
  2717 00002665 B8[81260000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2718 0000266A 50                  <1> 	PUSH	eAX
  2719 0000266B B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2720 0000266D E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2721 00002672 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2722 00002674 88DC                <1> 	MOV	AH,BL
  2723 00002676 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2724 0000267B E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2725 00002680 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2726                              <1> RC_BACK:
  2727 00002681 6659                <1> 	POP	CX
  2728 00002683 C3                  <1> 	RETn
  2729                              <1> 
  2730                              <1> ;-------------------------------------------------------------------------------
  2731                              <1> ; CHK_STAT_2
  2732                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  2733                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  2734                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  2735                              <1> ;
  2736                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2737                              <1> ;-------------------------------------------------------------------------------
  2738                              <1> CHK_STAT_2:
  2739 00002684 B8[AC260000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2740 00002689 50                  <1> 	PUSH	eAX
  2741 0000268A E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2742 0000268F 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2743 00002691 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2744 00002693 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2745 00002698 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2746 0000269D 720C                <1> 	JC	short J34
  2747 0000269F A0[13D30000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2748 000026A4 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2749 000026A6 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2750 000026A8 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2751 000026AA F8                  <1> 	CLC				; GOOD RETURN
  2752                              <1> J34:
  2753 000026AB 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2754                              <1> CS_BACK:
  2755 000026AC C3                  <1> 	RETn
  2756                              <1> J35:
  2757 000026AD 800D[12D30000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2758 000026B4 F9                  <1> 	STC				; ERROR RETURN CODE
  2759 000026B5 EBF4                <1> 	JMP	SHORT J34
  2760                              <1> 
  2761                              <1> ;-------------------------------------------------------------------------------
  2762                              <1> ; WAIT_INT
  2763                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  2764                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  2765                              <1> ;	IF THE DRIVE IS NOT READY.
  2766                              <1> ;
  2767                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2768                              <1> ;-------------------------------------------------------------------------------
  2769                              <1> 
  2770                              <1> ; 17/12/2014
  2771                              <1> ; 2.5 seconds waiting !
  2772                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  2773                              <1> ; amount of time to wait for completion interrupt from NEC.
  2774                              <1> 
  2775                              <1> 
  2776                              <1> WAIT_INT:
  2777 000026B7 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2778 000026B8 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  2779                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  2780                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  2781                              <1> 
  2782                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  2783                              <1> 	;
  2784                              <1> 	;WAIT_FOR_MEM:	
  2785                              <1> 	;	Waits for a bit at a specified memory location pointed
  2786                              <1> 	;	to by ES:[DI] to become set.
  2787                              <1> 	;INPUT:
  2788                              <1> 	;	AH=Mask to test with.
  2789                              <1> 	;	ES:[DI] = memory location to watch.
  2790                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2791                              <1> 	;	     (normally 30 microseconds per period.)
  2792                              <1> 
  2793                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  2794                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  2795                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  2796                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  2797                              <1> 	; 27/02/2015
  2798 000026B9 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2799                              <1> WFMS_CHECK_MEM:
  2800 000026BE F605[0FD30000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2801 000026C5 7516                <1>         jnz     short J37
  2802                              <1> WFMS_HI:
  2803 000026C7 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2804 000026C9 A810                <1> 	TEST	AL,010H			; transition on memory
  2805 000026CB 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2806                              <1> WFMS_LO:
  2807 000026CD E461                <1> 	IN	AL,PORT_B		;SYS1
  2808 000026CF A810                <1> 	TEST	AL,010H
  2809 000026D1 74FA                <1> 	JZ	SHORT WFMS_LO
  2810 000026D3 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  2811                              <1> ;WFMS_OUTER_LP:
  2812                              <1> ;;	or	bl, bl			; check outer counter
  2813                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  2814                              <1> ;	dec	bl
  2815                              <1> ;	jz	short J36A	
  2816                              <1> ;	jmp	short WFMS_CHECK_MEM
  2817                              <1> 
  2818                              <1> 	;17/12/2014
  2819                              <1> 	;16/12/2014
  2820                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  2821                              <1> ;J36:
  2822                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2823                              <1> ;	JNZ	short J37
  2824                              <1> 	;16/12/2014
  2825                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  2826                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  2827                              <1> 	;JNZ	short J36
  2828                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  2829                              <1> ;	jb	short J36
  2830                              <1> 
  2831                              <1> ;WFMS_TIMEOUT:
  2832                              <1> ;J36A:
  2833 000026D5 800D[12D30000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2834 000026DC F9                  <1> 	STC				; ERROR RETURN
  2835                              <1> J37:
  2836 000026DD 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2837 000026DE 8025[0FD30000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2838 000026E5 9D                  <1> 	POPF				; RECOVER CARRY
  2839 000026E6 C3                  <1> 	RETn				; GOOD RETURN CODE
  2840                              <1> 
  2841                              <1> ;-------------------------------------------------------------------------------
  2842                              <1> ; RESULTS
  2843                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  2844                              <1> ;	FOLLOWING AN INTERRUPT.
  2845                              <1> ;
  2846                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2847                              <1> ;		AX,BX,CX,DX DESTROYED
  2848                              <1> ;-------------------------------------------------------------------------------
  2849                              <1> RESULTS:
  2850 000026E7 57                  <1> 	PUSH	eDI
  2851 000026E8 BF[13D30000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2852 000026ED B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2853 000026EF 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2854                              <1> 
  2855                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  2856                              <1> 
  2857                              <1> _R10: 
  2858                              <1> 	; 16/12/2014
  2859                              <1> 	; wait for (max) 0.5 seconds
  2860                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  2861                              <1> 	;XOR	CX,CX			; COUNTER
  2862                              <1> 
  2863                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  2864                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2865                              <1> 	; 27/02/2015
  2866 000026F3 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  2867                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  2868                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  2869                              <1> 
  2870                              <1> WFPSR_OUTER_LP:
  2871                              <1> 	;
  2872                              <1> WFPSR_CHECK_PORT:
  2873                              <1> J39:					; WAIT FOR MASTER
  2874 000026F8 EC                  <1> 	IN	AL,DX			; GET STATUS
  2875 000026F9 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2876 000026FB 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2877 000026FD 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2878                              <1> WFPSR_HI:
  2879 000026FF E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2880 00002701 A810                <1> 	TEST	AL,010H			; transition on memory
  2881 00002703 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2882                              <1> WFPSR_LO:
  2883 00002705 E461                <1> 	IN	AL, PORT_B		; SYS1
  2884 00002707 A810                <1> 	TEST	AL,010H
  2885 00002709 74FA                <1> 	JZ	SHORT WFPSR_LO
  2886 0000270B E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  2887                              <1> 	;; 27/02/2015
  2888                              <1> 	;;dec	bh
  2889                              <1> 	;;jnz	short WFPSR_OUTER_LP
  2890                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  2891                              <1> 
  2892                              <1> 	;;mov	byte [wait_count], 0
  2893                              <1> ;J39:					; WAIT FOR MASTER
  2894                              <1> ;	IN	AL,DX			; GET STATUS
  2895                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2896                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2897                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  2898                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  2899                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  2900                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  2901                              <1> 	;
  2902                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  2903                              <1> 	;;jb	short J39	
  2904                              <1> 
  2905                              <1> ;WFPSR_TIMEOUT:
  2906 0000270D 800D[12D30000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2907 00002714 F9                  <1> 	STC				; SET ERROR RETURN
  2908 00002715 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2909                              <1> 
  2910                              <1> ;-----	READ IN THE STATUS
  2911                              <1> 
  2912                              <1> J42:
  2913 00002717 EB00                <1> 	JMP	$+2			; I/O DELAY
  2914 00002719 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2915 0000271B EC                  <1> 	IN	AL,DX			; GET THE DATA
  2916                              <1> 	; 16/12/2014
  2917                              <1> 	NEWIODELAY
  2917 0000271C E6EB                <2>  out 0ebh,al
  2918 0000271E 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2919 00002720 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  2920                              <1> 	; 16/12/2014
  2921                              <1> ;	push	cx
  2922                              <1> ;	mov	cx, 30
  2923                              <1> ;wdw2:
  2924                              <1> ;	NEWIODELAY
  2925                              <1> ;	loop	wdw2
  2926                              <1> ;	pop	cx
  2927                              <1> 
  2928 00002721 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2929 00002726 E8EDF0FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2930 0000272B 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2931 0000272D EC                  <1> 	IN	AL,DX			; GET STATUS
  2932                              <1> 	; 16/12/2014
  2933                              <1> 	NEWIODELAY
  2933 0000272E E6EB                <2>  out 0ebh,al
  2934                              <1> 	;
  2935 00002730 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2936 00002732 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2937                              <1> 
  2938 00002734 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2939 00002736 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2940 00002738 800D[12D30000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2941 0000273F F9                  <1> 	STC				; SET ERROR FLAG
  2942                              <1> 
  2943                              <1> ;-----	RESULT OPERATION IS DONE
  2944                              <1> POPRES:
  2945 00002740 5F                  <1> 	POP	eDI
  2946 00002741 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  2947                              <1> 
  2948                              <1> ;-------------------------------------------------------------------------------
  2949                              <1> ; READ_DSKCHNG
  2950                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  2951                              <1> ;
  2952                              <1> ; ON ENTRY:	DI = DRIVE #
  2953                              <1> ;
  2954                              <1> ; ON EXIT:	DI = DRIVE #
  2955                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  2956                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  2957                              <1> ;		AX,CX,DX DESTROYED
  2958                              <1> ;-------------------------------------------------------------------------------
  2959                              <1> READ_DSKCHNG:
  2960 00002742 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2961 00002747 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2962 0000274B EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2963 0000274C A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2964 0000274E C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  2965                              <1> 
  2966                              <1> ;-------------------------------------------------------------------------------
  2967                              <1> ; DRIVE_DET
  2968                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  2969                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  2970                              <1> ; ON ENTRY:	DI = DRIVE #
  2971                              <1> ;-------------------------------------------------------------------------------
  2972                              <1> DRIVE_DET:
  2973 0000274F E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  2974 00002754 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2975 00002759 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  2976 0000275B B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  2977 0000275D E882FEFFFF          <1> 	CALL	SEEK
  2978 00002762 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  2979 00002764 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  2980                              <1> SK_GIN:
  2981 00002766 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  2982 00002768 6651                <1> 	PUSH	CX			; SAVE TRACK
  2983 0000276A E875FEFFFF          <1> 	CALL	SEEK
  2984 0000276F 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  2985 00002771 B8[AD270000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  2986 00002776 50                  <1> 	PUSH	eAX
  2987 00002777 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  2988 00002779 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2989 0000277E 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  2990 00002781 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  2991 00002783 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2992 00002788 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  2993 0000278D 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2994 0000278E 6659                <1> 	POP	CX			; RESTORE TRACK
  2995 00002790 F605[13D30000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  2996 00002797 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  2997 00002799 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  2998 0000279B 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  2999                              <1> 
  3000                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  3001                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  3002                              <1> 
  3003 0000279D 808F[1FD30000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  3004 000027A4 C3                  <1> 	RETn				; ALL INFORMATION SET
  3005                              <1> IS_80:
  3006 000027A5 808F[1FD30000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  3007                              <1> DD_BAC:
  3008 000027AC C3                  <1> 	RETn
  3009                              <1> POP_BAC:
  3010 000027AD 6659                <1> 	POP	CX			; THROW AWAY
  3011 000027AF C3                  <1> 	RETn
  3012                              <1> 
  3013                              <1> fdc_int:  
  3014                              <1> 	  ; 30/07/2015	
  3015                              <1> 	  ; 16/02/2015
  3016                              <1> ;int_0Eh: ; 11/12/2014
  3017                              <1> 
  3018                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  3019                              <1> ; DISK_INT
  3020                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  3021                              <1> ;
  3022                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  3023                              <1> ;-------------------------------------------------------------------------------
  3024                              <1> DISK_INT_1:
  3025                              <1> 
  3026 000027B0 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3027 000027B2 1E                  <1> 	push	ds
  3028 000027B3 66B81000            <1> 	mov	ax, KDATA
  3029 000027B7 8ED8                <1> 	mov 	ds, ax
  3030 000027B9 800D[0FD30000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3031 000027C0 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3032 000027C2 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3033 000027C4 1F                  <1> 	pop	ds
  3034 000027C5 6658                <1> 	POP	AX			; RECOVER REGISTER
  3035 000027C7 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  3036                              <1> 
  3037                              <1> ;-------------------------------------------------------------------------------
  3038                              <1> ; DSKETTE_SETUP
  3039                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  3040                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  3041                              <1> ;-------------------------------------------------------------------------------
  3042                              <1> 
  3043                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3044                              <1> 
  3045                              <1> DSKETTE_SETUP:
  3046                              <1> 	;PUSH	AX			; SAVE REGISTERS
  3047                              <1> 	;PUSH	BX
  3048                              <1> 	;PUSH	CX
  3049 000027C8 52                  <1> 	PUSH	eDX
  3050                              <1> 	;PUSH	DI
  3051                              <1> 	;;PUSH	DS
  3052                              <1> 	; 14/12/2014
  3053                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  3054                              <1> 	;mov	[DISK_POINTER+2], cs
  3055                              <1> 	;
  3056                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  3057 000027C9 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3058 000027CB 66C705[1FD30000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3058 000027D3 00                  <1>
  3059 000027D4 8025[1AD30000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3060 000027DB 800D[1AD30000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3061 000027E2 C605[0FD30000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3062 000027E9 C605[11D30000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3063 000027F0 C605[10D30000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3064 000027F7 C605[12D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3065                              <1> 	;
  3066                              <1> 	; 28/02/2015
  3067                              <1> 	;mov	word [cfd], 100h 
  3068 000027FE E84DF2FFFF          <1> 	call	DSK_RESET
  3069 00002803 5A                  <1> 	pop	edx
  3070 00002804 F8                  <1> 	clc	; 29/05/2016
  3071 00002805 C3                  <1> 	retn
  3072                              <1> 
  3073                              <1> ;SUP0:
  3074                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  3075                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3076                              <1> ;	; 02/01/2015
  3077                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  3078                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  3079                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  3080                              <1> ;       cmp     byte [fd1_type], 0	
  3081                              <1> ;	jna	short sup1
  3082                              <1> ;	or	di, di
  3083                              <1> ;	jnz	short sup1
  3084                              <1> ;	inc	di
  3085                              <1> ;       jmp     short SUP0
  3086                              <1> ;sup1:
  3087                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  3088                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  3089                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  3090                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  3091                              <1> ;	;POP	DI
  3092                              <1> ;	POP	eDX
  3093                              <1> ;	;POP	CX
  3094                              <1> ;	;POP	BX
  3095                              <1> ;	;POP	AX
  3096                              <1> ;	RETn
  3097                              <1> 
  3098                              <1> ;//////////////////////////////////////////////////////
  3099                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3100                              <1> ;
  3101                              <1> 
  3102                              <1> int13h: ; 21/02/2015
  3103 00002806 9C                  <1> 	pushfd
  3104 00002807 0E                  <1> 	push 	cs
  3105 00002808 E82B010000          <1> 	call 	DISK_IO
  3106 0000280D C3                  <1> 	retn
  3107                              <1> 
  3108                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  3109                              <1> ;/////////////////////////////////////////////////////////////////////
  3110                              <1> 
  3111                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  3112                              <1> ; 18/02/2016
  3113                              <1> ; 17/02/2016
  3114                              <1> ; 23/02/2015
  3115                              <1> ; 21/02/2015 (unix386.s)
  3116                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  3117                              <1> ;
  3118                              <1> ; Original Source Code:
  3119                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  3120                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  3121                              <1> ;
  3122                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  3123                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  3124                              <1> ;
  3125                              <1> 
  3126                              <1> 
  3127                              <1> ;The wait for controller to be not busy is 10 seconds.
  3128                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3129                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  3130                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  3131                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  3132                              <1> 
  3133                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  3134                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3135                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  3136                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  3137                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  3138                              <1> 
  3139                              <1> ;The wait for Data request on read and write longs is
  3140                              <1> ;2000 us. (?)
  3141                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  3142                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  3143                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  3144                              <1> 
  3145                              <1> ; Port 61h (PORT_B)
  3146                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  3147                              <1> 
  3148                              <1> ; 23/12/2014
  3149                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  3150                              <1> 
  3151                              <1> 
  3152                              <1> ;--- INT 13H -------------------------------------------------------------------
  3153                              <1> ;									       :
  3154                              <1> ; FIXED DISK I/O INTERFACE						       :
  3155                              <1> ;									       :
  3156                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  3157                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  3158                              <1> ;									       :
  3159                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  3160                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  3161                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  3162                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  3163                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  3164                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  3165                              <1> ;									       :
  3166                              <1> ;------------------------------------------------------------------------------:
  3167                              <1> ;									       :
  3168                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  3169                              <1> ;									       :
  3170                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  3171                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  3172                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  3173                              <1> ;			  DL > 80H - DISK				       :
  3174                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  3175                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  3176                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  3177                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  3178                              <1> ;	(AH)= 06H  UNUSED						       :
  3179                              <1> ;	(AH)= 07H  UNUSED						       :
  3180                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  3181                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  3182                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  3183                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  3184                              <1> ;	(AH)= 0AH  READ LONG						       :
  3185                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  3186                              <1> ;	(AH)= 0CH  SEEK 						       :
  3187                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  3188                              <1> ;	(AH)= 0EH  UNUSED						       :
  3189                              <1> ;	(AH)= 0FH  UNUSED						       :
  3190                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  3191                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  3192                              <1> ;	(AH)= 12H  UNUSED						       :
  3193                              <1> ;	(AH)= 13H  UNUSED						       :
  3194                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  3195                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  3196                              <1> ;									       :
  3197                              <1> ;-------------------------------------------------------------------------------
  3198                              <1> ;									       :
  3199                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  3200                              <1> ;									       :
  3201                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  3202                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  3203                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  3204                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  3205                              <1> ;									       :
  3206                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  3207                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  3208                              <1> ;				 (10 BITS TOTAL)			       :
  3209                              <1> ;									       :
  3210                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  3211                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  3212                              <1> ;									       :
  3213                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  3214                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  3215                              <1> ;									       :
  3216                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  3217                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  3218                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  3219                              <1> ;			       80H FOR A BAD SECTOR			       :
  3220                              <1> ;			   N = SECTOR NUMBER				       :
  3221                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  3222                              <1> ;			   THE TABLE SHOULD BE: 			       :
  3223                              <1> ;									       :
  3224                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  3225                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  3226                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  3227                              <1> ;									       :
  3228                              <1> ;-------------------------------------------------------------------------------
  3229                              <1> 
  3230                              <1> ;-------------------------------------------------------------------------------
  3231                              <1> ; OUTPUT								       :
  3232                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  3233                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  3234                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  3235                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  3236                              <1> ;									       :
  3237                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  3238                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  3239                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  3240                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  3241                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  3242                              <1> ;		REWRITTEN.						       :
  3243                              <1> ;									       :
  3244                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  3245                              <1> ;	   INPUT:							       :
  3246                              <1> ;	     (DL) = DRIVE NUMBER					       :	
  3247                              <1> ;	     ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)						       :	 	
  3248                              <1> ;	     EBX = Buffer address for fixed disk parameters table (32 bytes)   :
  3249                              <1> ;	   OUTPUT:							       :
  3250                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  3251                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  3252                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  3253                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  3254                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  3255                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  3256                              <1> ;									       :
  3257                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  3258                              <1> ;									       :
  3259                              <1> ;	AH = 0 - NOT PRESENT						       :
  3260                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  3261                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  3262                              <1> ;	     3 - FIXED DISK						       :
  3263                              <1> ;									       :
  3264                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  3265                              <1> ;									       :
  3266                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  3267                              <1> ;	INFORMATION.							       :
  3268                              <1> ;									       :
  3269                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  3270                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  3271                              <1> ;									       :
  3272                              <1> ;-------------------------------------------------------------------------------
  3273                              <1> 
  3274                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  3275                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  3276                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  3277                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  3278                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  3279                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  3280                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  3281                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  3282                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  3283                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  3284                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  3285                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  3286                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  3287                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  3288                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  3289                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  3290                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  3291                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  3292                              <1> 
  3293                              <1> ;--------------------------------------------------------
  3294                              <1> ;							:
  3295                              <1> ; FIXED DISK PARAMETER TABLE				:
  3296                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  3297                              <1> ;							:
  3298                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  3299                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  3300                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  3301                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  3302                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  3303                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  3304                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  3305                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  3306                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  3307                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  3308                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  3309                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  3310                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  3311                              <1> ;							:
  3312                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  3313                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  3314                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  3315                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  3316                              <1> ;							:
  3317                              <1> ;--------------------------------------------------------
  3318                              <1> 
  3319                              <1> ;--------------------------------------------------------
  3320                              <1> ;							:
  3321                              <1> ; HARDWARE SPECIFIC VALUES				:
  3322                              <1> ;							:
  3323                              <1> ;  -  CONTROLLER I/O PORT				:
  3324                              <1> ;							:
  3325                              <1> ;     > WHEN READ FROM: 				:
  3326                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  3327                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  3328                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  3329                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  3330                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  3331                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  3332                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  3333                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  3334                              <1> ;							:
  3335                              <1> ;     > WHEN WRITTEN TO:				:
  3336                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  3337                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  3338                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  3339                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  3340                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  3341                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  3342                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  3343                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  3344                              <1> ;							:
  3345                              <1> ;--------------------------------------------------------
  3346                              <1> 
  3347                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  3348                              <1> ;HF1_PORT	equ	0170h	
  3349                              <1> ;HF_REG_PORT	EQU	03F6H
  3350                              <1> ;HF1_REG_PORT	equ	0376h
  3351                              <1> 
  3352                              <1> HDC1_BASEPORT	equ	1F0h
  3353                              <1> HDC2_BASEPORT	equ	170h		
  3354                              <1> 
  3355                              <1> align 2
  3356                              <1> 
  3357                              <1> ;-----		STATUS REGISTER
  3358                              <1> 
  3359                              <1> ST_ERROR	EQU	00000001B	;
  3360                              <1> ST_INDEX	EQU	00000010B	;
  3361                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  3362                              <1> ST_DRQ		EQU	00001000B	;
  3363                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  3364                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  3365                              <1> ST_READY	EQU	01000000B	;
  3366                              <1> ST_BUSY 	EQU	10000000B	;
  3367                              <1> 
  3368                              <1> ;-----		ERROR REGISTER
  3369                              <1> 
  3370                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  3371                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  3372                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  3373                              <1> ;		EQU	00001000B	; NOT USED
  3374                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  3375                              <1> ;		EQU	00100000B	; NOT USED
  3376                              <1> ERR_DATA_ECC	EQU	01000000B
  3377                              <1> ERR_BAD_BLOCK	EQU	10000000B
  3378                              <1> 
  3379                              <1> 
  3380                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  3381                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  3382                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  3383                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  3384                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  3385                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  3386                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  3387                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  3388                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  3389                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  3390                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  3391                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  3392                              <1> 
  3393                              <1> ;MAX_FILE	EQU	2
  3394                              <1> ;S_MAX_FILE	EQU	2
  3395                              <1> MAX_FILE	equ	4		; 22/12/2014
  3396                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  3397                              <1> 
  3398                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  3399                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  3400                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  3401                              <1> 
  3402                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  3403                              <1> 
  3404                              <1> ;-----		COMMAND BLOCK REFERENCE
  3405                              <1> 
  3406                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  3407                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  3408                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  3409                              <1> ; 19/12/2014
  3410                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  3411                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  3412                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3413                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3414                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  3415                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  3416                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  3417                              <1> 
  3418                              <1> align 2
  3419                              <1> 
  3420                              <1> ;----------------------------------------------------------------
  3421                              <1> ; FIXED DISK I/O SETUP						:
  3422                              <1> ;								:
  3423                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  3424                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  3425                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  3426                              <1> ;								:
  3427                              <1> ;----------------------------------------------------------------
  3428                              <1> 
  3429                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3430                              <1> 
  3431                              <1> DISK_SETUP:
  3432                              <1> 	;CLI
  3433                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  3434                              <1> 	;xor	ax,ax
  3435                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  3436                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  3437                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  3438                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  3439                              <1> 	;MOV	[DISK_VECTOR+2],AX
  3440                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  3441                              <1> 	;MOV	[ORG_VECTOR+2],CS
  3442                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  3443                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  3444                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  3445                              <1> 	;;MOV	[HDISK_INT+2],CS
  3446                              <1> 	;mov	[HDISK_INT1+2],CS
  3447                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  3448                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  3449                              <1> 	;mov	[HDISK_INT2+2],CS
  3450                              <1> 	;
  3451                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  3452                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  3453                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  3454                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  3455                              <1> 	;push	cs
  3456                              <1> 	;pop	ds
  3457                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  3458                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  3459 0000280E C705[28D30000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3459 00002816 0900                <1>
  3460                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  3461                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  3462 00002818 C705[2CD30000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3462 00002820 0900                <1>
  3463                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  3464                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  3465 00002822 C705[30D30000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3465 0000282A 0900                <1>
  3466                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  3467                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  3468 0000282C C705[34D30000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3468 00002834 0900                <1>
  3469                              <1> 	;
  3470                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  3471                              <1> 	;;;AND	AL,0BFH
  3472                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  3473                              <1> 	;;;JMP	$+2
  3474                              <1> 	;;IODELAY
  3475                              <1> 	;;OUT	INTB01,AL
  3476                              <1> 	;;IODELAY
  3477                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  3478                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  3479                              <1> 	;;;JMP	$+2
  3480                              <1> 	;;IODELAY
  3481                              <1> 	;;OUT	INTA01,AL
  3482                              <1> 	;
  3483                              <1> 	;STI
  3484                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  3485                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  3486                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  3487                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3488                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  3489                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  3490                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  3491                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  3492                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  3493                              <1> 	;mov	si, hd0_type
  3494 00002836 BE[90CD0000]        <1> 	mov	esi, hd0_type
  3495                              <1> 	;mov	cx, 4
  3496 0000283B B904000000          <1> 	mov	ecx, 4
  3497                              <1> hde_l:
  3498 00002840 AC                  <1> 	lodsb
  3499 00002841 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3500 00002843 7206                <1> 	jb	short _L4
  3501 00002845 FE05[26D30000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3502                              <1> _L4: ; 26/02/2015
  3503 0000284B E2F3                <1> 	loop	hde_l	
  3504                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  3505                              <1> ;L4:
  3506                              <1> 	; 
  3507                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  3508                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  3509                              <1> 	;;mov 	cl, 3
  3510                              <1> 	;;
  3511                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  3512                              <1> ;;hdc_dl:
  3513                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  3514                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  3515                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  3516                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  3517                              <1> 	;;jnc	short hdc_reset0
  3518                              <1> 	;;loop	hdc_dl
  3519                              <1> 	;;; 27/12/2014
  3520                              <1> 	;;stc
  3521                              <1> 	;;retn
  3522                              <1> 	;
  3523                              <1> ;;hdc_reset0:
  3524                              <1> 	; 18/01/2015
  3525 0000284D 8A0D[26D30000]      <1> 	mov	cl, [HF_NUM]
  3526 00002853 20C9                <1> 	and	cl, cl
  3527 00002855 740E                <1> 	jz	short POD_DONE
  3528                              <1> 	;
  3529 00002857 B27F                <1> 	mov	dl, 7Fh
  3530                              <1> hdc_reset1:
  3531 00002859 FEC2                <1> 	inc	dl
  3532                              <1> 	;; 31/12/2015
  3533                              <1> 	;;push	dx
  3534                              <1> 	;;push	cx
  3535                              <1> 	;;push	ds
  3536                              <1> 	;;sub	ax, ax
  3537                              <1> 	;;mov	ds, ax
  3538                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  3539                              <1> 	;;pop	ds
  3540                              <1> 	;;MOV	BX,AX
  3541                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  3542                              <1> 	;;MOV	CX,AX
  3543                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  3544                              <1> 	;;
  3545                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  3546                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  3547                              <1> 	;;pop	cx
  3548                              <1> 	;;pop	dx
  3549                              <1> 	;;
  3550                              <1> 	; 18/01/2015
  3551 0000285B B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3552                              <1> 	;int	13h
  3553 0000285D E8A4FFFFFF          <1> 	call	int13h
  3554 00002862 E2F5                <1> 	loop	hdc_reset1
  3555 00002864 F8                  <1> 	clc 	; 29/05/2016
  3556                              <1> POD_DONE:
  3557 00002865 C3                  <1> 	RETn
  3558                              <1> 
  3559                              <1> ;;-----	POD_ERROR
  3560                              <1> 
  3561                              <1> ;;CTL_ERRX:
  3562                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  3563                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  3564                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3565                              <1> ;	;JMP	short POD_DONE
  3566                              <1> 
  3567                              <1> ;;HD_RESET_1:
  3568                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  3569                              <1> ;;	;PUSH	CX
  3570                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  3571                              <1> ;;	INT	13H
  3572                              <1> ;;	JC	short RES_2
  3573                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  3574                              <1> ;;	INT	13H
  3575                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  3576                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  3577                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3578                              <1> ;;					; (30 seconds)		
  3579                              <1> ;;	;cmc
  3580                              <1> ;;	;JNC	short RES_1
  3581                              <1> ;;	jb	short RES_1
  3582                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  3583                              <1> ;;	;TEST	DL,1
  3584                              <1> ;;	;JNZ	RES_E1
  3585                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  3586                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  3587                              <1> ;;	;JMP	SHORT RES_E1
  3588                              <1> ;;RES_ER: ; 22/12/2014
  3589                              <1> ;;RES_OK:
  3590                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3591                              <1> ;;	;POP	BX
  3592                              <1> ;;	RETn
  3593                              <1> ;;
  3594                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  3595                              <1> ;;	INT	13H
  3596                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  3597                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  3598                              <1> ;;	INT	13H
  3599                              <1> ;;	JC	short RES_ER
  3600                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  3601                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  3602                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  3603                              <1> ;;	INT	13H
  3604                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  3605                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  3606                              <1> ;;	JE	short RES_OK
  3607                              <1> ;;	CMP	AH,DATA_CORRECTED
  3608                              <1> ;;	JE	short RES_OK
  3609                              <1> ;;	CMP	AH,BAD_ECC
  3610                              <1> ;;	JE	short RES_OK
  3611                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  3612                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3613                              <1> ;;					; (60 seconds)		
  3614                              <1> ;;	cmc
  3615                              <1> ;;	JC	short RES_ER		; FAILED
  3616                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  3617                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  3618                              <1> ;;	AND	AL,3FH
  3619                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  3620                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  3621                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  3622                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  3623                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  3624                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  3625                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  3626                              <1> ;;	;TEST	DL,1
  3627                              <1> ;;	;JNZ	short RES_E1
  3628                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  3629                              <1> ;;;RES_E1:
  3630                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3631                              <1> ;;;RES_OK:
  3632                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3633                              <1> ;;	;POP	BX
  3634                              <1> ;;	;RETn
  3635                              <1> ;
  3636                              <1> ;;SET_FAIL:
  3637                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  3638                              <1> ;	;CALL	CMOS_READ
  3639                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  3640                              <1> ;	;XCHG	AH,AL			; SAVE IT
  3641                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  3642                              <1> ;	;RETn
  3643                              <1> ;
  3644                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  3645                              <1> ;	;POP	AX			; SAVE RETURN
  3646                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  3647                              <1> ;	;POP	BX
  3648                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  3649                              <1> ;	;PUSH	CX
  3650                              <1> ;	;PUSH	AX
  3651                              <1> ;	;push	ds
  3652                              <1> ;	;xor	ax, ax
  3653                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  3654                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  3655                              <1> ;	;				; BX = START TIME
  3656                              <1> ;	;				; CX = END TIME
  3657                              <1> ;	;pop	ds
  3658                              <1> ;	;CMP	BX,CX
  3659                              <1> ;	;JB	short TCHK1		; START < END
  3660                              <1> ;	;CMP	BX,AX
  3661                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  3662                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  3663                              <1> ;;TCHK1: CMP	AX,BX
  3664                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  3665                              <1> ;;TCHK2: CMP	AX,CX
  3666                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  3667                              <1> ;;					; OR CURRENT < END < START
  3668                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  3669                              <1> ;;	RETn
  3670                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  3671                              <1> ;;	RETn
  3672                              <1> ;;
  3673                              <1> ;;int_13h:
  3674                              <1> 
  3675                              <1> ;----------------------------------------
  3676                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  3677                              <1> ;----------------------------------------
  3678                              <1> 
  3679                              <1> ; 29/05/2016 
  3680                              <1> ; 28/05/2016
  3681                              <1> ; 27/05/2016
  3682                              <1> ; 16/05/2016
  3683                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  3684                              <1> int33h:  ; DISK I/O
  3685                              <1> 	; 29/05/2016
  3686 00002866 80642408FE          <1> 	and	byte [esp+8], 11111110b  ; clear carry bit of eflags register
  3687                              <1> 	; 16/05/2016
  3688 0000286B 53                  <1> 	push	ebx ; user's buffer address (virtual)
  3689 0000286C 1E                  <1> 	push	ds
  3690 0000286D 66BB1000            <1> 	mov	bx, KDATA ; System (Kernel's) data segment
  3691 00002871 8EDB                <1> 	mov	ds, bx
  3692 00002873 C605[4ED90000]00    <1> 	mov	byte [scount], 0 ; sector count for transfer
  3693 0000287A 80FC03              <1> 	cmp	ah, 03h ; chs write
  3694 0000287D 773C                <1> 	ja	short int33h_2
  3695 0000287F 7407                <1> 	je	short int33h_0
  3696 00002881 80FC02              <1> 	cmp	ah, 02h ; chs read
  3697 00002884 7260                <1> 	jb	short int33h_5
  3698 00002886 EB59                <1> 	jmp	short int33h_4
  3699                              <1> int33h_0:
  3700                              <1> 	; transfer user's buffer content to sector buffer
  3701 00002888 51                  <1> 	push	ecx
  3702 00002889 0FB6C8              <1> 	movzx	ecx, al
  3703                              <1> int33h_1:
  3704 0000288C 56                  <1> 	push	esi
  3705 0000288D 8B74240C            <1> 	mov	esi, [esp+12] ; esi, ecx, ds, ebx
  3706                              <1> 	; esi = user's buffer address (virtual, ebx)
  3707 00002891 57                  <1> 	push	edi
  3708 00002892 06                  <1> 	push	es
  3709 00002893 50                  <1> 	push	eax
  3710 00002894 66B81000            <1> 	mov	ax, KDATA
  3711 00002898 8EC0                <1> 	mov	es, ax
  3712 0000289A BF00000700          <1> 	mov	edi, Cluster_Buffer
  3713 0000289F C1E109              <1> 	shl	ecx, 9 ; * 512
  3714 000028A2 E8FD940000          <1> 	call	transfer_from_user_buffer
  3715 000028A7 58                  <1> 	pop	eax
  3716 000028A8 07                  <1> 	pop	es
  3717 000028A9 5F                  <1> 	pop	edi
  3718 000028AA 5E                  <1> 	pop	esi
  3719 000028AB 59                  <1> 	pop	ecx
  3720 000028AC 7338                <1> 	jnc	short int33h_5
  3721 000028AE 1F                  <1> 	pop	ds
  3722 000028AF 5B                  <1> 	pop	ebx
  3723                              <1> 
  3724                              <1> 	; (*) 29/05/2016
  3725                              <1> 	; (*) retf 4 ; skip eflags on stack
  3726                              <1> 
  3727                              <1> 	; 29/05/2016 -set carry flag on stack-
  3728                              <1> 	; [esp] = EIP
  3729                              <1> 	; [esp+4] = CS
  3730                              <1> 	; [esp+8] = E-FLAGS
  3731 000028B0 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3732                              <1> 	; [esp+12] = ESP (user)
  3733                              <1> 	; [esp+16] = SS (User)
  3734 000028B5 B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3735 000028BA CF                  <1> 	iretd
  3736                              <1> 	
  3737                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
  3738                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
  3739                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  3740                              <1> 	; // RETF instruction:
  3741                              <1> 	;
  3742                              <1> 	; IF OperandMode=32 THEN
  3743                              <1>  	;    Load CS:EIP from stack;
  3744                              <1>  	;    Set CS RPL to CPL;
  3745                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
  3746                              <1>  	;    Load SS:eSP from stack;
  3747                              <1>  	; ELSE (* OperandMode=16 *)
  3748                              <1>  	;    Load CS:IP from stack;
  3749                              <1>  	;    Set CS RPL to CPL;
  3750                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
  3751                              <1> 	;    Load SS:eSP from stack;
  3752                              <1>  	; FI;
  3753                              <1> 	;
  3754                              <1> 	; //
  3755                              <1> 
  3756                              <1> int33h_2:
  3757 000028BB 80FC05              <1> 	cmp	ah, 05h ; format track
  3758 000028BE 770A                <1> 	ja	short int33h_3
  3759 000028C0 7224                <1> 	jb	short int33h_5
  3760 000028C2 51                  <1> 	push	ecx
  3761 000028C3 B901000000          <1> 	mov	ecx, 1
  3762 000028C8 EBC2                <1> 	jmp	short int33h_1
  3763                              <1> int33h_3:
  3764 000028CA 80FC1C              <1> 	cmp	ah, 1Ch ; LBA write
  3765 000028CD 7717                <1> 	ja	short int33h_5
  3766 000028CF 74B7                <1> 	je	short int33h_0
  3767 000028D1 80FC1B              <1> 	cmp	ah, 1Bh ; LBA read
  3768 000028D4 740B                <1> 	je	short int33h_4
  3769 000028D6 80FC08              <1> 	cmp	ah, 08h ; get disk parameters
  3770 000028D9 750B                <1> 	jne	short int33h_5
  3771 000028DB 8B5C2404            <1> 	mov	ebx, [esp+4] ; user's buffer address
  3772 000028DF EB0A                <1> 	jmp	short int33h_6
  3773                              <1> int33h_4:
  3774 000028E1 A2[4ED90000]        <1> 	mov	byte [scount], al ; <= 128 sectors
  3775                              <1> int33h_5:
  3776 000028E6 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; max. 65536 bytes
  3777                              <1> 				    ; buf. addr: 70000h	
  3778                              <1> 	;mov	byte [ClusterBuffer_Valid], 0
  3779                              <1> int33h_6:
  3780 000028EB 1F                  <1> 	pop	ds
  3781 000028EC 9C                  <1> 	pushfd
  3782 000028ED 0E                  <1> 	push 	cs
  3783 000028EE E845000000          <1> 	call 	DISK_IO
  3784 000028F3 5B                  <1> 	pop	ebx
  3785 000028F4 723C                <1> 	jc	short int33h_9
  3786                              <1> 	;
  3787 000028F6 2E803D[4ED90000]00  <1> 	cmp	byte [CS:scount], 0
  3788 000028FE 762C                <1> 	jna	short int33h_7
  3789                              <1> 	; transfer sector buffer content to user's buffer
  3790 00002900 06                  <1> 	push	es
  3791 00002901 1E                  <1> 	push	ds
  3792 00002902 50                  <1> 	push	eax
  3793 00002903 66B81000            <1> 	mov	ax, KDATA
  3794 00002907 8ED8                <1> 	mov	ds, ax
  3795 00002909 8EC0                <1> 	mov	es, ax
  3796 0000290B 51                  <1> 	push	ecx
  3797 0000290C 56                  <1> 	push	esi
  3798 0000290D 57                  <1> 	push	edi
  3799 0000290E 0FB60D[4ED90000]    <1> 	movzx	ecx, byte [scount]
  3800 00002915 C1E109              <1> 	shl	ecx, 9 ; * 512 bytes
  3801 00002918 89DF                <1> 	mov	edi, ebx ; user's buffer address
  3802 0000291A BE00000700          <1> 	mov	esi, Cluster_Buffer
  3803 0000291F E836940000          <1> 	call	transfer_to_user_buffer
  3804 00002924 5F                  <1> 	pop	edi
  3805 00002925 5E                  <1> 	pop	esi
  3806 00002926 59                  <1> 	pop	ecx
  3807 00002927 58                  <1> 	pop	eax
  3808 00002928 1F                  <1> 	pop	ds
  3809 00002929 07                  <1> 	pop	es
  3810 0000292A 7201                <1> 	jc	short int33h_8
  3811                              <1> int33h_7:
  3812                              <1> 	; cf = 0  ; use eflags which is in stack
  3813 0000292C CF                  <1> 	iretd	
  3814                              <1> int33h_8:
  3815 0000292D B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3816                              <1> int33h_9:
  3817                              <1> 	; cf = 1
  3818                              <1> 
  3819                              <1> 	; (*) 29/05/2016	
  3820                              <1> 	; (*) retf 4 ; skip eflags on stack
  3821                              <1> 	; Note: This 'retf 4' was wrong, -it was causing
  3822                              <1> 	;       to stack errors in ring 3-
  3823                              <1> 	;	POP sequence of 'retf 4' is as
  3824                              <1> 	;       "eip, cs, eflags, esp, ss, +4 bytes" 
  3825                              <1>         ;       it is not as "eip, cs, +4 bytes, esp, ss" ! 
  3826                              <1> 
  3827                              <1> 	; 29/05/2016 -set carry flag on stack-
  3828 00002932 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3829 00002937 CF                  <1> 	iretd
  3830                              <1> 
  3831                              <1> ; 29/05/2016
  3832                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  3833                              <1> 
  3834                              <1> DISK_IO:
  3835 00002938 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  3836                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  3837                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  3838                              <1> 	;;call	int40h
  3839 0000293B 0F823FF0FFFF        <1> 	jb	DISKETTE_IO_1
  3840                              <1> ;RET_2:
  3841                              <1> 	;RETf	2			; BACK TO CALLER
  3842                              <1> ;	retf	4
  3843                              <1> A1:
  3844 00002941 FB                  <1> 	STI				; ENABLE INTERRUPTS
  3845                              <1> 	;; 04/01/2015
  3846                              <1> 	;;OR	AH,AH
  3847                              <1> 	;;JNZ	short A2
  3848                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  3849                              <1> 	;;SUB	AH,AH
  3850 00002942 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  3851                              <1> 	;JA	short RET_2
  3852 00002945 7616                <1> 	jna	short _A0
  3853                              <1> 	; 29/05/2016
  3854 00002947 1E                  <1> 	push	ds
  3855 00002948 6650                <1> 	push	ax
  3856 0000294A 66B81000            <1> 	mov	ax, KDATA
  3857 0000294E 8ED8                <1> 	mov	ds, ax
  3858 00002950 6658                <1> 	pop	ax
  3859 00002952 B4AA                <1>         mov     ah, 0AAh        ; Hard disk drive not ready !
  3860                              <1> 				; (Programmer's guide to AMIBIOS, 1992)
  3861 00002954 8825[25D30000]      <1> 	mov     byte [DISK_STATUS1], ah
  3862 0000295A 1F                  <1> 	pop	ds
  3863 0000295B EB38                <1> 	jmp	short RET_2
  3864                              <1> _A0:
  3865                              <1> 	; 18/01/2015
  3866 0000295D 08E4                <1> 	or	ah,ah
  3867 0000295F 743A                <1> 	jz	short A4
  3868 00002961 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  3869 00002964 7504                <1> 	jne	short A2
  3870 00002966 28E4                <1> 	sub	ah,ah	; Reset
  3871 00002968 EB31                <1> 	jmp	short A4
  3872                              <1> A2:
  3873 0000296A 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3874                              <1> 	;JNZ	short A3
  3875                              <1>         ;JMP    GET_PARM_N
  3876 0000296D 0F8431030000        <1> 	je	GET_PARM_N
  3877 00002973 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3878                              <1> 	;JNZ	short A4
  3879                              <1>         ;JMP    READ_DASD_TYPE
  3880 00002976 0F84DA020000        <1>         je      READ_DASD_TYPE
  3881                              <1> 	; 02/02/2015
  3882 0000297C 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3883                              <1> 	; 12/01/2015
  3884 0000297F F5                  <1> 	cmc
  3885 00002980 7319                <1> 	jnc	short A4
  3886                              <1> int33h_bad_cmd:
  3887                              <1> 	; 16/05/2016
  3888                              <1> 	; 30/01/2015
  3889                              <1> 	; 29/05/2016
  3890 00002982 1E                  <1> 	push	ds
  3891 00002983 6650                <1> 	push	ax
  3892 00002985 66B81000            <1> 	mov	ax, KDATA
  3893 00002989 8ED8                <1> 	mov	ds, ax
  3894 0000298B 6658                <1> 	pop	ax
  3895 0000298D B401                <1> 	mov	ah, BAD_CMD
  3896 0000298F 8825[25D30000]      <1> 	mov     [DISK_STATUS1], ah ; BAD_CMD  ; COMMAND ERROR
  3897                              <1>         ;jmp	short RET_2
  3898                              <1> RET_2:
  3899                              <1> 	; (*) 29/05/2016
  3900                              <1> 	; (*) retf 4
  3901 00002995 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3902 0000299A CF                  <1> 	iretd
  3903                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3904 0000299B C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3905 0000299F 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3906 000029A0 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3907 000029A1 52                  <1> 	PUSH	eDX
  3908 000029A2 1E                  <1> 	PUSH	DS
  3909 000029A3 06                  <1> 	PUSH	ES
  3910 000029A4 56                  <1> 	PUSH	eSI
  3911 000029A5 57                  <1> 	PUSH	eDI
  3912                              <1> 	;;04/01/2015
  3913                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  3914                              <1> 	;;JNZ	short A5
  3915                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  3916                              <1> ;;A5:	
  3917                              <1> 	;push	cs
  3918                              <1> 	;pop	ds
  3919                              <1> 	; 21/02/2015
  3920 000029A6 6650                <1> 	push	ax
  3921 000029A8 66B81000            <1> 	mov	ax, KDATA
  3922 000029AC 8ED8                <1> 	mov	ds, ax
  3923 000029AE 8EC0                <1> 	mov	es, ax	
  3924 000029B0 6658                <1> 	pop	ax
  3925 000029B2 E88D000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3926                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3927 000029B7 8A25[25D30000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  3928                              <1> 	;(*) CMP AH,1			; SET THE CARRY FLAG TO INDICATE
  3929                              <1> 	;(*) CMC			; SUCCESS OR FAILURE
  3930 000029BD 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  3931 000029BE 5E                  <1> 	POP	eSI
  3932 000029BF 07                  <1>         POP     ES
  3933 000029C0 1F                  <1>         POP     DS
  3934 000029C1 5A                  <1> 	POP	eDX
  3935 000029C2 59                  <1> 	POP	eCX
  3936 000029C3 5B                  <1> 	POP	eBX
  3937 000029C4 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  3938                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  3939                              <1> 	; (*) 29/05/2016
  3940                              <1> 	; (*) retf 4
  3941 000029C5 80FC01              <1> 	cmp	ah, 1
  3942 000029C8 7205                <1> 	jc	short _A5 
  3943 000029CA 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3944                              <1> _A5:
  3945 000029CF CF                  <1> 	iretd
  3946                              <1> 
  3947                              <1> ; 21/02/2015
  3948                              <1> ;       dw --> dd
  3949                              <1> D1:					; FUNCTION TRANSFER TABLE
  3950 000029D0 [922B0000]          <1> 	dd	DISK_RESET		; 000H
  3951 000029D4 [092C0000]          <1> 	dd	RETURN_STATUS		; 001H
  3952 000029D8 [162C0000]          <1> 	dd	DISK_READ		; 002H
  3953 000029DC [1F2C0000]          <1> 	dd	DISK_WRITE		; 003H
  3954 000029E0 [282C0000]          <1> 	dd	DISK_VERF		; 004H
  3955 000029E4 [402C0000]          <1> 	dd	FMT_TRK 		; 005H
  3956 000029E8 [882B0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  3957 000029EC [882B0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  3958 000029F0 [882B0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  3959 000029F4 [2B2D0000]          <1> 	dd	INIT_DRV		; 009H
  3960 000029F8 [8A2D0000]          <1> 	dd	RD_LONG 		; 00AH
  3961 000029FC [932D0000]          <1> 	dd	WR_LONG 		; 00BH
  3962 00002A00 [9C2D0000]          <1> 	dd	DISK_SEEK		; 00CH
  3963 00002A04 [922B0000]          <1> 	dd	DISK_RESET		; 00DH
  3964 00002A08 [882B0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  3965 00002A0C [882B0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  3966 00002A10 [C42D0000]          <1> 	dd	TST_RDY 		; 010H
  3967 00002A14 [E82D0000]          <1> 	dd	HDISK_RECAL		; 011H
  3968 00002A18 [882B0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  3969 00002A1C [882B0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  3970 00002A20 [1E2E0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  3971                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  3972 00002A24 [882B0000]          <1> 	dd	BAD_COMMAND		; 015h
  3973 00002A28 [882B0000]          <1> 	dd	BAD_COMMAND		; 016h
  3974 00002A2C [882B0000]          <1> 	dd	BAD_COMMAND		; 017h
  3975 00002A30 [882B0000]          <1> 	dd	BAD_COMMAND		; 018h
  3976 00002A34 [882B0000]          <1> 	dd	BAD_COMMAND		; 019h
  3977 00002A38 [882B0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  3978 00002A3C [162C0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  3979 00002A40 [1F2C0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  3980                              <1> D1L     EQU    $ - D1
  3981                              <1> 
  3982                              <1> DISK_IO_CONT:
  3983                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3984 00002A44 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  3985                              <1> 	;;JNZ	short SU0
  3986                              <1>         ;;JMP    RETURN_STATUS
  3987 00002A47 0F84BC010000        <1> 	je	RETURN_STATUS
  3988                              <1> SU0:
  3989 00002A4D C605[25D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3990                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  3991                              <1> 	;mov	si, bx ;; 14/02/2015
  3992 00002A54 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  3993 00002A56 8A1D[26D30000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  3994                              <1> 	;; 04/01/2015
  3995                              <1> 	;;PUSH	AX
  3996 00002A5C 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  3997                              <1> 					; (get drive number as 0 to 3)
  3998 00002A5F 38D3                <1> 	CMP	BL,DL
  3999                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  4000 00002A61 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  4001                              <1>         ;
  4002                              <1> 	;;03/01/2015
  4003 00002A67 29DB                <1> 	sub	ebx, ebx
  4004 00002A69 88D3                <1> 	mov	bl, dl
  4005                              <1> 	;sub	bh, bh
  4006 00002A6B 883D[38D30000]      <1> 	mov	[LBAMode], bh 	; 0
  4007                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  4008                              <1> 	;test	byte [ebx+hd0_type], 1
  4009                              <1> 	;jz	short su1		; no
  4010                              <1> 	;inc	byte [LBAMode]
  4011                              <1> ;su1:
  4012                              <1> 	; 21/02/2015 (32 bit modification)
  4013                              <1> 	;04/01/2015
  4014 00002A71 6650                <1> 	push	ax ; ***
  4015                              <1> 	;PUSH	ES ; **
  4016 00002A73 6652                <1> 	PUSH	DX ; *
  4017 00002A75 6650                <1> 	push	ax
  4018 00002A77 E888060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  4019                              <1> 	; 02/02/2015
  4020                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  4021 00002A7C 668B4310            <1> 	mov	ax, [ebx+16]
  4022 00002A80 66A3[84CD0000]      <1> 	mov	[HF_PORT], ax
  4023                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  4024 00002A86 668B5312            <1> 	mov	dx, [ebx+18]
  4025 00002A8A 668915[86CD0000]    <1> 	mov	[HF_REG_PORT], dx
  4026                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  4027 00002A91 8A4314              <1> 	mov	al, [ebx+20]
  4028                              <1> 	; 23/02/2015
  4029 00002A94 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  4030 00002A96 7406                <1> 	jz 	short su1
  4031 00002A98 FE05[38D30000]      <1> 	inc	byte [LBAMode] ; 1 
  4032                              <1> su1: 	 
  4033 00002A9E C0E804              <1> 	shr 	al, 4
  4034 00002AA1 2401                <1> 	and	al, 1			
  4035 00002AA3 A2[88CD0000]        <1> 	mov	[hf_m_s], al 
  4036                              <1> 	;
  4037                              <1> 	; 03/01/2015
  4038                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  4039 00002AA8 8A4308              <1> 	mov	al, [ebx+8]
  4040                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  4041 00002AAB EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  4042                              <1> 					; Control Byte:  (= 08h, here)
  4043                              <1> 					; bit 0 - 0
  4044                              <1> 					; bit 1 - nIEN (1 = disable irq)
  4045                              <1> 					; bit 2 - SRST (software RESET)
  4046                              <1> 					; bit 3 - use extra heads (8 to 15)
  4047                              <1> 					;         -always set to 1-	
  4048                              <1> 					; (bits 3 to 7 are reserved
  4049                              <1> 					;          for ATA devices)
  4050 00002AAC 8A25[27D30000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4051 00002AB2 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  4052 00002AB5 08C4                <1> 	OR	AH,AL
  4053 00002AB7 8825[27D30000]      <1> 	MOV	[CONTROL_BYTE],AH	
  4054                              <1> 	; 04/01/2015
  4055 00002ABD 6658                <1> 	pop	ax
  4056 00002ABF 665A                <1> 	pop	dx ; * ;; 14/02/2015
  4057 00002AC1 20E4                <1> 	and	ah, ah	; Reset function ?
  4058 00002AC3 7507                <1> 	jnz	short su2
  4059                              <1> 	;;pop	dx ; * ;; 14/02/2015
  4060                              <1> 	;pop	es ; **
  4061 00002AC5 6658                <1> 	pop	ax ; ***
  4062                              <1> 	;;pop	bx
  4063 00002AC7 E9C6000000          <1>         jmp     DISK_RESET
  4064                              <1> su2:
  4065 00002ACC 803D[38D30000]00    <1> 	cmp	byte [LBAMode], 0
  4066 00002AD3 7661                <1> 	jna	short su3
  4067                              <1> 	;
  4068                              <1> 	; 02/02/2015 (LBA read/write function calls)
  4069 00002AD5 80FC1B              <1> 	cmp	ah, 1Bh
  4070 00002AD8 720B                <1> 	jb	short lbarw1
  4071 00002ADA 80FC1C              <1> 	cmp	ah, 1Ch
  4072 00002ADD 775C                <1> 	ja 	short invldfnc
  4073                              <1> 	;;pop	dx ; * ; 14/02/2015
  4074                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  4075 00002ADF 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  4076                              <1> 	;; 14/02/2015
  4077 00002AE1 88D1                <1> 	mov	cl, dl ; 14/02/2015
  4078                              <1> 	;;mov	dx, bx
  4079                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  4080                              <1> 	;;mov	bx, di
  4081                              <1> 	;mov	si, di ; Buffer offset
  4082 00002AE3 EB31                <1> 	jmp	short lbarw2
  4083                              <1> lbarw1:
  4084                              <1> 	; convert CHS to LBA
  4085                              <1> 	;
  4086                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  4087                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  4088                              <1> 	;	+ Sector - 1
  4089 00002AE5 6652                <1> 	push	dx ; * ;; 14/02/2015
  4090                              <1> 	;xor	dh, dh
  4091 00002AE7 31D2                <1> 	xor	edx, edx
  4092                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  4093 00002AE9 8A530E              <1> 	mov	dl, [ebx+14]
  4094                              <1> 	;xor	ah, ah
  4095 00002AEC 31C0                <1> 	xor	eax, eax
  4096                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  4097 00002AEE 8A4302              <1> 	mov	al, [ebx+2]
  4098 00002AF1 FEC8                <1> 	dec	al
  4099 00002AF3 6640                <1> 	inc	ax		; 0 =  256
  4100 00002AF5 66F7E2              <1> 	mul 	dx
  4101                              <1> 		; AX = # of Heads" * Sectors/Track
  4102 00002AF8 6689CA              <1> 	mov	dx, cx
  4103                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  4104 00002AFB 83E13F              <1> 	and	ecx, 3fh
  4105 00002AFE 86D6                <1> 	xchg	dl, dh
  4106 00002B00 C0EE06              <1> 	shr	dh, 6
  4107                              <1> 		; DX = cylinder (0 to 1023)
  4108                              <1> 	;mul 	dx
  4109                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  4110 00002B03 F7E2                <1> 	mul	edx
  4111 00002B05 FEC9                <1> 	dec	cl  ; sector - 1
  4112                              <1> 	;add	ax, cx
  4113                              <1> 	;adc	dx, 0
  4114                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  4115 00002B07 01C8                <1> 	add	eax, ecx
  4116 00002B09 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  4117                              <1> 	;push	dx
  4118                              <1> 	;push	ax
  4119 00002B0B 50                  <1> 	push	eax
  4120                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  4121 00002B0C 8A430E              <1> 	mov	al, [ebx+14]
  4122 00002B0F F6E5                <1> 	mul	ch
  4123                              <1> 		;  AX = Head * Sectors/Track
  4124 00002B11 6699                <1>         cwd
  4125                              <1> 	;pop	dx
  4126 00002B13 5A                  <1> 	pop	edx
  4127                              <1> 	;add	ax, dx
  4128                              <1> 	;pop	dx
  4129                              <1> 	;adc	dx, 0 ; add carry bit
  4130 00002B14 01D0                <1> 	add	eax, edx
  4131                              <1> lbarw2:
  4132 00002B16 29D2                <1> 	sub	edx, edx ; 21/02/2015
  4133 00002B18 88CA                <1> 	mov	dl, cl ; 21/02/2015
  4134 00002B1A C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  4135                              <1> 				; NOTE: Features register (1F1h, 171h)
  4136                              <1> 				; is not used for ATA device R/W functions. 
  4137                              <1> 				; It is old/obsolete 'write precompensation'
  4138                              <1> 				; register and error register
  4139                              <1> 				; for old ATA/IDE devices.
  4140                              <1> 	; 18/01/2014
  4141                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  4142 00002B1E 8A0D[88CD0000]      <1> 	mov	cl, [hf_m_s]
  4143                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  4144                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  4145                              <1> 				; bit 6 = 1 = LBA mode
  4146                              <1> 				; bit 7 = 1
  4147 00002B24 80C90E              <1> 	or	cl, 0Eh ; 1110b
  4148                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  4149 00002B27 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  4150 00002B2C C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  4151                              <1> 	;or	dh, ch
  4152 00002B2F 09C8                <1> 	or	eax, ecx	
  4153                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  4154                              <1> 				  ; (Sector Number Register)
  4155                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  4156                              <1> 				  ; (Cylinder Low Register)
  4157                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  4158                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  4159                              <1> 				  ; (Cylinder High Register)
  4160                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  4161                              <1> 				  ; (Drive/Head Register)
  4162                              <1> 	
  4163                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  4164 00002B31 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  4165                              <1> 	;14/02/2015
  4166                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  4167 00002B34 EB38                <1> 	jmp	short su4
  4168                              <1> su3:
  4169                              <1> 	; 02/02/2015 
  4170                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  4171 00002B36 80FC14              <1> 	cmp 	ah, 14h
  4172 00002B39 7604                <1> 	jna 	short chsfnc
  4173                              <1> invldfnc:
  4174                              <1>         ; 14/02/2015  
  4175                              <1> 	;pop	es ; **
  4176 00002B3B 6658                <1>         pop     ax ; ***
  4177                              <1>         ;jmp     short BAD_COMMAND_POP
  4178 00002B3D EB49                <1>         jmp     short BAD_COMMAND
  4179                              <1> chsfnc:	
  4180                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  4181 00002B3F 668B4305            <1> 	mov	ax, [ebx+5]
  4182 00002B43 66C1E802            <1> 	SHR	AX,2
  4183 00002B47 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  4184                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  4185                              <1> 	;;PUSH	DX
  4186                              <1> 	;;MOV	DX,[HF_REG_PORT]
  4187                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  4188                              <1> 	;;POP	DX ; * 
  4189                              <1> 	;;POP	ES ; **
  4190                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4191                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  4192                              <1> 	;;OR	AH,AL
  4193                              <1> 	;;MOV	[CONTROL_BYTE],AH
  4194                              <1> 	;
  4195 00002B4A 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  4196 00002B4C 243F                <1> 	AND	AL,3FH
  4197 00002B4E 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  4198 00002B51 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  4199 00002B54 88C8                <1> 	MOV	AL,CL
  4200 00002B56 C0E806              <1> 	SHR	AL,6
  4201 00002B59 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  4202                              <1> 	;;05/01/2015
  4203                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  4204 00002B5C A0[88CD0000]        <1> 	mov	al, [hf_m_s]
  4205 00002B61 C0E004              <1> 	SHL	AL,4
  4206 00002B64 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  4207 00002B67 08F0                <1> 	OR	AL,DH
  4208                              <1> 	;OR	AL,80H or 20H
  4209 00002B69 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  4210 00002B6B 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  4211                              <1> su4:
  4212                              <1> 	;POP	ES ; **
  4213                              <1>         ;; 14/02/2015
  4214                              <1>         ;;POP   AX
  4215                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  4216                              <1>         ;;PUSH  AX
  4217                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  4218                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  4219                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  4220 00002B6E 6658                <1>         pop     ax ; ***
  4221 00002B70 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4222 00002B73 29DB                <1>         sub	ebx, ebx
  4223 00002B75 88E3                <1> 	mov     bl, ah
  4224                              <1>         ;xor     bh, bh
  4225                              <1>         ;sal     bx, 1
  4226 00002B77 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  4227                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  4228                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  4229                              <1>         ;;JNB   short BAD_COMMAND_POP
  4230                              <1>         ;cmp     bx, D1L
  4231 00002B7B 83FB74              <1> 	cmp	ebx, D1L
  4232 00002B7E 7308                <1> 	jnb	short BAD_COMMAND
  4233                              <1>         ;xchg    bx, si
  4234 00002B80 87DE                <1>         xchg	ebx, esi
  4235                              <1> 	;;;POP	AX			; RESTORE AX
  4236                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  4237                              <1> 	
  4238                              <1> 	;;PUSH	CX
  4239                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  4240                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  4241                              <1> 	;SHR	CX,4
  4242                              <1> 	;MOV	AX,ES
  4243                              <1> 	;ADD	AX,CX
  4244                              <1> 	;MOV	ES,AX
  4245                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  4246                              <1> 	;;POP	AX
  4247                              <1> 	;;POP	CX
  4248                              <1> 	;;JMP	word [CS:SI+D1]
  4249                              <1> 	;jmp	word [SI+D1]
  4250 00002B82 FFA6[D0290000]      <1> 	jmp	dword [esi+D1]
  4251                              <1> ;;BAD_COMMAND_POP:
  4252                              <1> ;;	POP	AX
  4253                              <1> ;;	POP	BX
  4254                              <1> BAD_COMMAND:
  4255 00002B88 C605[25D30000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4256 00002B8F B000                <1> 	MOV	AL,0
  4257 00002B91 C3                  <1> 	RETn
  4258                              <1> 
  4259                              <1> ;----------------------------------------
  4260                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  4261                              <1> ;----------------------------------------
  4262                              <1> 
  4263                              <1> ; 18-1-2015 : one controller reset (not other one)
  4264                              <1> 
  4265                              <1> DISK_RESET:
  4266 00002B92 FA                  <1> 	CLI
  4267 00002B93 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4268                              <1> 	;JMP	$+2
  4269                              <1> 	IODELAY
  4269 00002B95 EB00                <2>  jmp short $+2
  4269 00002B97 EB00                <2>  jmp short $+2
  4270                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4271 00002B99 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4272 00002B9B E6A1                <1> 	OUT	INTB01,AL
  4273 00002B9D FB                  <1> 	STI				; START INTERRUPTS
  4274                              <1> 	; 14/02/2015
  4275 00002B9E 6689D7              <1> 	mov	di, dx	
  4276                              <1> 	; 04/01/2015
  4277                              <1> 	;xor	di,di
  4278                              <1> drst0:
  4279 00002BA1 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4280                              <1> 	;MOV	DX,HF_REG_PORT
  4281 00002BA3 668B15[86CD0000]    <1> 	MOV	DX,[HF_REG_PORT]
  4282 00002BAA EE                  <1> 	OUT	DX,AL			; RESET
  4283                              <1> ;	MOV	CX,10			; DELAY COUNT
  4284                              <1> ;DRD:	DEC	CX
  4285                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  4286                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  4287 00002BAB B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4288 00002BB0 E863ECFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4289                              <1>                                         ; 40 micro seconds)
  4290 00002BB5 A0[27D30000]        <1> 	mov	al,[CONTROL_BYTE]
  4291 00002BBA 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4292 00002BBC EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4293 00002BBD E838040000          <1> 	CALL	NOT_BUSY
  4294 00002BC2 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4295 00002BC4 668B15[84CD0000]    <1> 	MOV	DX,[HF_PORT]
  4296 00002BCB FEC2                <1> 	inc	dl  ; HF_PORT+1
  4297                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4298                              <1>         ;mov     cl, 10
  4299 00002BCD B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4300                              <1> drst1:
  4301 00002BD2 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4302 00002BD3 3C01                <1> 	CMP	AL,1
  4303                              <1> 	; 04/01/2015
  4304 00002BD5 740A                <1> 	jz	short drst2
  4305                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4306                              <1>         	; Drive/Head Register - bit 4
  4307 00002BD7 E2F9                <1> 	loop	drst1
  4308                              <1> DRERR:	
  4309 00002BD9 C605[25D30000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4310 00002BE0 C3                  <1> 	RETn
  4311                              <1> drst2:
  4312                              <1> 	; 14/02/2015
  4313 00002BE1 6689FA              <1> 	mov	dx,di
  4314                              <1> ;drst3:
  4315                              <1> ;	; 05/01/2015
  4316                              <1> ;	shl 	di,1
  4317                              <1> ;	; 04/01/2015
  4318                              <1> ;	mov	ax,[di+hd_cports]
  4319                              <1> ;	cmp	ax,[HF_REG_PORT]
  4320                              <1> ;	je	short drst4
  4321                              <1> ;	mov	[HF_REG_PORT], ax
  4322                              <1> ;	; 03/01/2015
  4323                              <1> ;	mov	ax,[di+hd_ports]
  4324                              <1> ;       mov     [HF_PORT], ax
  4325                              <1> ;	; 05/01/2014
  4326                              <1> ;	shr	di,1
  4327                              <1> ;	; 04/01/2015
  4328                              <1> ;	jmp	short drst0	; reset other controller
  4329                              <1> ;drst4:
  4330                              <1> ;	; 05/01/2015
  4331                              <1> ;	shr	di,1
  4332                              <1> ;	mov	al,[di+hd_dregs]
  4333                              <1> ;	and	al,10h ; bit 4 only
  4334                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  4335                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  4336                              <1> 	;
  4337 00002BE4 A0[88CD0000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4338 00002BE9 A801                <1> 	test	al,1
  4339                              <1> ;	jnz	short drst6
  4340 00002BEB 7516                <1>         jnz     short drst4
  4341 00002BED 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4342                              <1> ;drst5:
  4343                              <1> drst3:
  4344 00002BF1 E835010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4345                              <1> 	;mov	dx,di
  4346 00002BF6 E8ED010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  4347                              <1> 	; 04/01/2014
  4348                              <1> ;	inc	di
  4349                              <1> ;	mov	dx,di
  4350                              <1> ;	cmp	dl,[HF_NUM]
  4351                              <1> ;	jb	short drst3
  4352                              <1> ;DRE:
  4353 00002BFB C605[25D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4354 00002C02 C3                  <1> 	RETn
  4355                              <1> ;drst6:
  4356                              <1> drst4:		; Drive/Head Register - bit 4
  4357 00002C03 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4358                              <1>         ;jmp    short drst5
  4359 00002C07 EBE8                <1>         jmp     short drst3
  4360                              <1> 
  4361                              <1> ;----------------------------------------
  4362                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  4363                              <1> ;----------------------------------------
  4364                              <1> 
  4365                              <1> RETURN_STATUS:
  4366 00002C09 A0[25D30000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4367 00002C0E C605[25D30000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4368 00002C15 C3                  <1> 	RETn
  4369                              <1> 
  4370                              <1> ;----------------------------------------
  4371                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4372                              <1> ;----------------------------------------
  4373                              <1> 
  4374                              <1> DISK_READ:
  4375 00002C16 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4376 00002C1A E954020000          <1>         JMP     COMMANDI
  4377                              <1> 
  4378                              <1> ;----------------------------------------
  4379                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4380                              <1> ;----------------------------------------
  4381                              <1> 
  4382                              <1> DISK_WRITE:
  4383 00002C1F C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4384 00002C23 E9A6020000          <1>         JMP     COMMANDO
  4385                              <1> 
  4386                              <1> ;----------------------------------------
  4387                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4388                              <1> ;----------------------------------------
  4389                              <1> 
  4390                              <1> DISK_VERF:
  4391 00002C28 C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4392 00002C2C E814030000          <1> 	CALL	COMMAND
  4393 00002C31 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4394 00002C33 E886030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4395 00002C38 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4396 00002C3A E813040000          <1> 	CALL	CHECK_STATUS
  4397                              <1> VERF_EXIT:
  4398 00002C3F C3                  <1> 	RETn
  4399                              <1> 
  4400                              <1> ;----------------------------------------
  4401                              <1> ;	FORMATTING	     (AH = 05H) :
  4402                              <1> ;----------------------------------------
  4403                              <1> 
  4404                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  4405 00002C40 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4406                              <1> 	;PUSH	ES
  4407                              <1> 	;PUSH	BX
  4408 00002C44 53                  <1> 	push	ebx
  4409 00002C45 E8BA040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4410                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4411 00002C4A 8A430E              <1> 	mov	al, [ebx+14]
  4412 00002C4D 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4413 00002C50 5B                  <1> 	pop	ebx
  4414                              <1> 	;POP	BX
  4415                              <1> 	;POP	ES
  4416 00002C51 E97F020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  4417                              <1> 
  4418                              <1> ;----------------------------------------
  4419                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  4420                              <1> ;----------------------------------------
  4421                              <1> 
  4422                              <1> READ_DASD_TYPE:
  4423                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  4424 00002C56 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4425                              <1> 	;PUSH	ES
  4426 00002C57 53                  <1> 	PUSH	eBX
  4427                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4428                              <1> 	;push	cs
  4429                              <1> 	;pop	ds
  4430 00002C58 66BB1000            <1>         mov	bx, KDATA
  4431 00002C5C 8EDB                <1> 	mov	ds, bx
  4432                              <1> 	;mov	es, bx
  4433 00002C5E C605[25D30000]00    <1> 	MOV     byte [DISK_STATUS1],0
  4434 00002C65 8A1D[26D30000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4435 00002C6B 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4436 00002C6E 38D3                <1> 	CMP	BL,DL
  4437 00002C70 7627                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4438 00002C72 E88D040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  4439                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4440 00002C77 8A4302              <1> 	mov	al, [ebx+2]
  4441                              <1> 	;MOV	CL,[ES:BX+14]
  4442 00002C7A 8A4B0E              <1> 	mov	cl, [ebx+14]
  4443 00002C7D F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4444                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4445 00002C7F 668B0B              <1> 	mov	cx ,[ebx]
  4446                              <1> 	;
  4447                              <1> 	; 02/01/2015 
  4448                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  4449                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  4450 00002C82 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4451                              <1> 	;
  4452 00002C84 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4453 00002C87 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4454 00002C8A 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4455                              <1> 	;SUB	AX,AX
  4456 00002C8D 28C0                <1> 	sub	al, al
  4457 00002C8F B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4458 00002C91 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  4459                              <1> 	;POP	ES
  4460 00002C92 1F                  <1> 	POP	DS
  4461                              <1> 	; (*) CLC			; CLEAR CARRY
  4462                              <1> 	;RETf	2
  4463                              <1> 	; (*) 29/05/2016
  4464                              <1> 	; (*) retf 4
  4465 00002C93 80642408FE          <1> 	and	byte [esp+8], 0FEh ; clear carry bit of eflags register
  4466 00002C98 CF                  <1> 	iretd
  4467                              <1> 
  4468                              <1> RDT_NOT_PRESENT:
  4469 00002C99 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4470 00002C9C 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4471 00002C9F 6689C2              <1> 	MOV	DX,AX
  4472 00002CA2 EBED                <1> 	JMP	short RDT2
  4473                              <1> 
  4474                              <1> ; 28/05/2016
  4475                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  4476                              <1> 
  4477                              <1> ;----------------------------------------
  4478                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  4479                              <1> ;----------------------------------------
  4480                              <1> 
  4481                              <1> GET_PARM_N:
  4482                              <1> 	; ebx = user's buffer address for parameters table
  4483                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  4484 00002CA4 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4485 00002CA5 06                  <1> 	PUSH	ES
  4486 00002CA6 53                  <1> 	PUSH	eBX
  4487                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  4488                              <1> 	;MOV	DS,AX
  4489                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  4490                              <1> 	;JZ	short G0
  4491                              <1> 	;LES	BX,@HF1_TBL_VEC
  4492                              <1> 	;JMP	SHORT G1
  4493                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  4494                              <1> ;G1:
  4495                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  4496                              <1> 	; 22/12/2014
  4497                              <1> 	;push	cs
  4498                              <1> 	;pop	ds
  4499 00002CA7 66BB1000            <1> 	mov	bx, KDATA
  4500 00002CAB 8EDB                <1> 	mov	ds, bx
  4501 00002CAD 8EC3                <1> 	mov	es, bx	; 27/05/2016
  4502                              <1> 	;
  4503 00002CAF 80EA80              <1> 	SUB	DL,80H
  4504 00002CB2 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4505 00002CB5 7361                <1> 	JAE	short G4
  4506                              <1> 	;
  4507 00002CB7 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4508                              <1> 	; 22/12/2014
  4509 00002CB9 88D3                <1> 	mov	bl, dl
  4510                              <1> 	;xor	bh, bh  
  4511 00002CBB C0E302              <1> 	shl	bl, 2			; convert index to offset
  4512                              <1> 	;add	bx, HF_TBL_VEC
  4513 00002CBE 81C3[28D30000]      <1> 	add	ebx, HF_TBL_VEC
  4514                              <1> 	;mov	ax, [bx+2]
  4515                              <1> 	;mov	es, ax			; dpt segment
  4516                              <1> 	;mov	bx, [bx]		; dpt offset
  4517 00002CC4 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4518                              <1> 
  4519 00002CC6 C605[25D30000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4520                              <1>         ;MOV     AX,[ES:BX]             ; MAX NUMBER OF CYLINDERS
  4521 00002CCD 668B03              <1> 	mov	ax, [ebx]
  4522                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4523 00002CD0 6648                <1> 	dec	ax			; max. cylinder number
  4524 00002CD2 88C5                <1> 	MOV	CH,AL
  4525 00002CD4 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4526 00002CD8 66D1E8              <1> 	SHR	AX,1
  4527 00002CDB 66D1E8              <1> 	SHR	AX,1
  4528                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4529 00002CDE 0A430E              <1> 	or	al, [ebx+14]
  4530 00002CE1 88C1                <1> 	MOV	CL,AL
  4531                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4532 00002CE3 8A7302              <1> 	mov	dh, [ebx+2]
  4533 00002CE6 FECE                <1> 	DEC	DH			; 0-N RANGE
  4534 00002CE8 8A15[26D30000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4535 00002CEE 6629C0              <1> 	SUB	AX,AX
  4536                              <1>         ;27/12/2014 
  4537                              <1> 	;mov	di, bx			; HDPT offset
  4538                              <1> 	
  4539                              <1> 	; 27/05/2016
  4540                              <1> 	; return fixed disk parameters table to user
  4541                              <1> 	; in user's buffer, which is pointed by EBX
  4542                              <1> 	;
  4543 00002CF1 873C24              <1> 	xchg	edi, [esp]		; ebx (input)-> edi, edi -> [esp]
  4544 00002CF4 56                  <1> 	push	esi
  4545 00002CF5 89DE                <1> 	mov	esi, ebx		; hard disk parameter table (32 bytes)	
  4546 00002CF7 89FB                <1> 	mov	ebx, edi		; ebx = user's buffer address
  4547 00002CF9 51                  <1> 	push	ecx
  4548 00002CFA 50                  <1> 	push	eax
  4549 00002CFB B920000000          <1> 	mov	ecx, 32 ; 32 bytes
  4550 00002D00 E855900000          <1> 	call	transfer_to_user_buffer ; trdosk6.s (16/05/2016)
  4551 00002D05 58                  <1> 	pop	eax
  4552 00002D06 59                  <1> 	pop	ecx
  4553 00002D07 5E                  <1> 	pop	esi
  4554 00002D08 5F                  <1> 	pop	edi
  4555 00002D09 730A                <1> 	jnc	short G5
  4556                              <1> 	; 29/05/2016 (*)
  4557 00002D0B B8FF000000          <1> 	mov	eax, 0FFh ; unknown error !
  4558                              <1> _G6:
  4559 00002D10 804C241001          <1> 	or	byte [esp+16], 1 ; set carry bit of eflags register
  4560                              <1> G5:
  4561                              <1> 	; 27/05/2016
  4562                              <1> 	;POP	eBX			; RESTORE REGISTERS
  4563 00002D15 07                  <1> 	POP	ES
  4564 00002D16 1F                  <1> 	POP	DS
  4565                              <1> 	;RETf	2
  4566                              <1> 	; (*) 29/05/2016
  4567                              <1> 	; (*) retf 4
  4568                              <1> 	; (*) or byte [esp+8], 1 ; set carry bit of eflags register
  4569 00002D17 CF                  <1> 	iretd
  4570                              <1> G4:
  4571 00002D18 C605[25D30000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4572 00002D1F B407                <1> 	MOV	AH,INIT_FAIL
  4573 00002D21 28C0                <1> 	SUB	AL,AL
  4574 00002D23 6629D2              <1> 	SUB	DX,DX
  4575 00002D26 6629C9              <1> 	SUB	CX,CX
  4576                              <1> 	; 29/05/2016 (*)
  4577                              <1> 	;STC				; SET ERROR FLAG
  4578                              <1> 	;JMP	short G5
  4579 00002D29 EBE5                <1> 	jmp	short _G6
  4580                              <1> 
  4581                              <1> ;----------------------------------------
  4582                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  4583                              <1> ;----------------------------------------
  4584                              <1> 	; 03/01/2015
  4585                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  4586                              <1> 	; logical sector per logical track
  4587                              <1> 	; and logical heads - 1 would be set but
  4588                              <1> 	; it is seen as it will be good
  4589                              <1> 	; if physical parameters will be set here
  4590                              <1> 	; because, number of heads <= 16.
  4591                              <1> 	; (logical heads usually more than 16)
  4592                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  4593                              <1> 	;	== INT 13h physical parameters
  4594                              <1> 
  4595                              <1> ;INIT_DRV:
  4596                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  4597                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  4598                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  4599                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  4600                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  4601                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  4602                              <1> ;	OR	AH,AL			; TO MAX HEAD
  4603                              <1> ;	MOV	[CMD_BLOCK+5],AH
  4604                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  4605                              <1> ;	MOV	[CMD_BLOCK+1],AL
  4606                              <1> ;	SUB	AX,AX
  4607                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  4608                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  4609                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  4610                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  4611                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  4612                              <1> ;	CALL	CHECK_STATUS
  4613                              <1> ;INIT_EXIT:
  4614                              <1> ;	RETn
  4615                              <1> 
  4616                              <1> ; 04/01/2015
  4617                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  4618                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  4619                              <1> INIT_DRV:
  4620                              <1> 	;xor	ah,ah
  4621 00002D2B 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4622 00002D2D B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4623 00002D2F 3825[38D30000]      <1>         cmp     [LBAMode], ah   ; 0
  4624 00002D35 7702                <1> 	ja	short idrv0
  4625 00002D37 B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4626                              <1> idrv0:
  4627                              <1> 	; DL = drive number (0 based)
  4628 00002D39 E8C6030000          <1> 	call	GET_VEC
  4629                              <1> 	;push	bx
  4630 00002D3E 53                  <1> 	push	ebx ; 21/02/2015
  4631                              <1> 	;add	bx,ax
  4632 00002D3F 01C3                <1> 	add	ebx, eax
  4633                              <1> 	;; 05/01/2015
  4634 00002D41 8A25[88CD0000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4635                              <1> 	;;and 	ah,1 
  4636 00002D47 C0E404              <1> 	shl	ah,4
  4637 00002D4A 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4638                              <1> 	;mov	al,[es:bx]
  4639 00002D4D 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4640 00002D4F FEC8                <1> 	dec	al	 ; last head number 
  4641                              <1> 	;and	al,0Fh
  4642 00002D51 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4643                              <1> 	;
  4644 00002D53 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4645 00002D57 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4646                              <1> 	;pop	bx
  4647 00002D5A 5B                  <1> 	pop	ebx
  4648 00002D5B 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4649 00002D5D B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4650 00002D5F 803D[38D30000]00    <1> 	cmp	byte [LBAMode], 0
  4651 00002D66 7702                <1> 	ja	short idrv1
  4652 00002D68 B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  4653                              <1> idrv1:
  4654                              <1> 	;xor	ah,ah
  4655                              <1> 	;add	bx,ax
  4656 00002D6A 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4657                              <1> 	;mov	al,[es:bx]
  4658                              <1> 			; sector number
  4659 00002D6C 8A03                <1> 	mov	al, [ebx]
  4660 00002D6E 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4661 00002D71 28C0                <1> 	sub	al,al
  4662 00002D73 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4663 00002D76 E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4664 00002D7B 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4665 00002D7D E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4666 00002D82 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4667 00002D84 E8C9020000          <1> 	call	CHECK_STATUS
  4668                              <1> INIT_EXIT:
  4669 00002D89 C3                  <1> 	RETn
  4670                              <1> 
  4671                              <1> ;----------------------------------------
  4672                              <1> ;	READ LONG	     (AH = 0AH) :
  4673                              <1> ;----------------------------------------
  4674                              <1> 
  4675                              <1> RD_LONG:
  4676                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  4677 00002D8A C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4678 00002D8E E9E0000000          <1>         JMP     COMMANDI
  4679                              <1> 
  4680                              <1> ;----------------------------------------
  4681                              <1> ;	WRITE LONG	     (AH = 0BH) :
  4682                              <1> ;----------------------------------------
  4683                              <1> 
  4684                              <1> WR_LONG:
  4685                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  4686 00002D93 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4687 00002D97 E932010000          <1>         JMP     COMMANDO
  4688                              <1> 
  4689                              <1> ;----------------------------------------
  4690                              <1> ;	SEEK		     (AH = 0CH) :
  4691                              <1> ;----------------------------------------
  4692                              <1> 
  4693                              <1> DISK_SEEK:
  4694 00002D9C C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4695 00002DA0 E8A0010000          <1> 	CALL	COMMAND
  4696 00002DA5 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4697 00002DA7 E812020000          <1> 	CALL	_WAIT
  4698 00002DAC 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4699 00002DAE E89F020000          <1> 	CALL	CHECK_STATUS
  4700 00002DB3 803D[25D30000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4701 00002DBA 7507                <1> 	JNE	short DS_EXIT
  4702 00002DBC C605[25D30000]00    <1>         MOV     byte [DISK_STATUS1],0
  4703                              <1> DS_EXIT:
  4704 00002DC3 C3                  <1> 	RETn
  4705                              <1> 
  4706                              <1> ;----------------------------------------
  4707                              <1> ;	TEST DISK READY      (AH = 10H) :
  4708                              <1> ;----------------------------------------
  4709                              <1> 
  4710                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  4711 00002DC4 E831020000          <1> 	CALL	NOT_BUSY
  4712 00002DC9 751C                <1> 	JNZ	short TR_EX
  4713 00002DCB 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4714 00002DCE 668B15[84CD0000]    <1> 	MOV	DX,[HF_PORT]
  4715 00002DD5 80C206              <1> 	add	dl,6
  4716 00002DD8 EE                  <1> 	OUT	DX,AL
  4717 00002DD9 E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4718 00002DDE 7507                <1> 	JNZ	short TR_EX
  4719 00002DE0 C605[25D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4720                              <1> TR_EX:	
  4721 00002DE7 C3                  <1> 	RETn
  4722                              <1> 
  4723                              <1> ;----------------------------------------
  4724                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4725                              <1> ;----------------------------------------
  4726                              <1> 
  4727                              <1> HDISK_RECAL:
  4728 00002DE8 C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4729 00002DEC E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4730 00002DF1 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4731 00002DF3 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4732 00002DF8 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4733 00002DFA E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4734 00002DFF 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4735                              <1> RECAL_X:
  4736 00002E01 E84C020000          <1> 	CALL	CHECK_STATUS
  4737 00002E06 803D[25D30000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4738 00002E0D 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4739 00002E0F C605[25D30000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4740                              <1> RECAL_EXIT:
  4741 00002E16 803D[25D30000]00    <1>         CMP     byte [DISK_STATUS1],0
  4742 00002E1D C3                  <1> 	RETn
  4743                              <1> 
  4744                              <1> ;----------------------------------------
  4745                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4746                              <1> ;----------------------------------------
  4747                              <1> 
  4748                              <1> CTLR_DIAGNOSTIC:
  4749 00002E1E FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4750 00002E1F E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4751                              <1> 	;AND	AL,0BFH
  4752 00002E21 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4753                              <1> 	;JMP	$+2
  4754                              <1> 	IODELAY
  4754 00002E23 EB00                <2>  jmp short $+2
  4754 00002E25 EB00                <2>  jmp short $+2
  4755 00002E27 E6A1                <1> 	OUT	INTB01,AL
  4756                              <1> 	IODELAY
  4756 00002E29 EB00                <2>  jmp short $+2
  4756 00002E2B EB00                <2>  jmp short $+2
  4757 00002E2D E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4758 00002E2F 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4759                              <1> 	;JMP	$+2
  4760                              <1> 	IODELAY
  4760 00002E31 EB00                <2>  jmp short $+2
  4760 00002E33 EB00                <2>  jmp short $+2
  4761 00002E35 E621                <1> 	OUT	INTA01,AL
  4762 00002E37 FB                  <1> 	STI
  4763 00002E38 E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4764 00002E3D 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4765                              <1> 	;MOV	DX, HF_PORT+7
  4766 00002E3F 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4767 00002E46 80C207              <1> 	add	dl, 7
  4768 00002E49 B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4769 00002E4B EE                  <1> 	OUT	DX,AL
  4770 00002E4C E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4771 00002E51 B480                <1> 	MOV	AH,TIME_OUT
  4772 00002E53 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4773                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4774 00002E55 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4775 00002E5C FEC2                <1> 	inc	dl
  4776 00002E5E EC                  <1> 	IN	AL,DX
  4777 00002E5F A2[1CD30000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4778 00002E64 B400                <1> 	MOV	AH,0
  4779 00002E66 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4780 00002E68 7402                <1> 	JE	SHORT CD_EXIT
  4781 00002E6A B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4782                              <1> CD_EXIT:
  4783 00002E6C 8825[25D30000]      <1> 	MOV	[DISK_STATUS1],AH
  4784 00002E72 C3                  <1> 	RETn
  4785                              <1> 
  4786                              <1> ;----------------------------------------
  4787                              <1> ; COMMANDI				:
  4788                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  4789                              <1> ;	NSECTOR RETURNS ZERO		:
  4790                              <1> ;----------------------------------------
  4791                              <1> COMMANDI:
  4792 00002E73 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4793 00002E78 7253                <1> 	JC	short CMD_ABORT
  4794                              <1> 	;MOV	DI,BX
  4795 00002E7A 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4796 00002E7C E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4797 00002E81 754A                <1> 	JNZ	short CMD_ABORT
  4798                              <1> CMD_I1:
  4799 00002E83 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4800 00002E88 7543                <1> 	JNZ	short TM_OUT		; TIME OUT
  4801                              <1> cmd_i1x: ; 18/02/2016
  4802                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  4803 00002E8A B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4804                              <1> 	;MOV	DX,HF_PORT
  4805 00002E8F 668B15[84CD0000]    <1> 	mov	dx,[HF_PORT]
  4806 00002E96 FA                  <1> 	CLI
  4807 00002E97 FC                  <1> 	CLD
  4808 00002E98 F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4809 00002E9B FB                  <1> 	STI
  4810 00002E9C F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4811 00002EA0 7419                <1> 	JZ	short CMD_I3
  4812 00002EA2 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4813 00002EA7 7224                <1> 	JC	short TM_OUT
  4814                              <1> 	;MOV	DX,HF_PORT
  4815 00002EA9 668B15[84CD0000]    <1> 	mov	dx,[HF_PORT]
  4816                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4817 00002EB0 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4818 00002EB5 EC                  <1> CMD_I2: IN	AL,DX
  4819                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4820 00002EB6 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4821 00002EB8 47                  <1> 	INC	eDI
  4822 00002EB9 E2FA                <1> 	LOOP	CMD_I2
  4823                              <1> CMD_I3: 
  4824                              <1> 	; wait for 400 ns
  4825 00002EBB 80C207              <1> 	add 	dl, 7
  4826 00002EBE EC                  <1> 	in	al, dx
  4827 00002EBF EC                  <1> 	in	al, dx
  4828 00002EC0 EC                  <1> 	in	al, dx
  4829                              <1> 	;
  4830 00002EC1 E88C010000          <1> 	CALL	CHECK_STATUS
  4831 00002EC6 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4832 00002EC8 FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4833                              <1> 	;JNZ	SHORT CMD_I1
  4834 00002ECB 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4835                              <1> CMD_ABORT:
  4836 00002ECD C3                  <1> TM_OUT: RETn
  4837                              <1> 
  4838                              <1> ;----------------------------------------
  4839                              <1> ; COMMANDO				:
  4840                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  4841                              <1> ;	NSECTOR RETURNS ZERO		:
  4842                              <1> ;----------------------------------------
  4843                              <1> COMMANDO:
  4844 00002ECE E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4845 00002ED3 72F8                <1> 	JC	short CMD_ABORT
  4846 00002ED5 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4847 00002ED7 E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4848 00002EDC 75EF                <1> 	JNZ	short CMD_ABORT
  4849 00002EDE E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4850 00002EE3 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  4851                              <1> CMD_O1: ;PUSH	DS
  4852                              <1> 	;PUSH	ES			; MOVE ES TO DS
  4853                              <1> 	;POP	DS
  4854                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  4855                              <1> 	;MOV	DX,HF_PORT
  4856                              <1> 	; 01/02/2015
  4857 00002EE5 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4858                              <1> 	;push	es
  4859                              <1> 	;pop	ds
  4860                              <1> 	;mov	cx, 256
  4861 00002EEC B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4862 00002EF1 FA                  <1> 	CLI
  4863 00002EF2 FC                  <1> 	CLD
  4864 00002EF3 F3666F              <1> 	REP	OUTSW
  4865 00002EF6 FB                  <1> 	STI
  4866                              <1> 	;POP	DS			; RESTORE DS
  4867 00002EF7 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4868 00002EFB 7419                <1> 	JZ	short CMD_O3
  4869 00002EFD E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4870 00002F02 72C9                <1> 	JC	short TM_OUT
  4871                              <1> 	;MOV	DX,HF_PORT
  4872 00002F04 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4873                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4874 00002F0B B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4875                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  4876 00002F10 8A06                <1> 	mov	al, [esi]
  4877 00002F12 EE                  <1> 	OUT	DX,AL
  4878 00002F13 46                  <1> 	INC	eSI
  4879 00002F14 E2FA                <1> 	LOOP	CMD_O2
  4880                              <1> CMD_O3:
  4881 00002F16 E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  4882 00002F1B 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  4883 00002F1D E830010000          <1> 	CALL	CHECK_STATUS
  4884 00002F22 75A9                <1> 	JNZ	short CMD_ABORT
  4885 00002F24 F605[1BD30000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  4886 00002F2B 75B8                <1> 	JNZ	SHORT CMD_O1
  4887                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  4888 00002F2D 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4889                              <1> 	;add	dl, 2
  4890 00002F34 FEC2                <1> 	inc	dl
  4891 00002F36 FEC2                <1> 	inc	dl
  4892 00002F38 EC                  <1> 	IN	AL,DX			;
  4893 00002F39 A8FF                <1> 	TEST	AL,0FFH 		;
  4894 00002F3B 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  4895 00002F3D C605[25D30000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  4896                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  4897                              <1> CMD_O4:
  4898 00002F44 C3                  <1> 	RETn
  4899                              <1> 
  4900                              <1> ;--------------------------------------------------------
  4901                              <1> ; COMMAND						:
  4902                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  4903                              <1> ; OUTPUT						:
  4904                              <1> ;	BL = STATUS					:
  4905                              <1> ;	BH = ERROR REGISTER				:
  4906                              <1> ;--------------------------------------------------------
  4907                              <1> 
  4908                              <1> COMMAND:
  4909 00002F45 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  4910                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  4911                              <1> COMMAND1:
  4912                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  4913 00002F46 E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  4914                              <1> 	;;POP	CX
  4915 00002F4B 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  4916 00002F4D 803D[25D30000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  4917                              <1> 	;JZ	short CMD_TIMEOUT
  4918                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  4919                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  4920 00002F54 7507                <1> 	jne	short COMMAND4
  4921                              <1> CMD_TIMEOUT:
  4922 00002F56 C605[25D30000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4923                              <1> COMMAND4:
  4924 00002F5D 5B                  <1> 	POP	eBX
  4925 00002F5E 803D[25D30000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  4926 00002F65 C3                  <1> 	RETn
  4927                              <1> COMMAND2:
  4928 00002F66 5B                  <1> 	POP	eBX
  4929 00002F67 57                  <1> 	PUSH	eDI
  4930 00002F68 C605[1DD30000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  4931 00002F6F FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  4932 00002F70 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4933                              <1> 	;AND	AL,0BFH
  4934 00002F72 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  4935                              <1> 	;JMP	$+2
  4936                              <1> 	IODELAY
  4936 00002F74 EB00                <2>  jmp short $+2
  4936 00002F76 EB00                <2>  jmp short $+2
  4937 00002F78 E6A1                <1> 	OUT	INTB01,AL
  4938 00002F7A E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4939 00002F7C 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4940                              <1> 	;JMP	$+2
  4941                              <1> 	IODELAY
  4941 00002F7E EB00                <2>  jmp short $+2
  4941 00002F80 EB00                <2>  jmp short $+2
  4942 00002F82 E621                <1> 	OUT	INTA01,AL
  4943 00002F84 FB                  <1> 	STI
  4944 00002F85 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  4945                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  4946 00002F87 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  4947 00002F8E FEC2                <1> 	inc	dl
  4948 00002F90 F605[27D30000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  4949 00002F97 7411                <1> 	JZ	short COMMAND3
  4950 00002F99 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  4951 00002F9C 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  4952 00002F9E 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  4953 00002FA0 7208                <1> 	JB	short COMMAND3
  4954 00002FA2 3C40                <1> 	CMP	AL,40H
  4955 00002FA4 7704                <1> 	JA	short COMMAND3
  4956 00002FA6 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  4957                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  4958                              <1> COMMAND3:
  4959 00002FAA 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  4960 00002FAE EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  4961                              <1> 	IODELAY
  4961 00002FAF EB00                <2>  jmp short $+2
  4961 00002FB1 EB00                <2>  jmp short $+2
  4962 00002FB3 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  4963 00002FB4 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  4964 00002FB6 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  4965 00002FBA 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  4966 00002FBC 5F                  <1> 	POP	eDI
  4967 00002FBD C3                  <1> 	RETn				; ZERO FLAG IS SET
  4968                              <1> 
  4969                              <1> ;CMD_TIMEOUT:
  4970                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4971                              <1> ;COMMAND4:
  4972                              <1> ;	POP	BX
  4973                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4974                              <1> ;	RETn
  4975                              <1> 
  4976                              <1> ;----------------------------------------
  4977                              <1> ;	WAIT FOR INTERRUPT		:
  4978                              <1> ;----------------------------------------
  4979                              <1> ;WAIT:
  4980                              <1> _WAIT:
  4981 00002FBE FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4982                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4983                              <1> 	;CLC
  4984                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  4985                              <1> 	;INT	15H
  4986                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  4987                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  4988                              <1> 
  4989                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  4990                              <1> 	;; 21/02/2015
  4991                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  4992                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  4993 00002FBF B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  4994                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  4995                              <1> ;-----	WAIT LOOP
  4996                              <1> 
  4997                              <1> WT1:	
  4998                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  4999 00002FC4 F605[1DD30000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  5000                              <1> 	;LOOPZ	WT1
  5001 00002FCB 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  5002                              <1> 	;DEC	BL
  5003                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  5004                              <1> 
  5005                              <1> WT1_hi:
  5006 00002FCD E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  5007 00002FCF A810                <1> 	test	al, 10h			; transition on memory
  5008 00002FD1 75FA                <1> 	jnz	short WT1_hi		; refresh.
  5009                              <1> WT1_lo:
  5010 00002FD3 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  5011 00002FD5 A810                <1> 	test	al, 10h			
  5012 00002FD7 74FA                <1> 	jz	short WT1_lo
  5013 00002FD9 E2E9                <1> 	loop	WT1
  5014                              <1> 	;;or	bl, bl
  5015                              <1> 	;;jz	short WT2	
  5016                              <1> 	;;dec	bl
  5017                              <1> 	;;jmp	short WT1
  5018                              <1> 	;dec	bl
  5019                              <1> 	;jnz	short WT1	
  5020                              <1> 
  5021 00002FDB C605[25D30000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  5022 00002FE2 EB0E                <1> 	JMP	SHORT WT4
  5023 00002FE4 C605[25D30000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  5024 00002FEB C605[1DD30000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  5025 00002FF2 803D[25D30000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5026 00002FF9 C3                  <1> 	RETn
  5027                              <1> 
  5028                              <1> ;----------------------------------------
  5029                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  5030                              <1> ;----------------------------------------
  5031                              <1> NOT_BUSY:
  5032 00002FFA FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  5033                              <1> 	;PUSH	eBX
  5034                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  5035 00002FFB 668B15[84CD0000]    <1> 	mov	DX, [HF_PORT]
  5036 00003002 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  5037                              <1> 	;MOV	BL,DELAY_1
  5038                              <1> 					; wait for 10 seconds
  5039                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  5040                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  5041                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  5042 00003005 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  5043                              <1> 	;
  5044                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  5045                              <1> NB1:	
  5046 0000300A EC                  <1> 	IN	AL,DX			; CHECK STATUS
  5047                              <1> 	;TEST	AL,ST_BUSY
  5048 0000300B 2480                <1> 	and	al, ST_BUSY
  5049                              <1> 	;LOOPNZ	NB1
  5050 0000300D 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  5051                              <1> 	;DEC	BL			
  5052                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  5053                              <1> 
  5054 0000300F E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  5055 00003011 A810                <1> 	TEST	AL,010H			; transition on memory
  5056 00003013 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  5057 00003015 E461                <1> NB1_lo: IN	AL,SYS1
  5058 00003017 A810                <1> 	TEST	AL,010H
  5059 00003019 74FA                <1> 	JZ	short NB1_lo
  5060 0000301B E2ED                <1> 	LOOP	NB1
  5061                              <1> 	;dec	bl
  5062                              <1> 	;jnz	short NB1
  5063                              <1> 	;
  5064                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  5065                              <1> ;;	jb	short NB1
  5066                              <1> 	;
  5067                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  5068                              <1> 	;JMP	SHORT NB3
  5069 0000301D B080                <1> 	mov	al, TIME_OUT
  5070                              <1> NB2:	
  5071                              <1> 	;MOV	byte [DISK_STATUS1],0
  5072                              <1> ;NB3:	
  5073                              <1> 	;POP	eBX
  5074 0000301F A2[25D30000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  5075                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5076 00003024 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  5077 00003026 C3                  <1> 	RETn
  5078                              <1> 
  5079                              <1> ;----------------------------------------
  5080                              <1> ;	WAIT FOR DATA REQUEST		:
  5081                              <1> ;----------------------------------------
  5082                              <1> WAIT_DRQ:
  5083                              <1> 	;MOV	CX,DELAY_3
  5084                              <1> 	;MOV	DX,HF_PORT+7
  5085 00003027 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  5086 0000302E 80C207              <1> 	add	dl, 7
  5087                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  5088                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  5089                              <1> 					; (but it is written as 2000
  5090                              <1> 					; micro seconds in ATORGS.ASM file
  5091                              <1> 					; of Award Bios - 1999, D1A0622)
  5092 00003031 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  5093 00003036 EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  5094 00003037 A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  5095 00003039 7516                <1> 	JNZ	short WQ_OK
  5096                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  5097                              <1> WQ_hi:	
  5098 0000303B E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  5099 0000303D A810                <1> 	TEST	AL,010H			; transition on memory
  5100 0000303F 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  5101 00003041 E461                <1> WQ_lo:  IN      AL,SYS1
  5102 00003043 A810                <1> 	TEST	AL,010H
  5103 00003045 74FA                <1> 	JZ	SHORT WQ_lo
  5104 00003047 E2ED                <1> 	LOOP	WQ_1
  5105                              <1> 
  5106 00003049 C605[25D30000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  5107 00003050 F9                  <1> 	STC
  5108                              <1> WQ_OK:
  5109 00003051 C3                  <1> 	RETn
  5110                              <1> ;WQ_OK:	;CLC
  5111                              <1> ;	RETn
  5112                              <1> 
  5113                              <1> ;----------------------------------------
  5114                              <1> ;	CHECK FIXED DISK STATUS 	:
  5115                              <1> ;----------------------------------------
  5116                              <1> CHECK_STATUS:
  5117 00003052 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  5118 00003057 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  5119 00003059 A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  5120 0000305B 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  5121 0000305D E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  5122                              <1> CHECK_S1:
  5123 00003062 803D[25D30000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  5124 00003069 C3                  <1> 	RETn
  5125                              <1> 
  5126                              <1> ;----------------------------------------
  5127                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  5128                              <1> ;----------------------------------------
  5129                              <1> CHECK_ST:
  5130                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  5131 0000306A 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]
  5132 00003071 80C207              <1> 	add	dl, 7
  5133                              <1> 	
  5134                              <1> 	; 17/02/2016
  5135                              <1> 	;(http://wiki.osdev.org/ATA_PIO_Mode)
  5136                              <1> 	;"delay 400ns to allow drive to set new values of BSY and DRQ"
  5137 00003074 EC                  <1> 	IN	AL,DX
  5138                              <1> 	;in	al, dx ; 100ns
  5139                              <1> 	;in	al, dx ; 100ns
  5140                              <1>  	;in	al, dx ; 100ns
  5141                              <1> 	NEWIODELAY ; 18/02/2016 (AWARD BIOS - 1999, 'CKST' in AHSDK.ASM)
  5141 00003075 E6EB                <2>  out 0ebh,al
  5142                              <1> 	;
  5143 00003077 A2[1BD30000]        <1> 	MOV	[HF_STATUS],AL
  5144 0000307C B400                <1> 	MOV	AH,0
  5145 0000307E A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  5146 00003080 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  5147 00003082 B4CC                <1> 	MOV	AH,WRITE_FAULT
  5148 00003084 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  5149 00003086 7514                <1> 	JNZ	short CKST_EXIT
  5150 00003088 B4AA                <1> 	MOV	AH,NOT_RDY
  5151 0000308A A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  5152 0000308C 740E                <1> 	JZ	short CKST_EXIT
  5153 0000308E B440                <1> 	MOV	AH,BAD_SEEK
  5154 00003090 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  5155 00003092 7408                <1> 	JZ	short CKST_EXIT
  5156 00003094 B411                <1> 	MOV	AH,DATA_CORRECTED
  5157 00003096 A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  5158 00003098 7502                <1> 	JNZ	short CKST_EXIT
  5159 0000309A B400                <1> 	MOV	AH,0
  5160                              <1> CKST_EXIT:
  5161 0000309C 8825[25D30000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  5162 000030A2 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  5163 000030A5 7403                <1> 	JZ	short CKST_EX1
  5164 000030A7 80FC00              <1> 	CMP	AH,0
  5165                              <1> CKST_EX1:
  5166 000030AA C3                  <1> 	RETn
  5167                              <1> 
  5168                              <1> ;----------------------------------------
  5169                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  5170                              <1> ;----------------------------------------
  5171                              <1> CHECK_ER:
  5172                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  5173 000030AB 668B15[84CD0000]    <1> 	mov	dx, [HF_PORT]		;
  5174 000030B2 FEC2                <1> 	inc	dl
  5175 000030B4 EC                  <1> 	IN	AL,DX
  5176 000030B5 A2[1CD30000]        <1> 	MOV	[HF_ERROR],AL
  5177 000030BA 53                  <1> 	PUSH	eBX ; 21/02/2015
  5178 000030BB B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  5179 000030C0 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  5180 000030C2 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  5181 000030C4 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  5182 000030C6 BB[78CD0000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  5183 000030CB 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  5184                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  5185                              <1> 	;mov	ah, [bx]
  5186 000030CD 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  5187 000030CF 8825[25D30000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  5188 000030D5 5B                  <1> 	POP	eBX
  5189 000030D6 80FC00              <1> 	CMP	AH,0
  5190 000030D9 C3                  <1> 	RETn
  5191                              <1> 
  5192                              <1> ;--------------------------------------------------------
  5193                              <1> ; CHECK_DMA						:
  5194                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  5195                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  5196                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  5197                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  5198                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  5199                              <1> ;  -ERROR OTHERWISE					:
  5200                              <1> ;--------------------------------------------------------
  5201                              <1> CHECK_DMA:
  5202 000030DA 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  5203 000030DC 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  5204 000030E0 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  5205 000030E4 7404                <1> 	JZ	short CKD1
  5206 000030E6 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  5207 000030EA 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  5208 000030ED 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  5209 000030EF 7208                <1> 	JB	short CKDERR		; TOO MANY
  5210 000030F1 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  5211 000030F3 7204                <1> 	JB	short CKDERR		; ERROR
  5212 000030F5 F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  5213 000030F6 6658                <1> 	POP	AX
  5214 000030F8 C3                  <1> 	RETn				; NORMAL RETURN
  5215 000030F9 F9                  <1> CKDERR: STC				; INDICATE ERROR
  5216 000030FA C605[25D30000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  5217 00003101 6658                <1> 	POP	AX
  5218 00003103 C3                  <1> 	RETn
  5219                              <1> 
  5220                              <1> ;----------------------------------------
  5221                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  5222                              <1> ;----------------------------------------
  5223                              <1> 					
  5224                              <1> ; INPUT -> DL = 0 based drive number
  5225                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  5226                              <1> 
  5227                              <1> GET_VEC:
  5228                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  5229                              <1> 	;MOV	ES,AX
  5230                              <1> 	;TEST	DL,1
  5231                              <1> 	;JZ	short GV_0
  5232                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  5233                              <1> ;	JMP	SHORT GV_EXIT
  5234                              <1> ;GV_0:
  5235                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  5236                              <1> ;
  5237                              <1> 	;xor	bh, bh
  5238 00003104 31DB                <1> 	xor	ebx, ebx
  5239 00003106 88D3                <1> 	mov	bl, dl
  5240                              <1> 	;;02/01/2015
  5241                              <1> 	;;shl	bl, 1			; port address offset
  5242                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  5243                              <1> 	;;shl	bl, 1			; dpt pointer offset
  5244 00003108 C0E302              <1> 	shl	bl, 2	;;
  5245                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  5246 0000310B 81C3[28D30000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  5247                              <1> 	;push	word [bx+2]		; dpt segment
  5248                              <1> 	;pop	es
  5249                              <1> 	;mov	bx, [bx]		; dpt offset
  5250 00003111 8B1B                <1> 	mov	ebx, [ebx]		
  5251                              <1> ;GV_EXIT:
  5252 00003113 C3                  <1> 	RETn
  5253                              <1> 
  5254                              <1> hdc1_int: ; 21/02/2015
  5255                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  5256                              <1> ;								:
  5257                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5258                              <1> ;								:
  5259                              <1> ;----------------------------------------------------------------
  5260                              <1> 
  5261                              <1> ; 22/12/2014
  5262                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  5263                              <1> ;	 '11/15/85'
  5264                              <1> ; AWARD BIOS 1999 (D1A0622) 
  5265                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  5266                              <1> 
  5267                              <1> ;int_76h:
  5268                              <1> HD_INT:
  5269 00003114 6650                <1> 	PUSH	AX
  5270 00003116 1E                  <1> 	PUSH	DS
  5271                              <1> 	;CALL	DDS
  5272                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5273 00003117 66B81000            <1> 	mov	ax, KDATA
  5274 0000311B 8ED8                <1> 	mov 	ds, ax
  5275                              <1> 	;
  5276                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5277                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  5278 0000311D C605[1DD30000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5279                              <1> 	;
  5280 00003124 6652                <1> 	push	dx
  5281 00003126 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5282                              <1> 					; Clear Controller
  5283                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5284 0000312A EC                  <1> 	in	al, dx			;
  5285 0000312B 665A                <1> 	pop	dx
  5286                              <1> 	NEWIODELAY
  5286 0000312D E6EB                <2>  out 0ebh,al
  5287                              <1> 	;
  5288 0000312F B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5289 00003131 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5290                              <1> 	;JMP	$+2			; WAIT
  5291                              <1> 	NEWIODELAY
  5291 00003133 E6EB                <2>  out 0ebh,al
  5292 00003135 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5293 00003137 1F                  <1> 	POP	DS
  5294                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  5295                              <1> 	;MOV	AX,9100H		; DEVICE POST
  5296                              <1> 	;INT	15H			;  INTERRUPT
  5297                              <1> irq15_iret: ; 25/02/2015
  5298 00003138 6658                <1> 	POP	AX
  5299 0000313A CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  5300                              <1> 
  5301                              <1> hdc2_int: ; 21/02/2015
  5302                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  5303                              <1> ;								:
  5304                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5305                              <1> ;								:
  5306                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5307                              <1> 
  5308                              <1> ;int_77h:
  5309                              <1> HD1_INT:
  5310 0000313B 6650                <1> 	PUSH	AX
  5311                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  5312                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  5313 0000313D B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5314 0000313F E6A0                <1> 	out	0A0h, al
  5315 00003141 EB00                <1>         jmp short $+2
  5316 00003143 EB00                <1> 	jmp short $+2
  5317 00003145 E4A0                <1> 	in	al, 0A0h
  5318 00003147 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5319 00003149 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5320                              <1> 	;
  5321 0000314B 1E                  <1> 	PUSH	DS
  5322                              <1> 	;CALL	DDS
  5323                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5324 0000314C 66B81000            <1> 	mov	ax, KDATA
  5325 00003150 8ED8                <1> 	mov 	ds, ax
  5326                              <1> 	;
  5327                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5328                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  5329 00003152 800D[1DD30000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5330                              <1> 	;
  5331 00003159 6652                <1> 	push	dx
  5332 0000315B 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5333                              <1> 					; Clear Controller (Award BIOS 1999)
  5334 0000315F EBC9                <1> 	jmp	short Clear_IRQ1415
  5335                              <1> 
  5336                              <1> 
  5337                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  5338                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  5339                              <1> 
  5340                              <1> 
  5341                              <1> ;////////////////////////////////////////////////////////////////////
  5342                              <1> ;; END OF DISK I/O SYTEM ///
  1873                                  %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: 27/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> ; 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 00003161 A1[90D20000]        <1> 	mov	eax, [free_pages]
   328 00003166 21C0                <1> 	and	eax, eax
   329 00003168 7438                <1> 	jz	short out_of_memory
   330                              <1> 	;
   331 0000316A 53                  <1> 	push	ebx
   332 0000316B 51                  <1> 	push	ecx
   333                              <1> 	;
   334 0000316C BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   335 00003171 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 00003173 031D[94D20000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   343                              <1> 				 ; next_free_page >> 5
   344 00003179 030D[98D20000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   345                              <1> 				 ; (total_pages - 1) >> 5
   346                              <1> al_p_scan:
   347 0000317F 39CB                <1> 	cmp	ebx, ecx
   348 00003181 770A                <1> 	ja	short al_p_notfound
   349                              <1> 	;
   350                              <1> 	; 01/07/2015
   351                              <1> 	; AMD64 Architecture Programmer’s 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 00003183 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 00003186 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 00003188 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 0000318B EBF2                <1>         jmp     short al_p_scan
   382                              <1> 	;
   383                              <1> al_p_notfound:
   384 0000318D 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   385 00003193 890D[94D20000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   386                              <1> 				 ; (deallocate_page procedure will change it)
   387 00003199 31C0                <1> 	xor	eax, eax
   388 0000319B A3[90D20000]        <1> 	mov	[free_pages], eax ; 0
   389 000031A0 59                  <1> 	pop	ecx
   390 000031A1 5B                  <1> 	pop	ebx
   391                              <1> 	;
   392                              <1> out_of_memory:
   393 000031A2 E857040000          <1> 	call	swap_out
   394 000031A7 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   395                              <1> 	;
   396 000031A9 29C0                <1> 	sub 	eax, eax ; 0
   397 000031AB F9                  <1> 	stc
   398 000031AC C3                  <1> 	retn
   399                              <1> 
   400                              <1> al_p_found:
   401 000031AD 89D9                <1> 	mov	ecx, ebx
   402 000031AF 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   403 000031B5 890D[94D20000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   404                              <1> 				 ; address/offset (to the next)
   405 000031BB FF0D[90D20000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   406                              <1> 	;
   407 000031C1 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 000031C4 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   415 000031C7 01C8                <1> 	add	eax, ecx	 ; = page number
   416 000031C9 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 000031CC 59                  <1> 	pop	ecx
   422 000031CD 5B                  <1> 	pop	ebx
   423                              <1> al_p_ok:
   424 000031CE 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 000031CF E88DFFFFFF          <1> 	call	allocate_page
   446 000031D4 7216                <1> 	jc	short mkpd_error
   447                              <1> 	;
   448 000031D6 A3[A1E30000]        <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 000031DB 57                  <1> 	push	edi
   462 000031DC 51                  <1> 	push	ecx
   463 000031DD 50                  <1> 	push	eax
   464 000031DE B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   465 000031E3 89C7                <1> 	mov	edi, eax
   466 000031E5 31C0                <1> 	xor	eax, eax
   467 000031E7 F3AB                <1> 	rep	stosd
   468 000031E9 58                  <1> 	pop	eax
   469 000031EA 59                  <1> 	pop	ecx
   470 000031EB 5F                  <1> 	pop	edi
   471                              <1> mkpd_error:
   472                              <1> mkpt_error:
   473 000031EC 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 000031ED E86FFFFFFF          <1> 	call	allocate_page
   497 000031F2 72F8                <1> 	jc	short mkpt_error
   498 000031F4 E811000000          <1> 	call	set_pde	
   499 000031F9 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 000031FB E861FFFFFF          <1> 	call	allocate_page
   520 00003200 7207                <1> 	jc	short mkp_err
   521 00003202 E821000000          <1> 	call	set_pte	
   522 00003207 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   523                              <1> mkp_err:
   524 00003209 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 0000320A 89DA                <1> 	mov	edx, ebx
   550 0000320C C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   551 0000320F C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   552 00003212 0315[A1E30000]      <1> 	add	edx, [u.pgdir]
   553                              <1> 	;
   554 00003218 21C0                <1> 	and	eax, eax
   555 0000321A 7506                <1> 	jnz	short spde_1
   556                              <1> 	;
   557 0000321C 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   558                              <1> 	;test	al, 1
   559                              <1> 	;jz	short spde_2
   560 0000321E 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   561                              <1> spde_1:
   562                              <1> 	;and	cx, 0FFFh
   563 00003222 8902                <1> 	mov	[edx], eax
   564 00003224 66090A              <1> 	or	[edx], cx
   565 00003227 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 00003228 50                  <1> 	push	eax
   596 00003229 A1[A1E30000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   597 0000322E E837000000          <1> 	call 	get_pde
   598                              <1> 		; EDX = PDE address
   599                              <1> 		; EAX = PDE value
   600 00003233 5A                  <1> 	pop	edx ; physical page address
   601 00003234 722A                <1> 	jc	short spte_err ; PDE not present
   602                              <1> 	;
   603 00003236 53                  <1> 	push	ebx ; 24/07/2015
   604 00003237 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   605                              <1> 			    ; EDX = PT address (physical)	
   606 0000323B C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   607 0000323E 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   608                              <1> 			 ; clear higher 10 bits (PD bits)
   609 00003244 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   610 00003247 01C3                <1> 	add	ebx, eax
   611                              <1> 	;
   612 00003249 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   613 0000324B A801                <1> 	test	al, 1
   614 0000324D 740C                <1> 	jz	short spte_0
   615 0000324F 09D2                <1> 	or	edx, edx
   616 00003251 750F                <1> 	jnz	short spte_1
   617 00003253 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   618 00003257 89C2                <1> 	mov	edx, eax
   619 00003259 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 0000325B 21C0                <1> 	and	eax, eax
   625 0000325D 7403                <1> 	jz	short spte_1
   626                              <1> 	; 24/07/2015
   627                              <1> 	; swapped page ! (on disk)
   628 0000325F 5B                  <1> 	pop	ebx
   629                              <1> spte_err:
   630 00003260 F9                  <1> 	stc
   631 00003261 C3                  <1> 	retn
   632                              <1> spte_1: 
   633 00003262 89D0                <1> 	mov	eax, edx
   634                              <1> spte_2:
   635 00003264 09CA                <1> 	or	edx, ecx
   636                              <1> 	; 23/06/2015
   637 00003266 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   638                              <1> 	; 24/07/2015
   639 00003268 5B                  <1> 	pop	ebx
   640 00003269 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 0000326A 89DA                <1> 	mov	edx, ebx
   658 0000326C C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   659 0000326F C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   660 00003272 01C2                <1> 	add	edx, eax ; page directory address (physical)
   661 00003274 8B02                <1> 	mov	eax, [edx]
   662 00003276 A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   663 00003278 751F                <1> 	jnz	short gpte_retn
   664 0000327A F9                  <1> 	stc
   665                              <1> gpde_retn:	
   666 0000327B 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 0000327C E8E9FFFFFF          <1> 	call 	get_pde
   688 00003281 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 00003283 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   693 00003287 89DA                <1> 	mov	edx, ebx
   694 00003289 C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   695 0000328C 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   696                              <1> 			 ; clear higher 10 bits (PD bits)
   697 00003292 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   698 00003295 01C2                <1> 	add	edx, eax
   699 00003297 8B02                <1> 	mov	eax, [edx]
   700                              <1> gpte_retn:
   701 00003299 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 0000329A 56                  <1> 	push	esi
   724 0000329B 51                  <1> 	push	ecx
   725 0000329C 50                  <1> 	push	eax
   726 0000329D 89C6                <1> 	mov	esi, eax 
   727 0000329F 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 000032A1 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   731                              <1> dapd_0:
   732 000032A3 AD                  <1> 	lodsd
   733 000032A4 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   734 000032A6 7409                <1> 	jz	short dapd_1	
   735 000032A8 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   736 000032AC E812000000          <1> 	call	deallocate_page_table			
   737                              <1> dapd_1:
   738 000032B1 41                  <1> 	inc	ecx ; page directory entry index
   739 000032B2 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   740 000032B8 72E9                <1> 	jb	short dapd_0
   741                              <1> dapd_2:
   742 000032BA 58                  <1> 	pop	eax
   743 000032BB E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   744 000032C0 59                  <1> 	pop	ecx
   745 000032C1 5E                  <1> 	pop	esi
   746 000032C2 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 000032C3 56                  <1> 	push	esi
   770 000032C4 57                  <1> 	push	edi
   771 000032C5 52                  <1> 	push	edx
   772 000032C6 50                  <1> 	push	eax ; *
   773 000032C7 89C6                <1> 	mov	esi, eax 
   774 000032C9 31FF                <1> 	xor	edi, edi ; 0
   775                              <1> dapt_0:
   776 000032CB AD                  <1> 	lodsd
   777 000032CC A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   778 000032CE 7441                <1> 	jz	short dapt_1
   779                              <1> 	;
   780 000032D0 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   781                              <1> 				  ; (must be 1)
   782 000032D2 754C                <1> 	jnz	short dapt_3
   783                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   784 000032D4 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   785                              <1> 				   ; as child's page ?
   786 000032D8 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 000032DA 53                  <1> 	push	ebx
   790 000032DB 51                  <1> 	push	ecx
   791 000032DC 66C1E102            <1> 	shl	cx, 2 ; *4 
   792 000032E0 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   793 000032E2 8B0B                <1> 	mov	ecx, [ebx]
   794 000032E4 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   795 000032E7 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   796 000032E9 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   797                              <1> 	; EDI = page table entry index (0-1023)
   798 000032EE 89FA                <1> 	mov	edx, edi 
   799 000032F0 66C1E202            <1> 	shl	dx, 2 ; *4 
   800 000032F4 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   801 000032F6 8B1A                <1> 	mov	ebx, [edx]
   802 000032F8 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   803 000032FB 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   804 000032FD 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   805 00003301 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   806 00003306 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   807 00003308 7514                <1> 	jne	short dapt_2	; not same page
   808                              <1> 				; deallocate the child's page
   809 0000330A 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   810 0000330D 59                  <1> 	pop	ecx
   811 0000330E 5B                  <1> 	pop	ebx
   812 0000330F EB14                <1> 	jmp	short dapt_4
   813                              <1> dapt_1:
   814 00003311 09C0                <1> 	or	eax, eax	; swapped page ?
   815 00003313 7417                <1> 	jz	short dapt_5	; no
   816                              <1> 				; yes
   817 00003315 D1E8                <1> 	shr	eax, 1
   818 00003317 E880040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   819                              <1> 				  ; on the swap disk (or in file)
   820 0000331C EB0E                <1> 	jmp	short dapt_5
   821                              <1> dapt_2:
   822 0000331E 59                  <1> 	pop	ecx
   823 0000331F 5B                  <1> 	pop	ebx
   824                              <1> dapt_3:	
   825                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   826 00003320 E814000000          <1> 	call	deallocate_page
   827                              <1> dapt_4:
   828 00003325 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   829                              <1> dapt_5:
   830 0000332C 47                  <1> 	inc	edi ; page table entry index
   831 0000332D 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   832 00003333 7296                <1> 	jb	short dapt_0
   833                              <1> 	;
   834 00003335 58                  <1> 	pop	eax ; *
   835 00003336 5A                  <1> 	pop	edx
   836 00003337 5F                  <1> 	pop	edi	
   837 00003338 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 00003339 53                  <1> 	push	ebx
   860 0000333A 52                  <1> 	push	edx
   861                              <1> 	;
   862 0000333B C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   863                              <1> 				     ; 12 bits right
   864                              <1> 				     ; to get page number
   865 0000333E 89C2                <1> 	mov	edx, eax
   866                              <1> 	; 15/09/2015
   867 00003340 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 00003343 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   871                              <1> 				     ; (to get 32 bit position)			
   872                              <1> 	;
   873 00003346 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   874 0000334B 01D3                <1> 	add	ebx, edx
   875 0000334D 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   876                              <1> 				     ; (allocation bit position)	 
   877 00003350 3B15[94D20000]      <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 00003356 7306                <1> 	jnb	short dap_1	     ; no	
   881 00003358 8915[94D20000]      <1> 	mov	[next_page], edx     ; yes
   882                              <1> dap_1:
   883 0000335E 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 00003361 FF05[90D20000]      <1>         inc     dword [free_pages]
   891                              <1> dap_2:
   892 00003367 5A                  <1> 	pop	edx
   893 00003368 5B                  <1> 	pop	ebx
   894 00003369 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 0000336A E8F2FDFFFF          <1> 	call	allocate_page
   978 0000336F 723E                <1> 	jc	short dpd_err
   979                              <1> 	;
   980 00003371 55                  <1> 	push	ebp ; 20/07/2015
   981 00003372 56                  <1> 	push	esi
   982 00003373 57                  <1> 	push	edi
   983 00003374 53                  <1> 	push	ebx
   984 00003375 51                  <1> 	push	ecx
   985 00003376 8B35[A1E30000]      <1> 	mov	esi, [u.pgdir]
   986 0000337C 89C7                <1> 	mov	edi, eax
   987 0000337E 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 0000337F A5                  <1> 	movsd
   992 00003380 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
   993 00003385 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
   994                              <1> dpd_0:	
   995 0000338A AD                  <1> 	lodsd
   996                              <1> 	;or	eax, eax
   997                              <1>         ;jnz     short dpd_1
   998 0000338B A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
   999 0000338D 7508                <1> 	jnz	short dpd_1
  1000                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1001 0000338F 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1002 00003395 EB0F                <1> 	jmp	short dpd_2
  1003                              <1> dpd_1:	
  1004 00003397 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1005 0000339B 89C3                <1> 	mov	ebx, eax
  1006                              <1> 	; EBX = Parent's page table address
  1007 0000339D E81F000000          <1> 	call	duplicate_page_table
  1008 000033A2 720C                <1> 	jc	short dpd_p_err
  1009                              <1> 	; EAX = Child's page table address
  1010 000033A4 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 000033A6 AB                  <1> 	stosd
  1015 000033A7 E2E1                <1> 	loop	dpd_0
  1016                              <1> 	;
  1017 000033A9 58                  <1> 	pop	eax  ; restore child's page directory address
  1018                              <1> dpd_3:
  1019 000033AA 59                  <1> 	pop	ecx
  1020 000033AB 5B                  <1> 	pop	ebx
  1021 000033AC 5F                  <1> 	pop	edi
  1022 000033AD 5E                  <1> 	pop	esi
  1023 000033AE 5D                  <1> 	pop	ebp ; 20/07/2015
  1024                              <1> dpd_err:
  1025 000033AF C3                  <1> 	retn
  1026                              <1> dpd_p_err:
  1027                              <1> 	; release the allocated pages missing (recover free space)
  1028 000033B0 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1029 000033B1 8B1D[A1E30000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1030 000033B7 E8DEFEFFFF          <1> 	call 	deallocate_page_dir
  1031 000033BC 29C0                <1> 	sub	eax, eax ; 0
  1032 000033BE F9                  <1> 	stc
  1033 000033BF 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 000033C1 E89BFDFFFF          <1> 	call	allocate_page
  1057 000033C6 726A                <1> 	jc	short dpt_err
  1058                              <1> 	;
  1059 000033C8 50                  <1> 	push	eax ; *
  1060 000033C9 56                  <1> 	push	esi
  1061 000033CA 57                  <1> 	push	edi
  1062 000033CB 52                  <1> 	push	edx
  1063 000033CC 51                  <1> 	push	ecx
  1064                              <1> 	;
  1065 000033CD 89DE                <1> 	mov	esi, ebx
  1066 000033CF 89C7                <1> 	mov	edi, eax
  1067 000033D1 89C2                <1> 	mov	edx, eax
  1068 000033D3 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1069                              <1> dpt_0:
  1070 000033D9 AD                  <1> 	lodsd
  1071 000033DA 21C0                <1> 	and	eax, eax
  1072 000033DC 7444                <1> 	jz	short dpt_3
  1073 000033DE A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1074 000033E0 7507                <1> 	jnz	short dpt_1
  1075                              <1> 	; 20/07/2015
  1076                              <1> 	; ebp = virtual (linear) address of the memory page
  1077 000033E2 E8BF040000          <1> 	call	reload_page ; 28/04/2015
  1078 000033E7 7244                <1> 	jc	short dpt_p_err
  1079                              <1> dpt_1:
  1080                              <1> 	; 21/09/2015
  1081 000033E9 89C1                <1> 	mov	ecx, eax
  1082 000033EB 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1083 000033EF F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1084 000033F2 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 000033F4 E868FDFFFF          <1> 	call	allocate_page
  1089 000033F9 7232                <1> 	jc	short dpt_p_err
  1090 000033FB 57                  <1> 	push	edi
  1091 000033FC 56                  <1> 	push	esi
  1092 000033FD 89CE                <1> 	mov	esi, ecx
  1093 000033FF 89C7                <1> 	mov	edi, eax
  1094 00003401 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1095 00003406 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1096 00003408 5E                  <1> 	pop	esi
  1097 00003409 5F                  <1> 	pop	edi
  1098                              <1> 	; 
  1099 0000340A 53                  <1> 	push	ebx
  1100 0000340B 50                  <1> 	push	eax
  1101                              <1> 	; 20/07/2015
  1102 0000340C 89EB                <1> 	mov	ebx, ebp
  1103                              <1> 	; ebx = virtual address of the memory page
  1104 0000340E E843030000          <1> 	call	add_to_swap_queue
  1105 00003413 58                  <1> 	pop	eax
  1106 00003414 5B                  <1> 	pop	ebx
  1107                              <1> 	; 21/09/2015
  1108 00003415 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1109                              <1> 		; user + writable + present page
  1110 00003417 EB09                <1> 	jmp	short dpt_3
  1111                              <1> dpt_2:
  1112                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1113 00003419 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1114                              <1> 		    ; (read only page!)
  1115 0000341B 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1116 0000341E 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1117                              <1> dpt_3:
  1118 00003422 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1119                              <1> 	;
  1120 00003423 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1121                              <1> 	;
  1122 00003429 39D7                <1> 	cmp	edi, edx
  1123 0000342B 72AC                <1> 	jb	short dpt_0
  1124                              <1> dpt_p_err:
  1125 0000342D 59                  <1> 	pop	ecx
  1126 0000342E 5A                  <1> 	pop	edx
  1127 0000342F 5F                  <1> 	pop	edi
  1128 00003430 5E                  <1> 	pop	esi
  1129 00003431 58                  <1> 	pop	eax ; *
  1130                              <1> dpt_err:
  1131 00003432 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 00003433 53                  <1> 	push	ebx
  1274 00003434 52                  <1> 	push	edx
  1275 00003435 51                  <1> 	push	ecx
  1276                              <1> 	;
  1277                              <1> 	; 21/09/2015 (debugging)
  1278 00003436 FF05[B1E30000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1279 0000343C FF05[2CF10000]      <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 00003442 8A15[24F10000]      <1> 	mov	dl, [error_code]
  1283                              <1> 	;
  1284 00003448 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1285                              <1> 			; sign
  1286 0000344B 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 0000344D F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1309                              <1> 			; sign
  1310 00003450 0F84AB000000        <1>         jz      pfh_p_err
  1311                              <1> 	; 31/08/2015
  1312 00003456 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 00003459 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 0000345F 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1320                              <1> 			 ; which has caused to page fault
  1321 00003462 E8A2000000          <1> 	call 	copy_page
  1322 00003467 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1323                              <1> 	;
  1324 0000346D EB7D                <1>         jmp     pfh_cpp_ok
  1325                              <1> 	;
  1326                              <1> pfh_alloc_np:
  1327 0000346F E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1328 00003474 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 0000347A 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1334 0000347D 7505                <1> 	jnz	short pfh_um
  1335                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1336 0000347F 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 00003482 EB06                <1> 	jmp	short pfh_get_pde
  1341                              <1> 	;
  1342                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1343 00003484 8B1D[A1E30000]      <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 0000348A 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1348 0000348D 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1349                              <1> 			 ; which has been caused to page fault
  1350                              <1> 			 ;
  1351 00003490 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1352 00003493 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1353                              <1> 	;
  1354 00003496 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1355 00003498 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1356 0000349A F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1357 0000349D 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1358                              <1> 			  	  ; set/validate page directory entry
  1359 0000349F 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1360 000034A4 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1361 000034A6 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1362 000034A8 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 000034AA 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1368 000034AC 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1369 000034AE 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1370 000034B0 89C3                <1> 	mov	ebx, eax
  1371 000034B2 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1372 000034B7 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 000034B9 89C1                <1> 	mov	ecx, eax
  1376 000034BB E81BFDFFFF          <1> 	call	clear_page ; Clear page content
  1377                              <1> pfh_get_pte:
  1378 000034C0 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1379                              <1> 			 ; which has been caused to page fault
  1380 000034C3 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1381 000034C5 C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1382                              <1> 			 ; higher 20 bits of the page fault address 
  1383 000034C8 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1384 000034CD C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1385 000034D0 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1386 000034D2 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 000034D4 21C0                <1> 	and	eax, eax
  1389 000034D6 7410                <1> 	jz	short pfh_gpte_1
  1390                              <1> 	; 20/07/2015
  1391 000034D8 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1392 000034DA 55                  <1> 	push	ebp ; 20/07/2015
  1393 000034DB 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 000034DE E8B7000000          <1> 	call	swap_in
  1399 000034E3 5D                  <1> 	pop	ebp
  1400 000034E4 7210                <1> 	jc      short pfh_err_retn
  1401 000034E6 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 000034E8 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1406 000034EA 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 000034EC 0F20D3              <1> 	mov	ebx, cr2
  1410 000034EF E862020000          <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 000034F4 31C0                <1> 	xor	eax, eax  ; 0
  1419                              <1> 	;
  1420                              <1> pfh_err_retn:
  1421 000034F6 59                  <1> 	pop	ecx
  1422 000034F7 5A                  <1> 	pop	edx
  1423 000034F8 5B                  <1> 	pop	ebx
  1424 000034F9 C3                  <1> 	retn 
  1425                              <1> 	
  1426                              <1> pfh_im_err:
  1427 000034FA 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 000034FF 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 00003501 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 00003506 F9                  <1> 	stc
  1440 00003507 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 00003509 56                  <1> 	push	esi
  1470 0000350A 57                  <1> 	push	edi
  1471                              <1> 	;push	ebx
  1472                              <1> 	;push	ecx
  1473 0000350B 31F6                <1> 	xor 	esi, esi
  1474 0000350D C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1475 00003510 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1476 00003512 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1477 00003515 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1478 00003518 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1479 0000351A 031D[A1E30000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1480 00003520 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1481 00003522 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1482 00003526 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1483 00003528 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1484 0000352E 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1485 00003532 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1486                              <1> 	; 07/09/2015
  1487 00003534 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1488                              <1> 				     ; read only page as a child process?)	
  1489 00003539 7509                <1> 	jnz	short cpp_0 ; yes
  1490 0000353B 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1491 0000353D 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1492 00003542 EB32                <1> 	jmp	short cpp_1
  1493                              <1> cpp_0:
  1494 00003544 89FE                <1> 	mov	esi, edi
  1495 00003546 0335[A5E30000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1496 0000354C 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1497 0000354E 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1498 00003552 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1499 00003554 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1500 0000355A 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1501 0000355E 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1502 00003560 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1503                              <1> 	; 21/09/2015
  1504 00003562 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1505 00003564 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1506                              <1> 	;
  1507 00003568 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1508 0000356B 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1509                              <1> 	;
  1510 0000356D 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1511 00003572 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1512 00003574 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 00003576 E8E6FBFFFF          <1> 	call	allocate_page
  1516 0000357B 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1517 0000357D 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1518 0000357F 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 00003581 890E                <1> 	mov	[esi], ecx
  1524 00003583 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 00003586 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1528                              <1> 	; 07/09/2015
  1529 00003588 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1530 0000358A B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1531 0000358F F3A5                <1> 	rep	movsd ; 31/08/2015
  1532                              <1> cpp_3:		
  1533 00003591 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1534 00003593 8903                <1> 	mov	[ebx], eax ; Update PTE
  1535 00003595 28C0                <1> 	sub	al, al ; clear attributes
  1536                              <1> cpp_4:
  1537                              <1> 	;pop	ecx
  1538                              <1> 	;pop	ebx
  1539 00003597 5F                  <1> 	pop	edi
  1540 00003598 5E                  <1> 	pop	esi
  1541 00003599 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 0000359A 833D[0EF10000]00    <1>         cmp     dword [swp_drv], 0
  1731 000035A1 7648                <1> 	jna	short swpin_dnp_err
  1732                              <1> 
  1733 000035A3 3B05[12F10000]      <1> 	cmp	eax, [swpd_size]
  1734 000035A9 734C                <1> 	jnb	short swpin_snp_err
  1735                              <1> 
  1736 000035AB 56                  <1> 	push	esi
  1737 000035AC 53                  <1> 	push	ebx
  1738 000035AD 51                  <1> 	push	ecx
  1739 000035AE 8B35[0EF10000]      <1> 	mov	esi, [swp_drv]	
  1740 000035B4 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 000035B9 50                  <1> 	push	eax
  1751 000035BA E86B020000          <1> 	call	logical_disk_read
  1752 000035BF 58                  <1> 	pop	eax
  1753 000035C0 730C                <1> 	jnc	short swpin_read_ok
  1754                              <1> 	;
  1755 000035C2 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1756 000035C7 A3[9DE30000]        <1> 	mov	[u.error], eax
  1757 000035CC EB19                <1> 	jmp	short swpin_retn
  1758                              <1> 	;
  1759                              <1> swpin_read_ok:
  1760                              <1> 	; EAX = Offset address (logical sector number)
  1761 000035CE E8C9010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
  1762                              <1> 	;
  1763                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1764                              <1> 	; 20/07/2015
  1765 000035D3 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1766 000035D5 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1767 000035DA 8A1D[97E30000]      <1> 	mov	bl, [u.uno] ; current process number
  1768                              <1> 	; EBX = Virtual address & process number combination
  1769 000035E0 E8D6000000          <1> 	call	swap_queue_shift
  1770 000035E5 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  1771                              <1> 	;
  1772                              <1> swpin_retn:
  1773 000035E7 59                  <1> 	pop	ecx
  1774 000035E8 5B                  <1> 	pop	ebx
  1775 000035E9 5E                  <1> 	pop	esi
  1776 000035EA C3                  <1> 	retn
  1777                              <1> 
  1778                              <1> swpin_dnp_err:
  1779 000035EB B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1780                              <1> swpin_err_retn:
  1781 000035F0 A3[9DE30000]        <1> 	mov	[u.error], eax
  1782 000035F5 F9                  <1> 	stc
  1783 000035F6 C3                  <1> 	retn
  1784                              <1> 
  1785                              <1> swpin_snp_err:
  1786 000035F7 B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1787 000035FC EBF2                <1> 	jmp	short swpin_err_retn
  1788                              <1> 
  1789                              <1> swap_out:
  1790                              <1>         ; 23/05/2016
  1791                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1792                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
  1793                              <1> 	;
  1794                              <1> 	; INPUT -> 
  1795                              <1> 	;	none
  1796                              <1> 	;
  1797                              <1> 	; OUTPUT ->
  1798                              <1> 	;	EAX = Physical page address (which is swapped out
  1799                              <1> 	;	      for allocating a new page)
  1800                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  1801                              <1> 	;		  or sector not present or drive not ready
  1802                              <1> 	;	     EAX = Error code
  1803                              <1> 	;	     [u.error] = EAX 
  1804                              <1> 	;		       = The last error code for the process
  1805                              <1> 	;		         (will be reset after returning to user)	  
  1806                              <1> 	;
  1807                              <1> 	; Modified Registers -> none (except EAX)
  1808                              <1> 	;
  1809 000035FE 66833D[0CF10000]01  <1> 	cmp 	word [swpq_count], 1
  1810 00003606 0F82A8000000        <1>         jc      swpout_im_err ; 'insufficient memory'
  1811                              <1> 
  1812                              <1>         ;cmp    dword [swp_drv], 1
  1813                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  1814                              <1> 
  1815 0000360C 833D[16F10000]01    <1>         cmp     dword [swpd_free], 1
  1816 00003613 0F8288000000        <1>         jc      swpout_nfspc_err ; 'no free space on swap disk'
  1817                              <1> 
  1818 00003619 53                  <1> 	push	ebx
  1819                              <1> swpout_1:
  1820 0000361A 31DB                <1> 	xor	ebx, ebx
  1821 0000361C E89A000000          <1> 	call	swap_queue_shift
  1822 00003621 21C0                <1> 	and	eax, eax	; entry count (before shifting)
  1823 00003623 0F8483000000        <1>         jz      swpout_npts_err        ; There is no any PTE in
  1824                              <1> 				       ; the swap queue
  1825 00003629 BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
  1826                              <1> 				       ; the swap queue		
  1827 0000362E 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
  1828                              <1> 
  1829                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
  1830                              <1> 	;jz	short swpout_1	       ; non-present page already
  1831                              <1> 				       ; must not be in the queue
  1832                              <1> 
  1833                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
  1834                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
  1835                              <1> 				       ; swapped out)
  1836                              <1> 	
  1837 00003630 A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
  1838 00003632 75E6                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
  1839                              <1> 				       ; swapped out, at this stage)
  1840                              <1> 	;
  1841 00003634 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1842                              <1> 	;
  1843                              <1> 	; 19/05/2016
  1844                              <1> 	; check this page is in timer events or not
  1845                              <1> swpout_timer_page_0:
  1846 00003638 52                  <1> 	push	edx
  1847 00003639 51                  <1> 	push	ecx
  1848 0000363A BA[0CF00000]        <1> 	mov	edx, timer_set ; beginning address of timer event
  1849                              <1> 			       ; structures 
  1850                              <1> swpout_timer_page_1:
  1851 0000363F 668B0A              <1> 	mov	cx, [edx]
  1852 00003642 6609C9              <1> 	or	cx, cx
  1853 00003645 7410                <1> 	jz	short swpout_timer_page_2 ; end of timer events
  1854 00003647 8B4A0C              <1> 	mov	ecx, [edx+12] ; response (signal return) address
  1855 0000364A 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
  1856                              <1> 				; of the response byte address, to
  1857                              <1> 				; get beginning of the page address)
  1858 0000364F 39C8                <1> 	cmp	eax, ecx
  1859 00003651 7504                <1> 	jne	short swpout_timer_page_2 ; not same page
  1860                              <1> 	
  1861                              <1> 	; !same page!
  1862                              <1> 	;
  1863                              <1> 	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
  1864                              <1> 	; This page will be used by the kernel to put timer event
  1865                              <1> 	; response (signal return) byte at the requested address;
  1866                              <1> 	; in order to prevent a possible wrong write (while
  1867                              <1> 	; this page is swapped out) on physical memory,
  1868                              <1> 	; we must protect this page against to be swapped out!
  1869                              <1> 	;
  1870 00003653 59                  <1> 	pop	ecx
  1871 00003654 5A                  <1> 	pop	edx
  1872 00003655 EBC3                <1> 	jmp	short swpout_1	; do not swap out this page !
  1873                              <1>  
  1874                              <1> swpout_timer_page_2:
  1875 00003657 81FA[FCF00000]      <1> 	cmp	edx, timer_set + 240 ; last timer event (15*16) 
  1876 0000365D 7305                <1> 	jnb	short swpout_timer_page_3
  1877 0000365F 83C210              <1> 	add	edx, 16
  1878 00003662 EBDB                <1> 	jmp	short swpout_timer_page_1	
  1879                              <1> 
  1880                              <1> swpout_timer_page_3:
  1881 00003664 59                  <1> 	pop	ecx
  1882                              <1> 	;
  1883                              <1> 	;push	edx
  1884 00003665 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1885 00003667 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1886                              <1> 	;
  1887 00003669 E861010000          <1> 	call	link_swap_block
  1888 0000366E 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
  1889 00003670 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
  1890 00003671 5B                  <1> 	pop	ebx
  1891 00003672 EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
  1892                              <1> swpout_2:	
  1893 00003674 56                  <1> 	push	esi
  1894 00003675 51                  <1> 	push	ecx
  1895 00003676 50                  <1> 	push	eax ; sector address
  1896 00003677 8B35[0EF10000]      <1> 	mov	esi, [swp_drv]	
  1897 0000367D B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1898                              <1> 		; Note: Even if corresponding physical disk's sector 
  1899                              <1> 		; size different than 512 bytes, logical disk sector
  1900                              <1> 		; size is 512 bytes and disk writing procedure
  1901                              <1> 		; will be performed for writing 4096 bytes
  1902                              <1> 		; (2*2048, 8*512). 
  1903                              <1> 	; ESI = Logical disk description table address
  1904                              <1> 	; EBX = Buffer address
  1905                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1906                              <1> 	; ECX = Sector count ; 8 sectors
  1907 00003682 E8A4010000          <1> 	call	logical_disk_write
  1908 00003687 59                  <1> 	pop	ecx ; sector address	
  1909 00003688 730C                <1> 	jnc	short swpout_write_ok
  1910                              <1> 	;
  1911                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
  1912                              <1> swpout_dw_err:
  1913 0000368A B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1914 0000368F A3[9DE30000]        <1> 	mov	[u.error], eax
  1915 00003694 EB06                <1> 	jmp	short swpout_retn
  1916                              <1> 	;
  1917                              <1> swpout_write_ok:
  1918                              <1> 	; EBX = Buffer (page) address
  1919                              <1> 	; EDX = Page Table entry address
  1920                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
  1921 00003696 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1922 00003698 890A                <1> 	mov 	[edx], ecx 
  1923                              <1> 		; bit 0 = 0 (swapped page)
  1924 0000369A 89D8                <1> 	mov	eax, ebx
  1925                              <1> swpout_retn:
  1926 0000369C 59                  <1> 	pop	ecx
  1927 0000369D 5E                  <1> 	pop	esi
  1928 0000369E 5A                  <1> 	pop	edx
  1929 0000369F 5B                  <1> 	pop	ebx
  1930 000036A0 C3                  <1> 	retn
  1931                              <1> 
  1932                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
  1933                              <1> ;	after the page is swapped out. (the PTE at the queue head
  1934                              <1> ;	-with 'non-present' attribute- will be dropped from the
  1935                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
  1936                              <1> 	
  1937                              <1> ;swpout_dnp_err:
  1938                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  1939                              <1> ;	jmp	short swpout_err_retn
  1940                              <1> swpout_nfspc_err:
  1941 000036A1 B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1942                              <1> swpout_err_retn:
  1943 000036A6 A3[9DE30000]        <1> 	mov	[u.error], eax
  1944                              <1> 	;stc
  1945 000036AB C3                  <1> 	retn
  1946                              <1> swpout_npts_err:
  1947 000036AC B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1948 000036B1 5B                  <1> 	pop	ebx
  1949 000036B2 EBF2                <1> 	jmp	short swpout_err_retn
  1950                              <1> swpout_im_err:
  1951 000036B4 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1952 000036B9 EBEB                <1> 	jmp	short swpout_err_retn
  1953                              <1> 
  1954                              <1> swap_queue_shift:
  1955                              <1> 	; 20/07/2015
  1956                              <1> 	; 28/04/2015
  1957                              <1> 	; 18/04/2015
  1958                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
  1959                              <1> 	;
  1960                              <1> 	; INPUT ->
  1961                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  1962                              <1> 	;	      and process number combination (bit 0 to 11)
  1963                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  1964                              <1> 	; OUTPUT ->
  1965                              <1> 	;	If EBX input > 0 
  1966                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1967                              <1> 	; 	    from the tail to the head, up to entry offset
  1968                              <1> 	; 	    which points to EBX input value or nothing
  1969                              <1> 	;	    to do if EBX value is not found in the queue.
  1970                              <1> 	;	    (The entry -with EBX value- will be removed
  1971                              <1> 	;	     from the queue if it is found.)	
  1972                              <1> 	;	If EBX input = 0
  1973                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1974                              <1> 	; 	    from the tail to the head, if the PTE address
  1975                              <1> 	;	    in head of the queue is marked as "accessed"
  1976                              <1> 	;	    or it is marked as "non present".
  1977                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
  1978                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
  1979                              <1> 	;	    the queue will be rotated -without dropping
  1980                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
  1981                              <1> 	; 	    to tail direction. The PTE in the head will be
  1982                              <1> 	;	    moved in the tail, other PTEs will be shifted on
  1983                              <1> 	;	    head direction.)	
  1984                              <1> 	;
  1985                              <1> 	;	EAX = [swpq_count] (before the shifting)
  1986                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
  1987                              <1> 	; 	     is not applicable)	
  1988                              <1> 	;
  1989                              <1> 	; Modified Registers -> EAX
  1990                              <1> 	;
  1991 000036BB 0FB705[0CF10000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  1992 000036C2 6621C0              <1> 	and	ax, ax
  1993 000036C5 7433                <1> 	jz	short swpqs_retn
  1994 000036C7 57                  <1> 	push	edi
  1995 000036C8 56                  <1> 	push	esi
  1996 000036C9 53                  <1> 	push	ebx
  1997 000036CA 51                  <1> 	push	ecx
  1998 000036CB 50                  <1> 	push	eax
  1999 000036CC BE00E00800          <1> 	mov	esi, swap_queue
  2000 000036D1 89C1                <1> 	mov	ecx, eax
  2001 000036D3 09DB                <1> 	or	ebx, ebx
  2002 000036D5 7424                <1> 	jz	short swpqs_7
  2003                              <1> swpqs_1:
  2004 000036D7 AD                  <1> 	lodsd
  2005 000036D8 39D8                <1> 	cmp	eax, ebx
  2006 000036DA 7404                <1> 	je	short swpqs_2
  2007 000036DC E2F9                <1> 	loop	swpqs_1
  2008 000036DE EB15                <1> 	jmp	short swpqs_6
  2009                              <1> swpqs_2:
  2010 000036E0 89F7                <1> 	mov	edi, esi
  2011 000036E2 83EF04              <1> 	sub 	edi, 4
  2012                              <1> swpqs_3:
  2013 000036E5 66FF0D[0CF10000]    <1> 	dec	word [swpq_count]
  2014 000036EC 7403                <1> 	jz	short swpqs_5
  2015                              <1> swpqs_4:
  2016 000036EE 49                  <1> 	dec 	ecx
  2017 000036EF F3A5                <1> 	rep	movsd	; shift up (to the head)
  2018                              <1> swpqs_5:
  2019 000036F1 31C0                <1> 	xor	eax, eax
  2020 000036F3 8907                <1> 	mov	[edi], eax
  2021                              <1> swpqs_6:
  2022 000036F5 58                  <1> 	pop	eax
  2023 000036F6 59                  <1> 	pop	ecx
  2024 000036F7 5B                  <1> 	pop	ebx
  2025 000036F8 5E                  <1> 	pop	esi
  2026 000036F9 5F                  <1> 	pop	edi
  2027                              <1> swpqs_retn:
  2028 000036FA C3                  <1> 	retn		
  2029                              <1> swpqs_7:
  2030 000036FB 89F7                <1> 	mov	edi, esi ; head
  2031 000036FD AD                  <1> 	lodsd
  2032                              <1> 	; 20/07/2015
  2033 000036FE 89C3                <1> 	mov	ebx, eax
  2034 00003700 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  2035                              <1> 		      ; ebx = virtual address (at page boundary)	
  2036 00003706 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2037                              <1> 		      ; ax = process number (1 to 4095)
  2038 0000370B 3A05[97E30000]      <1> 	cmp	al, [u.uno]
  2039                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2040 00003711 7507                <1> 	jne	short swpqs_8
  2041 00003713 A1[A1E30000]        <1> 	mov	eax, [u.pgdir]
  2042 00003718 EB16                <1> 	jmp	short swpqs_9
  2043                              <1> swpqs_8:
  2044                              <1> 	;shl	ax, 2
  2045 0000371A C0E002              <1> 	shl	al, 2
  2046 0000371D 8B80[C8E00000]      <1> 	mov 	eax, [eax+p.upage-4]
  2047 00003723 09C0                <1> 	or	eax, eax
  2048 00003725 74BE                <1> 	jz	short swpqs_3 ; invalid upage
  2049 00003727 83C061              <1> 	add	eax, u.pgdir - user
  2050                              <1> 			 ; u.pgdir value for the process
  2051                              <1> 			 ; is in [eax]
  2052 0000372A 8B00                <1> 	mov	eax, [eax]
  2053 0000372C 21C0                <1> 	and	eax, eax
  2054 0000372E 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
  2055                              <1> swpqs_9:
  2056 00003730 52                  <1> 	push	edx
  2057                              <1> 	; eax = page directory
  2058                              <1> 	; ebx = virtual address
  2059 00003731 E846FBFFFF          <1> 	call	get_pte
  2060 00003736 89D3                <1> 	mov	ebx, edx ; PTE address
  2061 00003738 5A                  <1> 	pop	edx
  2062 00003739 72AA                <1> 	jc	short swpqs_3 ; empty PDE
  2063                              <1> 	; EAX = PTE value
  2064 0000373B A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2065 0000373D 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
  2066                              <1> 			      ; from the queue (head)
  2067 0000373F A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
  2068 00003741 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
  2069                              <1> 			      ; from the queue (head) 	
  2070                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
  2071                              <1> 	;jz	short swpqs_6 ; present
  2072                              <1> 			      ; non-accessed page
  2073 00003743 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2074 00003747 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
  2075 00003749 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2076                              <1> 	;
  2077                              <1> 	; Rotation (head -> tail)
  2078 0000374B 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2079 0000374C 74A7                <1> 	jz	short swpqs_6
  2080                              <1> 		; esi = head + 4
  2081                              <1> 		; edi = head
  2082 0000374E 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2083 00003750 F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2084 00003752 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
  2085 00003754 EB9F                <1> 	jmp	short swpqs_6
  2086                              <1> 
  2087                              <1> add_to_swap_queue:
  2088                              <1> ; temporary - 16/09/2015
  2089 00003756 C3                  <1> retn
  2090                              <1> 	; 20/07/2015
  2091                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2092                              <1> 	;
  2093                              <1> 	; Adds new page to swap queue
  2094                              <1> 	; (page directories and page tables must not be added
  2095                              <1> 	; to swap queue)	
  2096                              <1> 	;
  2097                              <1> 	; INPUT ->
  2098                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
  2099                              <1> 	;
  2100                              <1> 	; OUTPUT ->
  2101                              <1> 	;	EAX = [swpq_count]
  2102                              <1> 	;	      (after the PTE has been added)
  2103                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  2104                              <1> 	;	      the pte could not be added.
  2105                              <1> 	;
  2106                              <1> 	; Modified Registers -> EAX
  2107                              <1> 	;
  2108 00003757 53                  <1> 	push	ebx
  2109 00003758 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2110 0000375D 8A1D[97E30000]      <1> 	mov	bl, [u.uno] ; current process number
  2111 00003763 E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2112                              <1> 				 ; it is already in the queue
  2113                              <1> 		; Then add it to the tail of the queue
  2114 00003768 0FB705[0CF10000]    <1> 	movzx	eax, word [swpq_count]
  2115 0000376F 663D0004            <1> 	cmp	ax, 1024
  2116 00003773 7205                <1> 	jb	short atsq_1
  2117 00003775 6629C0              <1> 	sub	ax, ax
  2118 00003778 5B                  <1> 	pop	ebx
  2119 00003779 C3                  <1> 	retn
  2120                              <1> atsq_1:
  2121 0000377A 56                  <1> 	push	esi
  2122 0000377B BE00E00800          <1> 	mov	esi, swap_queue
  2123 00003780 6621C0              <1> 	and	ax, ax
  2124 00003783 740A                <1> 	jz	short atsq_2
  2125 00003785 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2126 00003789 01C6                <1> 	add	esi, eax
  2127 0000378B 66C1E802            <1> 	shr	ax, 2
  2128                              <1> atsq_2:
  2129 0000378F 6640                <1> 	inc	ax
  2130 00003791 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2131 00003793 66A3[0CF10000]      <1> 	mov	[swpq_count], ax
  2132 00003799 5E                  <1> 	pop	esi
  2133 0000379A 5B                  <1> 	pop	ebx
  2134 0000379B C3                  <1> 	retn
  2135                              <1> 
  2136                              <1> unlink_swap_block:
  2137                              <1> 	; 15/09/2015
  2138                              <1> 	; 30/04/2015
  2139                              <1> 	; 18/04/2015
  2140                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2141                              <1> 	;
  2142                              <1> 	; INPUT -> 
  2143                              <1> 	;	EAX = swap disk/file offset address
  2144                              <1> 	;	      (bit 1 to bit 31)
  2145                              <1> 	; OUTPUT ->
  2146                              <1> 	;	[swpd_free] is increased
  2147                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  2148                              <1> 	;
  2149                              <1> 	; Modified Registers -> EAX
  2150                              <1> 	;
  2151 0000379C 53                  <1> 	push	ebx
  2152 0000379D 52                  <1> 	push	edx
  2153                              <1> 	;
  2154 0000379E C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  2155                              <1> 				     ; 3 bits right
  2156                              <1> 				     ; to get swap block/page number
  2157 000037A1 89C2                <1> 	mov	edx, eax
  2158                              <1> 	; 15/09/2015
  2159 000037A3 C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
  2160                              <1> 				     ; (1 allocation bit = 1 page)
  2161                              <1> 				     ; (1 allocation bytes = 8 pages)
  2162 000037A6 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2163                              <1> 				     ; (to get 32 bit position)			
  2164                              <1> 	;
  2165 000037A9 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2166 000037AE 01D3                <1> 	add	ebx, edx
  2167 000037B0 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2168                              <1> 				     ; (allocation bit position)	 
  2169 000037B3 3B05[1AF10000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  2170                              <1> 				     ; than the address in 'swpd_next' ?
  2171                              <1> 				     ; (next/first free block value)		
  2172 000037B9 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2173 000037BB A3[1AF10000]        <1> 	mov	[swpd_next], eax     ; yes	
  2174                              <1> uswpbl_1:
  2175 000037C0 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
  2176                              <1> 				     ; set relevant bit to 1.
  2177                              <1> 				     ; set CF to the previous bit value	
  2178 000037C3 F5                  <1> 	cmc			     ; complement carry flag	
  2179 000037C4 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2180                              <1> 				     ; if the block is already deallocated
  2181                              <1> 				     ; before.	
  2182 000037C6 FF05[16F10000]      <1>         inc     dword [swpd_free]
  2183                              <1> uswpbl_2:
  2184 000037CC 5A                  <1> 	pop	edx
  2185 000037CD 5B                  <1> 	pop	ebx
  2186 000037CE C3                  <1> 	retn
  2187                              <1> 
  2188                              <1> link_swap_block:
  2189                              <1> 	; 01/07/2015
  2190                              <1> 	; 18/04/2015
  2191                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2192                              <1> 	;
  2193                              <1> 	; INPUT -> none
  2194                              <1> 	;
  2195                              <1> 	; OUTPUT ->
  2196                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  2197                              <1> 	;	      in sectors (corresponding 
  2198                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  2199                              <1> 	;
  2200                              <1> 	;	CF = 1 and EAX = 0 
  2201                              <1> 	; 		   if there is not a free block to be allocated	
  2202                              <1> 	;
  2203                              <1> 	; Modified Registers -> none (except EAX)
  2204                              <1> 	;
  2205                              <1> 
  2206                              <1> 	;mov	eax, [swpd_free]
  2207                              <1> 	;and	eax, eax
  2208                              <1> 	;jz	short out_of_swpspc
  2209                              <1> 	;
  2210 000037CF 53                  <1> 	push	ebx
  2211 000037D0 51                  <1> 	push	ecx
  2212                              <1> 	;
  2213 000037D1 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2214 000037D6 89D9                <1> 	mov	ecx, ebx
  2215 000037D8 031D[1AF10000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2216                              <1> 				 ; next_free_swap_block >> 5
  2217 000037DE 030D[1EF10000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2218                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2219                              <1> lswbl_scan:
  2220 000037E4 39CB                <1> 	cmp	ebx, ecx
  2221 000037E6 770A                <1> 	ja	short lswbl_notfound
  2222                              <1> 	;
  2223 000037E8 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2224                              <1> 			   ; Clears ZF if a bit is found set (1) and 
  2225                              <1> 			   ; loads the destination with an index to
  2226                              <1> 			   ; first set bit. (0 -> 31) 
  2227                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2228                              <1> 	; 01/07/2015
  2229 000037EB 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  2230                              <1> 			 ;
  2231                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
  2232                              <1> 			 ;	  with value of 1 means 
  2233                              <1> 			 ;	  the corresponding page is free 
  2234                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
  2235 000037ED 83C304              <1> 	add	ebx, 4
  2236                              <1> 			 ; We return back for searching next page block
  2237                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
  2238                              <1> 			 ;	 we always will find at least 1 free block here.
  2239 000037F0 EBF2                <1> 	jmp    	short lswbl_scan
  2240                              <1> 	;
  2241                              <1> lswbl_notfound:	
  2242 000037F2 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2243 000037F8 890D[1AF10000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2244                              <1> 				 ; (unlink_swap_block procedure will change it)
  2245 000037FE 31C0                <1> 	xor	eax, eax
  2246 00003800 A3[16F10000]        <1> 	mov	[swpd_free], eax
  2247 00003805 F9                  <1> 	stc
  2248                              <1> lswbl_ok:
  2249 00003806 59                  <1> 	pop	ecx
  2250 00003807 5B                  <1> 	pop	ebx
  2251 00003808 C3                  <1> 	retn
  2252                              <1> 	;
  2253                              <1> ;out_of_swpspc:
  2254                              <1> ;	stc
  2255                              <1> ;	retn
  2256                              <1> 
  2257                              <1> lswbl_found:
  2258 00003809 89D9                <1> 	mov	ecx, ebx
  2259 0000380B 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2260 00003811 890D[1AF10000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2261                              <1> 				 ; address/offset (to the next)
  2262 00003817 FF0D[16F10000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2263                              <1> 	;
  2264 0000381D 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2265                              <1> 				 ; is copied into the Carry Flag and then cleared
  2266                              <1> 				 ; in the destination.
  2267                              <1> 				 ;
  2268                              <1> 				 ; Reset the bit which is corresponding to the 
  2269                              <1> 				 ; (just) allocated block.
  2270 00003820 C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2271 00003823 01C8                <1> 	add	eax, ecx	 ; = block number
  2272 00003825 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  2273                              <1> 				 ; 1 block =  8 sectors
  2274                              <1> 	;
  2275                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
  2276                              <1> 	;
  2277                              <1> 	; NOTE: The relevant page table entry will be updated
  2278                              <1> 	;       according to this EAX value...
  2279                              <1> 	;
  2280 00003828 EBDC                <1> 	jmp	short lswbl_ok
  2281                              <1> 
  2282                              <1> logical_disk_read:
  2283                              <1> 	; 20/07/2015
  2284                              <1> 	; 09/03/2015 (temporary code here)
  2285                              <1> 	;
  2286                              <1> 	; INPUT ->
  2287                              <1> 	; 	ESI = Logical disk description table address
  2288                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2289                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2290                              <1> 	; 	ECX = Sector count
  2291                              <1> 	;
  2292                              <1> 	;
  2293 0000382A C3                  <1> 	retn
  2294                              <1> 
  2295                              <1> logical_disk_write:
  2296                              <1> 	; 20/07/2015
  2297                              <1> 	; 09/03/2015 (temporary code here)
  2298                              <1> 	;
  2299                              <1> 	; INPUT ->
  2300                              <1> 	; 	ESI = Logical disk description table address
  2301                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2302                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2303                              <1> 	; 	ECX = Sector count
  2304                              <1> 	;
  2305 0000382B C3                  <1> 	retn
  2306                              <1> 
  2307                              <1> get_physical_addr:
  2308                              <1> 	; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  2309                              <1> 	; 18/10/2015
  2310                              <1> 	; 29/07/2015
  2311                              <1> 	; 20/07/2015
  2312                              <1> 	; 04/06/2015
  2313                              <1> 	; 20/05/2015
  2314                              <1> 	; 28/04/2015
  2315                              <1> 	; 18/04/2015
  2316                              <1> 	; Get physical address
  2317                              <1> 	;     (allocates a new page for user if it is not present)
  2318                              <1> 	;	
  2319                              <1> 	; (This subroutine is needed for mapping user's virtual 
  2320                              <1> 	; (buffer) address to physical address (of the buffer).)
  2321                              <1> 	; ('sys write', 'sys read' system calls...)
  2322                              <1> 	;
  2323                              <1> 	; INPUT ->
  2324                              <1> 	;	EBX = virtual address
  2325                              <1> 	;	u.pgdir = page directory (physical) address
  2326                              <1> 	;
  2327                              <1> 	; OUTPUT ->
  2328                              <1> 	;	EAX = physical address 
  2329                              <1> 	;	EBX = linear address	
  2330                              <1> 	;	EDX = physical address of the page frame
  2331                              <1> 	;	      (with attribute bits)
  2332                              <1> 	;	ECX = byte count within the page frame
  2333                              <1> 	;
  2334                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  2335                              <1> 	;
  2336 0000382C 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2337                              <1> get_physical_addr_x: ; 27/05/2016
  2338 00003832 A1[A1E30000]        <1> 	mov	eax, [u.pgdir]
  2339 00003837 E840FAFFFF          <1> 	call	get_pte
  2340                              <1> 		; EDX = Page table entry address (if CF=0)
  2341                              <1> 	        ;       Page directory entry address (if CF=1)
  2342                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  2343                              <1> 		; EAX = Page table entry value (page address)
  2344                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  2345 0000383C 731C                <1> 	jnc	short gpa_1
  2346                              <1> 	;
  2347 0000383E E81EF9FFFF          <1> 	call	allocate_page
  2348 00003843 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2349                              <1> gpa_0:
  2350 00003845 E891F9FFFF          <1> 	call 	clear_page
  2351                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2352 0000384A 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  2353                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  2354                              <1> 			   ; (user, writable, present page)	
  2355 0000384C 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2356 0000384E A1[A1E30000]        <1> 	mov	eax, [u.pgdir]	
  2357 00003853 E824FAFFFF          <1> 	call	get_pte
  2358 00003858 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2359                              <1> gpa_1:
  2360                              <1> 	; EAX = PTE value, EDX = PTE address
  2361 0000385A A801                <1> 	test 	al, PTE_A_PRESENT
  2362 0000385C 751A                <1> 	jnz	short gpa_3
  2363 0000385E 09C0                <1> 	or	eax, eax
  2364 00003860 7430                <1> 	jz	short gpa_4  ; Allocate a new page
  2365                              <1> 	; 20/07/2015
  2366 00003862 55                  <1> 	push	ebp
  2367 00003863 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2368                              <1> 	; reload swapped page
  2369 00003865 E83C000000          <1> 	call	reload_page ; 28/04/2015
  2370 0000386A 5D                  <1> 	pop	ebp
  2371 0000386B 7224                <1> 	jc	short gpa_retn
  2372                              <1> gpa_2:
  2373                              <1> 	; 20/07/2015
  2374                              <1> 	; 20/05/2015
  2375                              <1> 	; add this page to swap queue
  2376 0000386D 50                  <1> 	push	eax 
  2377                              <1> 	; EBX = virtual address
  2378 0000386E E8E3FEFFFF          <1> 	call 	add_to_swap_queue
  2379 00003873 58                  <1> 	pop	eax
  2380                              <1> 		; PTE address in EDX
  2381                              <1> 		; virtual address in EBX
  2382                              <1> 	; EAX = memory page address
  2383 00003874 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  2384                              <1> 				  ; present flag, bit 0 = 1
  2385                              <1> 				  ; user flag, bit 2 = 1	
  2386                              <1> 				  ; writable flag, bit 1 = 1
  2387 00003876 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2388                              <1> gpa_3:
  2389                              <1> 	; 18/10/2015
  2390 00003878 89D9                <1> 	mov	ecx, ebx
  2391 0000387A 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2392 00003880 89C2                <1> 	mov 	edx, eax
  2393 00003882 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2394 00003886 01C8                <1> 	add	eax, ecx
  2395 00003888 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2396 0000388A 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2397 00003890 F8                  <1> 	clc
  2398                              <1> gpa_retn:
  2399 00003891 C3                  <1> 	retn	
  2400                              <1> gpa_4:	
  2401 00003892 E8CAF8FFFF          <1> 	call	allocate_page
  2402 00003897 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2403 00003899 E83DF9FFFF          <1> 	call	clear_page
  2404 0000389E EBCD                <1> 	jmp	short gpa_2
  2405                              <1> 
  2406                              <1> gpa_im_err:	
  2407 000038A0 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2408                              <1> 				  ; Major error = 0 (No protection fault)	
  2409 000038A5 C3                  <1> 	retn
  2410                              <1> 
  2411                              <1> reload_page:
  2412                              <1> 	; 20/07/2015
  2413                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  2414                              <1> 	;
  2415                              <1> 	; Reload (Restore) swapped page at memory
  2416                              <1> 	;
  2417                              <1> 	; INPUT -> 
  2418                              <1> 	;	EBP = Virtual (linear) memory address
  2419                              <1> 	;	EAX = PTE value (swap disk sector address)
  2420                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  2421                              <1> 	; OUTPUT ->
  2422                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  2423                              <1> 	;
  2424                              <1> 	;	CF = 1 and EAX = error code
  2425                              <1> 	;
  2426                              <1> 	; Modified Registers -> none (except EAX)
  2427                              <1> 	;
  2428 000038A6 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2429 000038A8 53                  <1> 	push	ebx      ;
  2430 000038A9 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2431 000038AB E8B1F8FFFF          <1> 	call	allocate_page
  2432 000038B0 720C                <1> 	jc	short rlp_im_err
  2433 000038B2 93                  <1> 	xchg 	eax, ebx	
  2434                              <1> 	; EBX = Physical memory (page) address
  2435                              <1> 	; EAX = Swap disk (offset) address
  2436                              <1> 	; EBP = Virtual (linear) memory address
  2437 000038B3 E8E2FCFFFF          <1> 	call	swap_in
  2438 000038B8 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2439 000038BA 89D8                <1> 	mov	eax, ebx	
  2440                              <1> rlp_retn:
  2441 000038BC 5B                  <1> 	pop	ebx
  2442 000038BD C3                  <1> 	retn
  2443                              <1> 	
  2444                              <1> rlp_im_err:	
  2445 000038BE B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2446                              <1> 				  ; Major error = 0 (No protection fault)	
  2447 000038C3 EBF7                <1> 	jmp	short rlp_retn
  2448                              <1> 
  2449                              <1> rlp_swp_err:
  2450 000038C5 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2451 000038CA EBF0                <1> 	jmp	short rlp_retn
  2452                              <1> 
  2453                              <1> 
  2454                              <1> copy_page_dir:
  2455                              <1> 	; 19/09/2015
  2456                              <1> 	; temporary - 07/09/2015
  2457                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2458                              <1> 	;
  2459                              <1> 	; INPUT -> 
  2460                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  2461                              <1> 	;		    page directory.
  2462                              <1> 	; OUTPUT ->
  2463                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  2464                              <1> 	;	       page directory.
  2465                              <1> 	;	(New page directory with new page table entries.)
  2466                              <1> 	;	(New page tables with read only copies of the parent's
  2467                              <1> 	;	pages.)
  2468                              <1> 	;	EAX = 0 -> Error (CF = 1)
  2469                              <1> 	;
  2470                              <1> 	; Modified Registers -> none (except EAX)
  2471                              <1> 	;
  2472 000038CC E890F8FFFF          <1> 	call	allocate_page
  2473 000038D1 723E                <1> 	jc	short cpd_err
  2474                              <1> 	;
  2475 000038D3 55                  <1> 	push	ebp ; 20/07/2015
  2476 000038D4 56                  <1> 	push	esi
  2477 000038D5 57                  <1> 	push	edi
  2478 000038D6 53                  <1> 	push	ebx
  2479 000038D7 51                  <1> 	push	ecx
  2480 000038D8 8B35[A1E30000]      <1> 	mov	esi, [u.pgdir]
  2481 000038DE 89C7                <1> 	mov	edi, eax
  2482 000038E0 50                  <1> 	push	eax ; save child's page directory address
  2483                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  2484                              <1> 	; (use same system space for all user page tables) 
  2485 000038E1 A5                  <1> 	movsd
  2486 000038E2 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2487 000038E7 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2488                              <1> cpd_0:	
  2489 000038EC AD                  <1> 	lodsd
  2490                              <1> 	;or	eax, eax
  2491                              <1>         ;jnz     short cpd_1
  2492 000038ED A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2493 000038EF 7508                <1> 	jnz	short cpd_1
  2494                              <1>  	; (virtual address at the end of the page table)	
  2495 000038F1 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2496 000038F7 EB0F                <1> 	jmp	short cpd_2
  2497                              <1> cpd_1:	
  2498 000038F9 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2499 000038FD 89C3                <1> 	mov	ebx, eax
  2500                              <1> 	; EBX = Parent's page table address
  2501 000038FF E81F000000          <1> 	call	copy_page_table
  2502 00003904 720C                <1> 	jc	short cpd_p_err
  2503                              <1> 	; EAX = Child's page table address
  2504 00003906 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  2505                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  2506                              <1> 			 ; (present, writable, user)
  2507                              <1> cpd_2:
  2508 00003908 AB                  <1> 	stosd
  2509 00003909 E2E1                <1> 	loop	cpd_0
  2510                              <1> 	;
  2511 0000390B 58                  <1> 	pop	eax  ; restore child's page directory address
  2512                              <1> cpd_3:
  2513 0000390C 59                  <1> 	pop	ecx
  2514 0000390D 5B                  <1> 	pop	ebx
  2515 0000390E 5F                  <1> 	pop	edi
  2516 0000390F 5E                  <1> 	pop	esi
  2517 00003910 5D                  <1> 	pop	ebp
  2518                              <1> cpd_err:
  2519 00003911 C3                  <1> 	retn
  2520                              <1> cpd_p_err:
  2521                              <1> 	; release the allocated pages missing (recover free space)
  2522 00003912 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2523 00003913 8B1D[A1E30000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2524 00003919 E87CF9FFFF          <1> 	call 	deallocate_page_dir
  2525 0000391E 29C0                <1> 	sub	eax, eax ; 0
  2526 00003920 F9                  <1> 	stc
  2527 00003921 EBE9                <1> 	jmp	short cpd_3	
  2528                              <1> 
  2529                              <1> copy_page_table:
  2530                              <1> 	; 19/09/2015
  2531                              <1> 	; temporary - 07/09/2015
  2532                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2533                              <1> 	;
  2534                              <1> 	; INPUT -> 
  2535                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  2536                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  2537                              <1> 	; OUTPUT ->
  2538                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  2539                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  2540                              <1> 	;	CF = 1 -> error 
  2541                              <1> 	;
  2542                              <1> 	; Modified Registers -> EBP (except EAX)
  2543                              <1> 	;
  2544 00003923 E839F8FFFF          <1> 	call	allocate_page
  2545 00003928 725A                <1> 	jc	short cpt_err
  2546                              <1> 	;
  2547 0000392A 50                  <1> 	push	eax ; *
  2548                              <1> 	;push 	ebx
  2549 0000392B 56                  <1> 	push	esi
  2550 0000392C 57                  <1> 	push	edi
  2551 0000392D 52                  <1> 	push	edx
  2552 0000392E 51                  <1> 	push	ecx
  2553                              <1> 	;
  2554 0000392F 89DE                <1> 	mov	esi, ebx
  2555 00003931 89C7                <1> 	mov	edi, eax
  2556 00003933 89C2                <1> 	mov	edx, eax
  2557 00003935 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2558                              <1> cpt_0:
  2559 0000393B AD                  <1> 	lodsd
  2560 0000393C A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2561 0000393E 750B                <1> 	jnz	short cpt_1
  2562 00003940 21C0                <1> 	and	eax, eax
  2563 00003942 7430                <1> 	jz	short cpt_2
  2564                              <1> 	; ebp = virtual (linear) address of the memory page
  2565 00003944 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2566 00003949 7234                <1> 	jc	short cpt_p_err
  2567                              <1> cpt_1:
  2568 0000394B 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2569 0000394F 89C1                <1> 	mov	ecx, eax
  2570                              <1> 	; Allocate a new page for the child process
  2571 00003951 E80BF8FFFF          <1> 	call	allocate_page
  2572 00003956 7227                <1> 	jc	short cpt_p_err
  2573 00003958 57                  <1> 	push	edi
  2574 00003959 56                  <1> 	push	esi
  2575 0000395A 89CE                <1> 	mov	esi, ecx
  2576 0000395C 89C7                <1> 	mov	edi, eax
  2577 0000395E B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2578 00003963 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2579 00003965 5E                  <1> 	pop	esi
  2580 00003966 5F                  <1> 	pop	edi
  2581                              <1> 	; 
  2582 00003967 53                  <1> 	push	ebx
  2583 00003968 50                  <1> 	push	eax
  2584 00003969 89EB                <1> 	mov	ebx, ebp
  2585                              <1> 	; ebx = virtual address of the memory page
  2586 0000396B E8E6FDFFFF          <1> 	call	add_to_swap_queue
  2587 00003970 58                  <1> 	pop	eax
  2588 00003971 5B                  <1> 	pop	ebx
  2589                              <1> 	;
  2590                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2591 00003972 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2592                              <1> cpt_2:
  2593 00003974 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2594                              <1> 	;
  2595 00003975 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2596                              <1> 	;
  2597 0000397B 39D7                <1> 	cmp	edi, edx
  2598 0000397D 72BC                <1> 	jb	short cpt_0
  2599                              <1> cpt_p_err:
  2600 0000397F 59                  <1> 	pop	ecx
  2601 00003980 5A                  <1> 	pop	edx
  2602 00003981 5F                  <1> 	pop	edi
  2603 00003982 5E                  <1> 	pop	esi
  2604                              <1> 	;pop	ebx
  2605 00003983 58                  <1> 	pop	eax ; *
  2606                              <1> cpt_err:
  2607 00003984 C3                  <1> 	retn
  2608                              <1> 
  2609                              <1> 
  2610                              <1> allocate_memory_block:
  2611                              <1> 	; 03/04/2016
  2612                              <1> 	; 02/04/2016
  2613                              <1> 	; 01/04/2016
  2614                              <1> 	; 14/03/2016
  2615                              <1> 	; 13/03/2016
  2616                              <1> 	; 12/03/2016 (TRDOS 386 = TRDOS v2.0)
  2617                              <1> 	; Allocating contiguous memory pages (in the kernel's memory space)
  2618                              <1> 	;
  2619                              <1> 	; INPUT -> 
  2620                              <1> 	;	EAX = Beginning address (physical)
  2621                              <1> 	;	EAX = 0 -> Allocate memory block from the first proper aperture	
  2622                              <1> 	;	ECX = Number of bytes to be allocated
  2623                              <1> 	;
  2624                              <1> 	; OUTPUT ->
  2625                              <1> 	; 	1) cf = 0 -> successful
  2626                              <1> 	;	EAX = Beginning (physical) address of the allocated memory block
  2627                              <1> 	;	ECX = Number of allocated bytes (rounded up to page borders) 
  2628                              <1> 	;	2) cf = 1 -> unsuccessful
  2629                              <1> 	;	 2.1) If EAX > 0 -> 
  2630                              <1> 	;	      (Number of requested pages is more than # of free pages
  2631                              <1> 	;	       but contiguous free pages -the aperture- is not enough!)	   	
  2632                              <1> 	;	      EAX = Beginning address of available aperture
  2633                              <1> 	;		    (one of all aperture with max. aperture size/length)		
  2634                              <1> 	;	      ECX = Size of available aperture (memory block) in bytes
  2635                              <1> 	;	 2.2) If EAX = 0 -> Out of memory error 
  2636                              <1> 	;	            (number of free pages is less than requested number)
  2637                              <1> 	;	      ECX = Total number of free bytes (free pages * 4096) 
  2638                              <1> 	;		    (It is not number of contiguous free bytes)	
  2639                              <1> 	;
  2640                              <1> 	; (Modified Registers -> EAX, ECX)
  2641                              <1> 	;
  2642                              <1> 	; PURPOSE: Loading a file at memory for copying or running etc.
  2643                              <1> 	; If this procedure returns with cf is set, ECX contains maximum
  2644                              <1> 	; available space and EAX contains the beginning address of it.
  2645                              <1> 	; If EAX has zero, ECX contains total number of free bytes.
  2646                              <1> 	; If requested block has been successfully allocated (by rounding up to
  2647                              <1> 	; the last page border), it must be deallocated later by using
  2648                              <1> 	; 'dealloacate_memory_block' procedure.    
  2649                              <1> 
  2650 00003985 52                  <1> 	push	edx ; *
  2651 00003986 BAFF0F0000          <1> 	mov	edx, PAGE_SIZE - 1   ; 4095
  2652 0000398B 01D1                <1> 	add	ecx, edx
  2653 0000398D 01D0                <1> 	add	eax, edx
  2654 0000398F C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2655                              <1> 
  2656                              <1> 	; ECX = number of contiguous pages to be allocated
  2657 00003992 8B15[90D20000]      <1> 	mov	edx, [free_pages]
  2658 00003998 39D1                <1> 	cmp	ecx, edx
  2659 0000399A 7775                <1> 	ja	short amb_6
  2660                              <1> 
  2661 0000399C C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; 12
  2662                              <1> 
  2663 0000399F 89C2                <1> 	mov	edx, eax 	     ; page number
  2664 000039A1 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2665                              <1> 				     ; (1 allocation bit = 1 page)
  2666                              <1> 				     ; (1 allocation bytes = 8 pages)
  2667 000039A4 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2668                              <1> 				     ; (to get 32 bit position)	
  2669 000039A7 53                  <1> 	push	ebx ; **
  2670                              <1> amb_0:
  2671 000039A8 890D[44DF0000]      <1> 	mov	[mem_ipg_count], ecx ; initial (reset) value of page count
  2672 000039AE 890D[48DF0000]      <1> 	mov	[mem_pg_count], ecx
  2673 000039B4 31C9                <1> 	xor	ecx, ecx ; 0
  2674 000039B6 890D[4CDF0000]      <1> 	mov	[mem_aperture], ecx ; 0
  2675 000039BC 890D[50DF0000]      <1> 	mov	[mem_max_aperture], ecx ; 0
  2676                              <1> 	
  2677 000039C2 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address.
  2678 000039C7 3B15[94D20000]      <1> 	cmp	edx, [next_page]     ; Is the beginning page address lower
  2679                              <1> 				     ; than the address in 'next_page' ?
  2680                              <1> 				     ; (the first/next free page of user space)		
  2681 000039CD 7208                <1> 	jb	short amb_1
  2682 000039CF 3B15[98D20000]      <1> 	cmp 	edx, [last_page]     ; is the beginning page address higher
  2683                              <1> 				     ; than the address in 'last_page' ?
  2684                              <1> 				     ; (end of the memory)		
  2685 000039D5 7606                <1> 	jna	short amb_2	     ; no	
  2686                              <1> amb_1:
  2687 000039D7 8B15[94D20000]      <1> 	mov	edx, [next_page]     ; yes (reset to the first page of user space)
  2688                              <1> amb_2:
  2689 000039DD 01D3                <1> 	add	ebx, edx
  2690                              <1> 
  2691 000039DF A3[54DF0000]        <1> 	mov	[mem_pg_pos], eax    ; beginning page no (for curr. mem. aperture)
  2692 000039E4 A3[58DF0000]        <1>  	mov	[mem_max_pg_pos], eax ; beginning page no for max. mem. aperture
  2693                              <1> 
  2694 000039E9 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only (0 to 31)
  2695                              <1> 				     ; (allocation bit position)	 
  2696 000039EC 744B                <1> 	jz	short amb_10	     ; 0	
  2697                              <1> amb_3:
  2698 000039EE 8B13                <1> 	mov	edx, [ebx]
  2699 000039F0 88C1                <1> 	mov	cl, al ; 1 to 31
  2700 000039F2 D3EA                <1> 	shr	edx, cl
  2701 000039F4 89D0                <1> 	mov	eax, edx
  2702                              <1> amb_4:
  2703 000039F6 D1E8                <1> 	shr	eax, 1 ; (***)
  2704 000039F8 7321                <1> 	jnc	short amb_7
  2705 000039FA FF05[4CDF0000]      <1> 	inc	dword [mem_aperture]
  2706 00003A00 FF0D[48DF0000]      <1> 	dec	dword [mem_pg_count]
  2707 00003A06 747B                <1> 	jz	short amb_15
  2708                              <1> amb_5:
  2709 00003A08 80F91F              <1> 	cmp	cl, 31
  2710 00003A0B 7317                <1> 	jnb	short amb_8
  2711 00003A0D FEC1                <1> 	inc	cl
  2712 00003A0F EBE5                <1> 	jmp	short amb_4
  2713                              <1> 
  2714                              <1> amb_6:	; out_of_memory
  2715 00003A11 31C0                <1> 	xor	eax, eax ; 0
  2716 00003A13 89D1                <1> 	mov	ecx, edx ; free pages
  2717 00003A15 C1E10C              <1> 	shl	ecx, PAGE_SHIFT
  2718 00003A18 5A                  <1> 	pop	edx ; *
  2719 00003A19 F9                  <1> 	stc
  2720 00003A1A C3                  <1> 	retn
  2721                              <1> amb_7:
  2722 00003A1B 50                  <1> 	push	eax ; (***) allocation bits (in shifted status)
  2723 00003A1C E819010000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2724 00003A21 58                  <1> 	pop	eax ; (***)
  2725 00003A22 EBE4                <1> 	jmp	short amb_5
  2726                              <1> amb_8:
  2727 00003A24 28C9                <1> 	sub	cl, cl ; 0
  2728                              <1> amb_9:
  2729 00003A26 89DA                <1> 	mov	edx, ebx
  2730 00003A28 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL
  2731 00003A2E 3B15[98D20000]      <1> 	cmp	edx, [last_page]
  2732 00003A34 7336                <1> 	jnb	short amb_14 ; contiguous pages not enough
  2733 00003A36 83C304              <1> 	add	ebx, 4
  2734                              <1> amb_10:
  2735 00003A39 8B03                <1> 	mov	eax, [ebx]
  2736 00003A3B 21C0                <1> 	and 	eax, eax
  2737 00003A3D 7406                <1>         jz      short amb_11 ; there is not a free page bit in this alloc dword
  2738 00003A3F 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0
  2739 00003A40 740A                <1> 	jz	short amb_12 ; all of bits are set (32 free pages)
  2740 00003A42 48                  <1> 	dec	eax
  2741 00003A43 EBB1                <1> 	jmp	short amb_4
  2742                              <1> amb_11:
  2743 00003A45 E8F0000000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2744 00003A4A EBDA                <1> 	jmp	short amb_9	
  2745                              <1> amb_12:
  2746 00003A4C B120                <1> 	mov	cl, 32
  2747 00003A4E 390D[48DF0000]      <1> 	cmp	[mem_pg_count], ecx ; 32
  2748 00003A54 7306                <1> 	jnb	short amb_13
  2749 00003A56 8B0D[48DF0000]      <1> 	mov	ecx, [mem_pg_count]
  2750                              <1> amb_13:
  2751 00003A5C 010D[4CDF0000]      <1> 	add	[mem_aperture], ecx
  2752 00003A62 290D[48DF0000]      <1> 	sub	[mem_pg_count], ecx
  2753 00003A68 7619                <1> 	jna	short amb_15
  2754 00003A6A EBB8                <1> 	jmp	short amb_8
  2755                              <1> amb_14:
  2756 00003A6C A1[58DF0000]        <1> 	mov	eax, [mem_max_pg_pos] ; begin address of max. mem aperture	
  2757 00003A71 8B0D[50DF0000]      <1> 	mov	ecx, [mem_max_aperture] ; max. (largest) memory aperture
  2758 00003A77 C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2759 00003A7A C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2760 00003A7D F9                  <1> 	stc
  2761 00003A7E E9AC000000          <1>         jmp     amb_25
  2762                              <1> 
  2763                              <1> amb_15: ; OK !
  2764 00003A83 A1[54DF0000]        <1> 	mov	eax, [mem_pg_pos]    ; Beginning address as page number
  2765 00003A88 8B0D[4CDF0000]      <1> 	mov	ecx, [mem_aperture]  ; Free contiguous page count
  2766                              <1> amb_16:
  2767                              <1> 	; allocate contiguous memory pages (via memory allocation table bits)
  2768 00003A8E 89C2                <1> 	mov	edx, eax
  2769 00003A90 C1EA05              <1> 	shr	edx, 5 ; 32 pages in one allocation dword (32 bits)
  2770 00003A93 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2771 00003A98 01D3                <1> 	add	ebx, edx
  2772 00003A9A 83E01F              <1> 	and	eax, 1Fh ; 31
  2773                              <1> 	; 03/04/2016
  2774 00003A9D BA20000000          <1> 	mov	edx, 32
  2775 00003AA2 28C2                <1> 	sub	dl, al
  2776 00003AA4 39CA                <1> 	cmp	edx, ecx
  2777 00003AA6 7602                <1> 	jna	short amb_17
  2778 00003AA8 89CA                <1> 	mov	edx, ecx
  2779                              <1> amb_17:
  2780 00003AAA 29D1                <1> 	sub	ecx, edx
  2781 00003AAC 51                  <1> 	push	ecx ; ***
  2782 00003AAD 89D1                <1> 	mov	ecx, edx
  2783                              <1> amb_18:		
  2784 00003AAF 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2785                              <1> 				 ; is copied into the Carry Flag and then cleared
  2786                              <1> 				 ; in the destination.
  2787 00003AB2 FF0D[90D20000]      <1> 	dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2788 00003AB8 49                  <1> 	dec	ecx
  2789 00003AB9 7404                <1> 	jz	short amb_19
  2790 00003ABB FEC0                <1> 	inc	al
  2791 00003ABD EBF0                <1> 	jmp	short amb_18
  2792                              <1> amb_19:	
  2793 00003ABF 59                  <1> 	pop	ecx ; ***
  2794 00003AC0 21C9                <1> 	and	ecx, ecx ; 0 ?
  2795 00003AC2 741E                <1> 	jz	short amb_22	
  2796                              <1> 	; 01/04/2016
  2797 00003AC4 B020                <1> 	mov	al, 32
  2798                              <1> amb_20:
  2799 00003AC6 83C304              <1> 	add	ebx, 4
  2800 00003AC9 39C1                <1> 	cmp	ecx, eax ; 32
  2801 00003ACB 7305                <1> 	jnb	short amb_21
  2802                              <1> 	; ECX < 32
  2803 00003ACD 28C0                <1> 	sub	al, al ; 0
  2804 00003ACF 50                  <1> 	push	eax ; 0 ***
  2805 00003AD0 EBDD                <1> 	jmp	short amb_18
  2806                              <1> amb_21:
  2807 00003AD2 2905[90D20000]      <1> 	sub	[free_pages], eax ; [free_pages] = [free_pages] - 32
  2808 00003AD8 C70300000000        <1> 	mov	dword [ebx], 0 ; reset 32 bits
  2809 00003ADE 29C1                <1> 	sub	ecx, eax ; 32
  2810 00003AE0 75E4                <1> 	jnz	short amb_20
  2811                              <1> amb_22:
  2812 00003AE2 A1[54DF0000]        <1> 	mov	eax, [mem_pg_pos]   ; Beginning address as page number
  2813 00003AE7 8B0D[4CDF0000]      <1> 	mov	ecx, [mem_aperture] ; Free contiguous page count
  2814                              <1> 	; [next_page] update
  2815 00003AED 89C2                <1> 	mov	edx, eax
  2816                              <1> 	; 03/04/2016
  2817 00003AEF C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2818                              <1> 				     ; (1 allocation bit = 1 page)
  2819                              <1> 				     ; (1 allocation bytes = 8 pages)
  2820 00003AF2 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2821                              <1> 				     ; (to get 32 bit position)	
  2822 00003AF5 3B15[94D20000]      <1> 	cmp	edx, [next_page] ; first free page pointer offset
  2823 00003AFB 7732                <1> 	ja	short amb_25
  2824 00003AFD BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2825 00003B02 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2826 00003B06 7721                <1> 	ja	short amb_24
  2827 00003B08 89C2                <1> 	mov	edx, eax
  2828 00003B0A 01CA                <1> 	add	edx, ecx
  2829 00003B0C C1EA03              <1> 	shr	edx, 3
  2830 00003B0F 80E2FC              <1> 	and	dl, 0FCh
  2831                              <1> amb_23:
  2832 00003B12 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2833 00003B16 7711                <1> 	ja	short amb_24
  2834 00003B18 83C204              <1> 	add	edx, 4
  2835 00003B1B 3B15[98D20000]      <1> 	cmp	edx, [last_page]    ; last page pointer offset
  2836 00003B21 76EF                <1> 	jna	short amb_23
  2837 00003B23 8B15[9CD20000]      <1> 	mov	edx, [first_page]   ; (for) beginning of user's space
  2838                              <1> amb_24:
  2839 00003B29 8915[94D20000]      <1> 	mov	[next_page], edx
  2840                              <1> amb_25:
  2841 00003B2F 9C                  <1> 	pushf
  2842 00003B30 C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2843 00003B33 C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2844 00003B36 9D                  <1> 	popf
  2845 00003B37 5B                  <1> 	pop	ebx ; **
  2846 00003B38 5A                  <1> 	pop	edx ; *
  2847 00003B39 C3                  <1> 	retn
  2848                              <1> 
  2849                              <1> amb_26:	; set maximum free memory aperture (free memory block size) 
  2850 00003B3A 89DA                <1> 	mov	edx, ebx ; current address
  2851 00003B3C 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL ; MAT beginning address
  2852                              <1> 	; 02/04/2016 
  2853 00003B42 C1E203              <1> 	shl	edx, 3 ; MAT byte offset * 8 = page number base
  2854 00003B45 01CA                <1> 	add	edx, ecx ; current page number (ecx =  0 to 31)
  2855                              <1> 	;
  2856 00003B47 A1[4CDF0000]        <1> 	mov	eax, [mem_aperture]
  2857 00003B4C 21C0                <1> 	and	eax, eax
  2858 00003B4E 7424                <1>         jz      short amb_27
  2859 00003B50 C705[4CDF0000]0000- <1>         mov     dword [mem_aperture], 0
  2859 00003B58 0000                <1>
  2860 00003B5A 3B05[50DF0000]      <1> 	cmp	eax, [mem_max_aperture]
  2861 00003B60 7612                <1> 	jna	short amb_27
  2862 00003B62 A3[50DF0000]        <1> 	mov	[mem_max_aperture], eax
  2863                              <1> 	;
  2864 00003B67 89D0                <1> 	mov	eax, edx
  2865 00003B69 2B05[50DF0000]      <1> 	sub	eax, [mem_max_aperture] ; the last aperture size in pages
  2866                              <1> 	; EAX = Beginning page number of the max. aperture 
  2867 00003B6F A3[58DF0000]        <1> 	mov	[mem_max_pg_pos], eax
  2868                              <1> amb_27: 
  2869 00003B74 42                  <1> 	inc	edx	
  2870 00003B75 8915[54DF0000]      <1> 	mov	[mem_pg_pos], edx ; next page
  2871                              <1> 
  2872 00003B7B A1[44DF0000]        <1> 	mov	eax, [mem_ipg_count] ; initial (reset) value of page count
  2873 00003B80 A3[48DF0000]        <1> 	mov	[mem_pg_count], eax
  2874                              <1> 
  2875 00003B85 C3                  <1> 	retn
  2876                              <1> 
  2877                              <1> deallocate_memory_block:
  2878                              <1> 	; 03/04/2016
  2879                              <1> 	; 14/03/2016 (TRDOS 386 = TRDOS v2.0)
  2880                              <1> 	; Deallocating contiguous memory pages (in the kernel's memory space)
  2881                              <1> 	;
  2882                              <1> 	; INPUT -> 
  2883                              <1> 	;	EAX = Beginning address (physical)
  2884                              <1> 	;	ECX = Number of bytes to be deallocated
  2885                              <1> 	;
  2886                              <1> 	; OUTPUT ->
  2887                              <1> 	;	Mememory Allocation Table bits will be updated
  2888                              <1> 	;	[free_pages] will be changed (increased)
  2889                              <1> 	;
  2890                              <1> 	; (Modified Registers -> EAX, ECX)
  2891                              <1> 	;
  2892                              <1> 	; PURPOSE: Unloading/Freeing a file -or an allocated memory block- 
  2893                              <1> 	; at memory after copying, running, saving, reading, writing etc.
  2894                              <1> 	;
  2895                              <1> 
  2896 00003B86 52                  <1> 	push	edx ; *
  2897 00003B87 53                  <1> 	push	ebx ; **
  2898                              <1> 
  2899 00003B88 C1E80C              <1> 	shr	eax, PAGE_SHIFT	     ; 12
  2900 00003B8B C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2901                              <1> 
  2902                              <1> 	; EAX = Beginning page number
  2903                              <1> 	; ECX = Number of contiguous pages to be deallocated
  2904                              <1> damb_0:
  2905                              <1> 	; deallocate contiguous memory pages (via memory allocation table bits)
  2906 00003B8E 89C2                <1> 	mov	edx, eax
  2907 00003B90 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2908                              <1> 				     ; (1 allocation bit = 1 page)
  2909                              <1> 				     ; (1 allocation bytes = 8 pages)
  2910 00003B93 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2911                              <1> 				     ; (to get 32 bit position)	
  2912 00003B96 3B15[94D20000]      <1> 	cmp	edx, [next_page] ; next free page
  2913 00003B9C 7306                <1> 	jnb	short damb_1
  2914 00003B9E 8915[94D20000]      <1> 	mov	[next_page], edx
  2915                              <1> damb_1:
  2916 00003BA4 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2917 00003BA9 01D3                <1> 	add	ebx, edx
  2918 00003BAB 83E01F              <1> 	and	eax, 1Fh ; 31
  2919                              <1> 
  2920                              <1> 	; 03/04/2016
  2921 00003BAE BA20000000          <1> 	mov	edx, 32
  2922 00003BB3 28C2                <1> 	sub	dl, al
  2923 00003BB5 39CA                <1> 	cmp	edx, ecx
  2924 00003BB7 7602                <1> 	jna	short damb_2
  2925 00003BB9 89CA                <1> 	mov	edx, ecx
  2926                              <1> damb_2:
  2927 00003BBB 29D1                <1> 	sub	ecx, edx
  2928 00003BBD 51                  <1> 	push	ecx ; ***
  2929 00003BBE 89D1                <1> 	mov	ecx, edx
  2930                              <1> damb_3:		
  2931 00003BC0 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
  2932                              <1> 				     ; set relevant bit to 1.
  2933                              <1> 				     ; set CF to the previous bit value	
  2934 00003BC3 FF05[90D20000]      <1> 	inc     dword [free_pages]   ; 1 page has been deallocated (X = X+1) 
  2935 00003BC9 49                  <1> 	dec	ecx
  2936 00003BCA 7404                <1> 	jz	short damb_4
  2937 00003BCC FEC0                <1> 	inc	al
  2938 00003BCE EBF0                <1> 	jmp	short damb_3
  2939                              <1> damb_4:	
  2940 00003BD0 59                  <1> 	pop	ecx ; ***
  2941 00003BD1 21C9                <1> 	and	ecx, ecx ; 0 ?
  2942 00003BD3 741E                <1> 	jz	short damb_7
  2943                              <1> 	; 03/04/2016
  2944 00003BD5 B020                <1> 	mov	al, 32
  2945                              <1> damb_5:
  2946 00003BD7 83C304              <1> 	add	ebx, 4
  2947 00003BDA 39C1                <1> 	cmp	ecx, eax ; 32
  2948 00003BDC 7305                <1> 	jnb	short damb_6
  2949                              <1> 	; ECX < 32
  2950 00003BDE 28C0                <1> 	sub	al, al ; 0
  2951 00003BE0 50                  <1> 	push	eax ; 0 ***
  2952 00003BE1 EBDD                <1> 	jmp	short damb_3
  2953                              <1> damb_6:
  2954 00003BE3 0105[90D20000]      <1> 	add	[free_pages], eax ; [free_pages] = [free_pages] + 32
  2955 00003BE9 C703FFFFFFFF        <1> 	mov	dword [ebx], 0FFFFFFFFh ; set 32 bits
  2956 00003BEF 29C1                <1> 	sub	ecx, eax ; 32
  2957 00003BF1 75E4                <1> 	jnz	short damb_5
  2958                              <1> damb_7:
  2959 00003BF3 5B                  <1> 	pop	ebx ; **
  2960 00003BF4 5A                  <1> 	pop	edx ; *
  2961 00003BF5 C3                  <1> 	retn
  2962                              <1> 
  2963                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  2964                              <1> 
  2965                              <1> ;; Data:
  2966                              <1> 
  2967                              <1> ; 09/03/2015
  2968                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  2969                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  2970                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2971                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2972                              <1> ;swpd_next:  dd 0 ; next free page block
  2973                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
  1874                                  %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/05/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 00003BF6 9C                  <1> 	pushfd
    30 00003BF7 0E                  <1> 	push 	cs
    31 00003BF8 E801000000          <1> 	call 	TIME_OF_DAY_1
    32 00003BFD 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/05/2016
    98                              <1> ; 29/01/2016
    99                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   100                              <1> 
   101                              <1> ; 29/05/2016
   102                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   103                              <1> int35h:  ; Date/Time functions
   104                              <1> 
   105                              <1> TIME_OF_DAY_1:
   106 00003BFE FB                  <1> 	sti				; INTERRUPTS BACK ON
   107                              <1> 	; 29/05/2016
   108 00003BFF 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   109                              <1> 	;
   110 00003C04 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   111 00003C07 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   112                              <1> 	; (*) jc short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   113 00003C08 721C                <1> 	jc	short _TIME_9 ; 29/05/2016
   114                              <1> 
   115 00003C0A 1E                  <1> 	push	ds
   116 00003C0B 56                  <1> 	push	esi
   117 00003C0C 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   118 00003C10 8EDE                <1> 	mov	ds, si
   119 00003C12 C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   120 00003C15 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   121 00003C18 FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   122 00003C19 FF96[2C3C0000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   123                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   124 00003C1F FB                  <1> 	sti				; INTERRUPTS BACK ON
   125 00003C20 B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   126 00003C22 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   127 00003C23 1F                  <1> 	pop	ds			; RECOVER USERS SEGMENT SELECTOR
   128                              <1> ;TIME_9:
   129                              <1> 					; RETURN WITH CY= 0 IF NO ERROR
   130                              <1> 	; (*) 29/05/2016
   131                              <1> 	; (*) retf 4 ; skip eflags on stack
   132 00003C24 7305                <1> 	jnc	short _TIME_10
   133                              <1> _TIME_9:
   134                              <1> 	; 29/05/2016 -set carry flag on stack-
   135                              <1> 	; [esp] = EIP
   136                              <1> 	; [esp+4] = CS
   137                              <1> 	; [esp+8] = E-FLAGS
   138 00003C26 804C240801          <1> 	or	byte [esp+8], 1	 ; set carry bit of eflags register
   139                              <1> 	; [esp+12] = ESP (user)
   140                              <1> 	; [esp+16] = SS (User)
   141                              <1> _TIME_10:
   142 00003C2B CF                  <1> 	iretd
   143                              <1> 	
   144                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
   145                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
   146                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
   147                              <1> 	; // RETF instruction:
   148                              <1> 	;
   149                              <1> 	; IF OperandMode=32 THEN
   150                              <1>  	;    Load CS:EIP from stack;
   151                              <1>  	;    Set CS RPL to CPL;
   152                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
   153                              <1>  	;    Load SS:eSP from stack;
   154                              <1>  	; ELSE (* OperandMode=16 *)
   155                              <1>  	;    Load CS:IP from stack;
   156                              <1>  	;    Set CS RPL to CPL;
   157                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
   158                              <1> 	;    Load SS:eSP from stack;
   159                              <1>  	; FI;
   160                              <1> 	;
   161                              <1> 	; //					
   162                              <1> 					; ROUTINE VECTOR TABLE (AH)=
   163                              <1> RTC_TB:
   164 00003C2C [4C3C0000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   165 00003C30 [5F3C0000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   166 00003C34 [6D3C0000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   167 00003C38 [9C3C0000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   168 00003C3C [DE3C0000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   169 00003C40 [0B3D0000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   170 00003C44 [583D0000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   171 00003C48 [AB3D0000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   172                              <1> 
   173                              <1> RTC_TBE	equ	$
   174                              <1> 
   175                              <1> RTC_00:				; READ TIME COUNT
   176 00003C4C A0[0ED30000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   177 00003C51 C605[0ED30000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   178 00003C58 8B0D[0AD30000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   179 00003C5E C3                  <1> 	retn
   180                              <1> 
   181                              <1> RTC_10:				; SET TIME COUNT
   182 00003C5F 890D[0AD30000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   183 00003C65 C605[0ED30000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   184 00003C6C C3                  <1> 	retn				; RETURN WITH NO CARRY
   185                              <1> 
   186                              <1> RTC_20:				; GET RTC TIME
   187 00003C6D E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   188 00003C72 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   189                              <1> 
   190 00003C74 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   191 00003C76 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   192 00003C7B 88C6                <1> 	mov	dh, al			; SAVE
   193 00003C7D B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   194 00003C7F E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   195 00003C84 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   196 00003C86 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   197 00003C88 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   198 00003C8A E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   199 00003C8F 88C1                <1> 	mov	cl, al			; SAVE
   200 00003C91 B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   201 00003C93 E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   202 00003C98 88C5                <1> 	mov	ch, al			; SAVE
   203 00003C9A F8                  <1> 	clc				; SET CY= 0
   204                              <1> RTC_29:
   205 00003C9B C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   206                              <1> 
   207                              <1> RTC_30:				; SET RTC TIME
   208 00003C9C E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   209 00003CA1 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   210 00003CA3 E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   211                              <1> RTC_35:
   212 00003CA8 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   213 00003CAA B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   214 00003CAC E8E0010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   215 00003CB1 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   216 00003CB3 B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   217 00003CB5 E8D7010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   218 00003CBA 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   219 00003CBC B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   220 00003CBE E8CE010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   221                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   222                              <1> 	;mov	ah, al
   223 00003CC3 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   224 00003CC7 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   225 00003CCC 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   226 00003CCE 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   227 00003CD0 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   228 00003CD3 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   229 00003CD5 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   230 00003CD7 E8B5010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   231 00003CDC F8                  <1> 	clc				; SET CY= 0
   232 00003CDD C3                  <1> 	retn				; RETURN WITH CY= 0
   233                              <1> 
   234                              <1> RTC_40:				; GET RTC DATE
   235 00003CDE E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   236 00003CE3 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   237                              <1> 
   238 00003CE5 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   239 00003CE7 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   240 00003CEC 88C2                <1> 	mov	dl, al			; SAVE
   241 00003CEE B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   242 00003CF0 E883010000          <1> 	call	CMOS_READ		; READ MONTH
   243 00003CF5 88C6                <1> 	mov	dh, al			; SAVE
   244 00003CF7 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   245 00003CF9 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   246 00003CFE 88C1                <1> 	mov	cl, al			; SAVE
   247 00003D00 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   248 00003D02 E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   249 00003D07 88C5                <1> 	mov	ch, al			; SAVE
   250 00003D09 F8                  <1> 	clc				; SET CY=0
   251                              <1> RTC_49:
   252 00003D0A C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   253                              <1> 
   254                              <1> RTC_50:				; SET RTC DATE
   255 00003D0B E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   256 00003D10 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   257 00003D12 E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   258                              <1> RTC_55:
   259 00003D17 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   260 00003D1B E871010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   261 00003D20 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   262 00003D22 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   263 00003D24 E868010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   264 00003D29 88F4                <1> 	mov	ah, dh			; GET MONTH
   265 00003D2B B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   266 00003D2D E85F010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   267 00003D32 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   268 00003D34 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   269 00003D36 E856010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   270 00003D3B 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   271 00003D3D B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   272 00003D3F E84D010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   273                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   274                              <1> 	;mov	ah, al
   275 00003D44 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   276 00003D48 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   277 00003D4D 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   278 00003D4F 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   279 00003D51 E83B010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   280 00003D56 F8                  <1> 	clc				; SET CY= 0
   281 00003D57 C3                  <1> 	retn				; RETURN CY=0
   282                              <1> 
   283                              <1> RTC_60:				; SET RTC ALARM
   284 00003D58 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   285 00003D5A E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   286 00003D5F A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   287 00003D61 F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   288 00003D62 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   289 00003D64 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   290 00003D69 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   291 00003D6B E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   292                              <1> RTC_65:	
   293 00003D70 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   294 00003D72 B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   295 00003D74 E818010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   296 00003D79 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   297 00003D7B B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   298 00003D7D E80F010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   299 00003D82 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   300 00003D84 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   301 00003D86 E806010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   302 00003D8B E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   303 00003D8D 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   304 00003D8F E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   305                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   306                              <1> 	;mov	ah, al
   307 00003D91 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   308 00003D95 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   309 00003D9A 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   310 00003D9C 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   311 00003D9E 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   312 00003DA0 E8EC000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   313 00003DA5 F8                  <1> 	clc				; SET CY= 0
   314                              <1> RTC_69:
   315 00003DA6 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   316 00003DAA C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAC
   317                              <1> 
   318                              <1> RTC_70:				; RESET ALARM
   319                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   320                              <1> 	;mov	ah, al
   321 00003DAB 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   322 00003DAF E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   323 00003DB4 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   324 00003DB6 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   325 00003DB8 E8D4000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   326 00003DBD F8                  <1> 	clc				; SET CY= 0
   327 00003DBE C3                  <1> 	retn				; RETURN WITH NO CARRY
   328                              <1> 
   329                              <1> RTC_STA:			; INITIALIZE REAL TIME CLOCK
   330                              <1> 	;mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK		
   331                              <1> 	;mov	ah, 26h
   332 00003DBF 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   333 00003DC3 E8C9000000          <1> 	call	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
   334                              <1> 	;mov	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION	
   335                              <1> 	;mov	ah, 82h
   336 00003DC8 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   337 00003DCC E8C0000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   338 00003DD1 B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   339 00003DD3 E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   340 00003DD8 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   341 00003DDA E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   342 00003DDF C3                  <1> 	retn
   343                              <1> 
   344                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   345                              <1> 
   346                              <1> ;--- HARDWARE INT  70 H -- ( IRQ LEVEL  8) --------------------------------------
   347                              <1> ; ALARM INTERRUPT HANDLER (RTC)							:
   348                              <1> ;       THIS ROUTINE HANDLES THE PERIODIC AND ALARM INTERRUPTS FROM THE CMOS	:
   349                              <1> ;       TIMER. INPUT FREQUENCY IS 1.024 KHZ OR APPROXIMATELY 1024 INTERRUPTS	:
   350                              <1> ;       EVERY SECOND FOR THE PERIODIC INTERRUPT. FOR THE ALARM FUNCTION,	:
   351                              <1> ;       THE INTERRUPT WILL OCCUR AT THE DESIGNATED TIME.			:
   352                              <1> ;										:
   353                              <1> ;       INTERRUPTS ARE ENABLED WHEN THE EVENT OR ALARM FUNCTION IS ACTIVATED.	:
   354                              <1> ;       FOR THE EVENT INTERRUPT, THE HANDLER WILL DECREMENT THE WAIT COUNTER	:
   355                              <1> ;       AND WHEN IT EXPIRES WILL SET THE DESIGNATED LOCATION TO 80H. FOR	:
   356                              <1> ;       THE ALARM INTERRUPT. THE USER MUST PROVIDE A ROUTINE TO INTERCEPT	:
   357                              <1> ;       THE CORRECT ADDRESS FROM THE VECTOR TABLE INVOKED BY INTERRUPT 4AH	:
   358                              <1> ;       PRIOR TO SETTING THE REAL TIME CLOCK ALARM (INT 1AH, AH= 06H).		:
   359                              <1> ;--------------------------------------------------------------------------------
   360                              <1> 
   361                              <1> RTC_INT:			; ALARM INTERRUPT
   362 00003DE0 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   363 00003DE1 50                  <1> 	push	eax			; SAVE REGISTERS
   364 00003DE2 57                  <1> 	push	edi
   365                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   366 00003DE3 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   367 00003DE7 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   368 00003DE9 90                  <1> 	nop				; I/O DELAY
   369 00003DEA EB00                <1> 	jmp	short $+2
   370 00003DEC E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   371 00003DEE A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   372 00003DF0 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   373                              <1> 
   374 00003DF2 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   375 00003DF4 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   376 00003DF6 90                  <1> 	nop				; I/O DELAY
   377 00003DF7 EB00                <1> 	jmp	short $+2	
   378 00003DF9 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   379 00003DFB 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   380 00003DFD A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   381 00003DFF 743B                <1> 	jz	short RTC_I_5		; SKIP IF NOT A PERIODIC INTERRUPT
   382                              <1> 
   383                              <1> ;-----	DECREMENT WAIT COUNT BY INTERRUPT INTERVAL
   384                              <1> 
   385 00003E01 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   386 00003E05 8EDF                <1> 	mov	ds, di
   387                              <1> 	
   388 00003E07 812D[02D30000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   388 00003E0F 0000                <1>
   389 00003E11 7329                <1> 	jnc	short RTC_I_5		; SKIP TILL 32 BIT WORD LESS THAN ZERO
   390                              <1> 
   391                              <1> ;-----	TURN OFF PERIODIC INTERRUPT ENABLE
   392                              <1> 
   393 00003E13 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   394 00003E15 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   395 00003E19 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   396 00003E1B 90                  <1> 	nop				; I/O DELAY
   397 00003E1C EB00                <1> 	jmp	short $+2
   398 00003E1E E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   399 00003E20 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   400 00003E22 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   401 00003E24 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   402 00003E26 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   403 00003E28 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   404 00003E2A C605[06D30000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   405 00003E31 8B3D[07D30000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   406 00003E37 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   407 00003E3A 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   408                              <1> RTC_I_5:
   409 00003E3C A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   410 00003E3E 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   411                              <1> 
   412 00003E40 B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   413 00003E42 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   414 00003E44 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   415 00003E45 52                  <1> 	push	edx
   416 00003E46 E871810000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   417 00003E4B 5A                  <1> 	pop	edx
   418 00003E4C FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   419                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   420 00003E4D EB94                <1> 	jmp	short RTC_I_1		;  ENTRY AND SECOND EVENT BEFORE DONE
   421                              <1> 
   422                              <1> RTC_I_9:				; EXIT - NO PENDING INTERRUPTS
   423 00003E4F B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   424 00003E51 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   425 00003E53 B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   426 00003E55 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   427 00003E57 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   428 00003E59 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   429 00003E5A 58                  <1> 	pop	eax
   430 00003E5B 1F                  <1> 	pop	ds
   431 00003E5C CF                  <1> 	iret				; END OF INTERRUPT
   432                              <1> 
   433                              <1> 	
   434                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
   435                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   436                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
   437                              <1> UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
   438 00003E5D 51                  <1> 	push	ecx
   439                              <1> 
   440                              <1> 	; 29/05/2016
   441 00003E5E B968110000          <1> 	mov	ecx, ((1984+244)*4)/2	; AWARD BIOS 1999, ATIME.ASM		
   442                              <1> 					; 'WAITCPU_CK_UD_STAT'
   443                              <1> 					; (244Us + 1984Us)
   444                              <1> 					; (assume each read takes
   445                              <1> 					;  2 microseconds).
   446                              <1> 	;mov	ecx, 65535		
   447                              <1> 		;mov cx, 800		; SET TIMEOUT LOOP COUNT (= 800)	
   448                              <1> UPD_10:
   449 00003E63 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   450 00003E65 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   451 00003E66 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   452 00003E6B A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   453 00003E6D 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   454 00003E6F FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   455 00003E70 E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   456 00003E72 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   457                              <1> 		; xor ax, ax
   458 00003E74 F9                  <1> 	stc				; SET CARRY FOR ERROR
   459                              <1> UPD_90:
   460 00003E75 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   461 00003E76 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   462 00003E77 C3                  <1> 	retn				; RETURN WITH CY FLAG SET
   463                              <1> 
   464                              <1> 
   465                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0) 
   466                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   467                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
   468                              <1> 
   469                              <1> ;--- CMOS_READ -----------------------------------------------------------------
   470                              <1> ;		READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE	       :
   471                              <1> ;									       :
   472                              <1> ; INPUT: (AL)=	CMOS_TABLE ADDRESS TO BE READ				       :
   473                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   474                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ		       :
   475                              <1> ;									       :
   476                              <1> ; OUTPUT: (AL)	VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS   :
   477                              <1> ;		ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND   :
   478                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   479                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   480                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   481                              <1> ;		ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED.	       :
   482                              <1> ;-------------------------------------------------------------------------------
   483                              <1> 
   484                              <1> CMOS_READ:
   485 00003E78 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   486 00003E79 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   487 00003E7B F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   488 00003E7C D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   489 00003E7E FA                  <1> 	cli				; DISABLE INTERRUPTS
   490 00003E7F E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   491                              <1> 	; 29/05/2016
   492                              <1> 	;nop				; I/O DELAY
   493 00003E81 E6EB                <1> 	out	0ebh,al	; NEWIODELAY ; AWARD BIOS 1999, ATIME.ASM
   494                              <1> 	;
   495 00003E83 E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   496 00003E85 6650                <1> 	push	ax			; SAVE (AH) REGISTER VALUE AND CMOS BYTE
   497                              <1> 	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
   498                              <1> 		     ; ----- 10/06/85 (test4.asm)
   499 00003E87 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 	; GET ADDRESS OF DEFAULT LOCATION
   500                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   501 00003E89 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   502 00003E8B E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   503 00003E8D 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   504 00003E8F 9D                  <1> 	popf	
   505 00003E90 C3                  <1> 	retn				; RETURN WITH FLAGS RESTORED
   506                              <1> 
   507                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   508                              <1> 
   509                              <1> ;--- CMOS_WRITE ----------------------------------------------------------------
   510                              <1> ;	WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE		       :
   511                              <1> ;									       :
   512                              <1> ; INPUT: (AL)=	CMOS TABLE ADDRESS TO BE WRITTEN TO			       :
   513                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   514                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE		       :
   515                              <1> ;	 (AH)=	NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION	       :
   516                              <1> ;									       :
   517                              <1> ; OUTPUT:	VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED   :
   518                              <1> ;		IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND    :
   519                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   520                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   521                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   522                              <1> ;		ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED.	       :
   523                              <1> ;-------------------------------------------------------------------------------
   524                              <1> 
   525                              <1> CMOS_WRITE:				; WRITE (AH) TO LOCATION (AL)
   526 00003E91 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   527 00003E92 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   528 00003E94 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   529 00003E96 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   530 00003E97 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   531 00003E99 FA                  <1> 	cli				; DISABLE INTERRUPTS
   532 00003E9A E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   533 00003E9C 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   534 00003E9E E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   535 00003EA0 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2	; GET ADDRESS OF DEFAULT LOCATION
   536                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   537 00003EA2 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   538 00003EA4 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   539 00003EA6 90                  <1> 	nop				; I/O DELAY
   540 00003EA7 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   541 00003EA9 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   542 00003EAB 9D                  <1> 	popf
   543 00003EAC C3                  <1> 	retn
   544                              <1> 
   545                              <1> ; /// End Of TIMER FUNCTIONS ///
  1875                                  %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: 20/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> ; 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> ; 20/05/2016
    79                              <1> ; 19/05/2016
    80                              <1> ; 18/05/2016
    81                              <1> ; 29/04/2016 
    82                              <1> ; TRDOS 386 (TRDOS v2.0) system calls - temporary List 
    83                              <1> ; 14/07/2013 - 21/09/2015 (Retro UNIX 8086 & 386 system calls) 
    84                              <1> ; UNIX v1 system calls
    85                              <1> ;_rele	equ 0
    86                              <1> _ver 	equ 0 ; Get TRDOS version (v2.0)
    87                              <1> _exit 	equ 1
    88                              <1> _fork 	equ 2
    89                              <1> _read 	equ 3
    90                              <1> _write	equ 4
    91                              <1> _open	equ 5
    92                              <1> _close 	equ 6
    93                              <1> _wait 	equ 7
    94                              <1> _creat 	equ 8
    95                              <1> _link 	equ 9
    96                              <1> _unlink	equ 10
    97                              <1> _exec	equ 11
    98                              <1> _chdir	equ 12
    99                              <1> _time 	equ 13
   100                              <1> _mkdir 	equ 14
   101                              <1> _chmod	equ 15
   102                              <1> _chown	equ 16
   103                              <1> _break	equ 17
   104                              <1> _stat	equ 18
   105                              <1> _seek	equ 19
   106                              <1> _tell 	equ 20
   107                              <1> _mount	equ 21
   108                              <1> _umount	equ 22
   109                              <1> _setuid	equ 23
   110                              <1> _getuid	equ 24
   111                              <1> _stime	equ 25
   112                              <1> _quit	equ 26	
   113                              <1> _intr	equ 27
   114                              <1> _fstat	equ 28
   115                              <1> _emt 	equ 29
   116                              <1> _mdate 	equ 30
   117                              <1> ;_stty 	equ 31
   118                              <1> _video  equ 31 ; TRDOS 386 Video Functions (16/05/2016)
   119                              <1> ;_gtty	equ 32
   120                              <1> _audio	equ 32 ; TRDOS 386 Video Functions (16/05/2016)
   121                              <1> ;_ilgins equ 33
   122                              <1> _timer	equ 33 ; TRDOS 386 Timer Functions (18/05/2016)
   123                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
   124                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
   125                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
   126                              <1> _reserved1 equ 37 ;; TRDOS 386 (19/05/2016)
   127                              <1> _pri 	equ 38 ; change priority - TRDOS 386 (20/05/2016)
   128                              <1> _rele	equ 39 ; TRDOS 386 (19/05/2016)
   129                              <1> 
   130                              <1> %macro sys 1-4
   131                              <1>     ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
   132                              <1>     ; 03/09/2015	
   133                              <1>     ; 13/04/2015
   134                              <1>     ; Retro UNIX 386 v1 system call.		
   135                              <1>     %if %0 >= 2   
   136                              <1>         mov ebx, %2
   137                              <1>         %if %0 >= 3    
   138                              <1>             mov ecx, %3
   139                              <1>             %if %0 = 4
   140                              <1>                mov edx, %4   
   141                              <1>             %endif
   142                              <1>         %endif
   143                              <1>     %endif
   144                              <1>     mov eax, %1
   145                              <1>     ;int 30h
   146                              <1>     int 40h ; TRDOS 386 (TRDOS v2.0)		   
   147                              <1> %endmacro
   148                              <1> 
   149                              <1> ; 13/05/2015 - ERROR CODES
   150                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
   151                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
   152                              <1> ; 14/05/2015
   153                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
   154                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
   155                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
   156                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
   157                              <1> ; 16/05/2015		
   158                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
   159                              <1> ; 18/05/2015
   160                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
   161                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
   162                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
   163                              <1> ; 07/06/2015
   164                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
   165                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
   166                              <1> ; 09/06/2015
   167                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
   168                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
   169                              <1> ; 16/06/2015
   170                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
   171                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
   172                              <1> ; 22/06/2015
   173                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
   174                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
   175                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
   176                              <1> ; 23/06/2015
   177                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
   178                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
   179                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
   180                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
   181                              <1> ; 27/06/2015
   182                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
   183                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
   184                              <1> ; 29/06/2015
   185                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
   186                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error
   187                              <1> ; 18/05/2016
   188                              <1> ERR_MISC	   equ 26 ; miscellaneous/other errors		
   189                              <1> 
   190                              <1> ; 26/08/2015
   191                              <1> ; 24/07/2015
   192                              <1> ; 24/06/2015
   193                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
   194                              <1> ; 01/07/2015
   195                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
   196                              <1> ;	 					 		
  1876                                  %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
  1877                                  %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: 13/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 00003EAD 31C0                <1> 	xor	eax, eax
    30 00003EAF BF00010900          <1> 	mov	edi, Logical_DOSDisks
    31 00003EB4 B980060000          <1> 	mov	ecx, 6656/4 ; 26*256 = 6656 bytes
    32 00003EB9 F3AB                <1> 	rep	stosd ; 1664 times 4 bytes
    33                              <1> 
    34 00003EBB B83F3A2F00          <1> 	mov	eax, '?:/'
    35 00003EC0 A3[4FD30000]        <1> 	mov	[Current_Dir_Drv], eax
    36                              <1> 
    37                              <1> 	; Logical DRV INIT (only for hard disks)
    38 00003EC5 E8B3010000          <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 00003ECA BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    45 00003ECF B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    46 00003ED1 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    47 00003ED4 8806                <1> 	mov 	[esi], al ; A:
    48 00003ED6 81C600010000        <1> 	add 	esi, 100h 
    49 00003EDC 8806                <1> 	mov 	[esi], al ; B: 
    50                              <1>            
    51                              <1> _current_drive_bootdisk:
    52 00003EDE 8A15[8ACD0000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    53 00003EE4 80FAFF              <1> 	cmp 	dl, 0FFh
    54 00003EE7 740A                <1> 	je 	short _last_dos_diskno_check
    55                              <1> _boot_drive_check:
    56 00003EE9 80FA80              <1> 	cmp 	dl, 80h
    57 00003EEC 7218                <1> 	jb 	short _current_drive_a
    58 00003EEE 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    59 00003EF1 EB13                <1> 	jmp 	short _current_drive_a 
    60                              <1> 
    61                              <1> _last_dos_diskno_check:
    62 00003EF3 8A15[E2C10000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    63 00003EF9 80FA02              <1> 	cmp 	dl, 2
    64 00003EFC 7706                <1> 	ja 	short _current_drive_c
    65 00003EFE 7406                <1> 	je 	short _current_drive_a
    66 00003F00 30D2                <1> 	xor 	dl, dl ; A:
    67 00003F02 EB02                <1> 	jmp 	short _current_drive_a
    68                              <1> 
    69                              <1> _current_drive_c:
    70 00003F04 B202                <1> 	mov 	dl, 2 ; C:
    71                              <1> 
    72                              <1> _current_drive_a:
    73 00003F06 8815[8BCD0000]      <1> 	mov	[drv], dl
    74 00003F0C BE[E4C10000]        <1>         mov     esi, msg_CRLF_temp
    75 00003F11 E89E000000          <1> 	call 	print_msg
    76                              <1> 
    77 00003F16 8A15[8BCD0000]      <1> 	mov	dl, [drv]
    78 00003F1C E898090000          <1> 	call 	change_current_drive
    79 00003F21 730C                <1> 	jnc 	short _start_mainprog
    80                              <1> 
    81                              <1> _drv_not_ready_error: 
    82 00003F23 BE[A8C40000]        <1> 	mov 	esi, msgl_drv_not_ready
    83 00003F28 E887000000          <1> 	call 	print_msg
    84 00003F2D 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 00003F2F 66B80100            <1> 	mov	ax, 1
    96 00003F33 A2[97E30000]        <1> 	mov	[u.uno], al
    97 00003F38 66A3[32E30000]      <1> 	mov	[mpid], ax
    98 00003F3E 66A3[2CE00000]      <1> 	mov	[p.pid], ax
    99 00003F44 A2[BCE00000]        <1> 	mov	[p.stat], al
   100 00003F49 B004                <1> 	mov	al, time_count
   101 00003F4B A2[8AE30000]        <1> 	mov	[u.quant], al
   102                              <1> 	;
   103 00003F50 A1[88D20000]        <1> 	mov	eax, [k_page_dir]
   104 00003F55 A3[A1E30000]        <1> 	mov	[u.pgdir], eax ; reset
   105                              <1> 	;
   106 00003F5A E802F2FFFF          <1> 	call	allocate_page
   107 00003F5F 0F82A3000000        <1> 	jc	panic
   108 00003F65 A3[98E30000]        <1> 	mov	[u.upage], eax ; user structure page	
   109 00003F6A A3[CCE00000]        <1> 	mov	[p.upage], eax
   110 00003F6F E867F2FFFF          <1> 	call	clear_page
   111                              <1> 	;
   112                              <1> 	; 24/08/2015
   113 00003F74 FE0D[3FE30000]      <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 00003F7A BF00300900          <1> 	mov	edi, Env_Page ; 93000h
   118 00003F7F B980000000          <1> 	mov	ecx, Env_Page_Size / 4 	; 512/4  (4096/4)				 	  		 	  
   119 00003F84 31C0                <1> 	xor	eax, eax
   120 00003F86 F3AB                <1> 	rep	stosd
   121                              <1> 
   122                              <1> 	; 14/04/2016
   123 00003F88 E8BF320000          <1>  	call	mainprog_startup_configuration
   124                              <1> 
   125 00003F8D E8630A0000          <1>         call    dos_prompt
   126                              <1>               
   127                              <1> _end_of_mainprog:
   128 00003F92 BE[E4C10000]        <1>         mov     esi, msg_CRLF_temp
   129 00003F97 E818000000          <1> 	call 	print_msg
   130 00003F9C BE[EAC10000]        <1> 	mov 	esi, mainprog_Version
   131 00003FA1 E80E000000          <1> 	call 	print_msg
   132                              <1> 	; 24/01/2016
   133 00003FA6 28E4                <1> 	sub	ah, ah
   134 00003FA8 E8EFCAFFFF          <1> 	call	int16h ; call getch
   135 00003FAD E9C6CFFFFF          <1> 	jmp	cpu_reset
   136                              <1> 
   137 00003FB2 EBFE                <1> infinitiveloop: jmp short infinitiveloop
   138                              <1> 
   139                              <1> print_msg:
   140                              <1> 	; 13/05/2016
   141                              <1> 	; 04/01/2016
   142                              <1> 	; 01/07/2015
   143                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   144                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   145                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
   146                              <1> 	;
   147 00003FB4 8A3D[B8D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   148                              <1> 	;mov	bl, 07h ; Black background, light gray forecolor
   149                              <1> 
   150 00003FBA AC                  <1> 	lodsb
   151                              <1> pmsg1:
   152 00003FBB 56                  <1> 	push 	esi
   153                              <1> 	;mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   154 00003FBC B307                <1> 	mov	bl, 07h ; Black background, light gray forecolor
   155 00003FBE E825D7FFFF          <1> 	call 	_write_tty
   156 00003FC3 5E                  <1> 	pop	esi
   157 00003FC4 AC                  <1> 	lodsb
   158 00003FC5 20C0                <1> 	and 	al, al
   159 00003FC7 75F2                <1> 	jnz 	short pmsg1
   160 00003FC9 C3                  <1> 	retn
   161                              <1> 
   162                              <1> clear_screen:
   163                              <1> 	; 13/05/2016
   164                              <1> 	; 30/01/2016
   165                              <1> 	; 24/01/2016
   166                              <1> 	; 04/01/2016
   167 00003FCA 0FB61D[B8D20000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   168 00003FD1 8AA3[00CD0000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   169 00003FD7 80FC04              <1> 	cmp	ah, 4
   170 00003FDA 7205                <1> 	jb	short cls1
   171 00003FDC 80FC07              <1> 	cmp	ah, 7
   172 00003FDF 7526                <1> 	jne	short vga_clear
   173                              <1> cls1:
   174                              <1> 	;mov	bh, bl
   175                              <1> 	;mov	bl, 7
   176 00003FE1 3A25[E6CC0000]      <1> 	cmp	ah, [CRT_MODE] ; current video mode ? 
   177                              <1> 	;je	short cls2 ; yes (current video mode = 3)
   178                              <1> 	;;call	set_mode_3 ; set video mode to 3 (& clear screen)
   179                              <1> 	;;retn
   180                              <1> 	;jmp	set_mode_3
   181 00003FE7 0F85B0D3FFFF        <1> 	jne	set_mode_3
   182                              <1> cls2:
   183 00003FED 88DF                <1> 	mov	bh, bl ; video page (0 to 7)
   184 00003FEF B307                <1> 	mov	bl, 07h ; attribute to be used on blanked line
   185 00003FF1 28C0                <1> 	sub 	al, al ; 0 =  entire window
   186 00003FF3 6631C9              <1> 	xor 	cx, cx
   187 00003FF6 66BA4F18            <1> 	mov 	dx, 184Fh
   188 00003FFA E825D5FFFF          <1> 	call	_scroll_up ; 24/01/2016
   189                              <1> 	;
   190                              <1> 	;mov	bh, [ACTIVE_PAGE] ; video page number (0 to 7)
   191 00003FFF 6631D2              <1> 	xor 	dx, dx
   192 00004002 E86CD7FFFF          <1> 	call	_set_cpos ; 24/01/2016 
   193                              <1> 	;retn
   194                              <1> vga_clear:
   195 00004007 C3                  <1> 	retn	
   196                              <1> 
   197                              <1> panic:
   198                              <1> 	; 13/05/2016 (TRDOS 386 = TRDOS v2)
   199                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   200                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   201 00004008 BE[23CF0000]        <1> 	mov 	esi, panic_msg
   202 0000400D E8A2FFFFFF          <1> 	call 	print_msg
   203                              <1> key_to_reboot:
   204                              <1>         ; 24/01/2016
   205 00004012 28E4                <1>         sub     ah, ah
   206 00004014 E883CAFFFF          <1>         call    int16h ; call   getch
   207                              <1>         ; wait for a character from the current tty
   208                              <1> 	;
   209 00004019 B00A                <1> 	mov	al, 0Ah
   210 0000401B 8A3D[B8D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
   211 00004021 B307                <1> 	mov	bl, 07h ; Black background, 
   212                              <1> 			; light gray forecolor
   213 00004023 E8C0D6FFFF          <1> 	call 	_write_tty
   214 00004028 E94BCFFFFF          <1> 	jmp	cpu_reset 
   215                              <1> 
   216                              <1> ctrlbrk:
   217                              <1> 	; 12/11/2015
   218                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   219                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
   220                              <1> 	;
   221                              <1> 	; INT 1Bh (control+break) handler		
   222                              <1> 	;
   223                              <1>       	; Retro Unix 8086 v1 feature only!
   224                              <1>       	;
   225 0000402D 66833D[8CE30000]00  <1> 	cmp 	word [u.intr], 0
   226 00004035 7645                <1> 	jna 	short cbrk4
   227                              <1> cbrk0:
   228                              <1> 	; 12/11/2015
   229                              <1> 	; 06/12/2013
   230 00004037 66833D[8EE30000]00  <1> 	cmp 	word [u.quit], 0
   231 0000403F 743B                <1> 	jz	short cbrk4
   232                              <1> 	;
   233                              <1> 	; 20/09/2013	
   234 00004041 6650                <1> 	push 	ax
   235 00004043 A0[B8D20000]        <1> 	mov	al, [ptty]
   236                              <1> 	;
   237                              <1> 	; 12/11/2015
   238                              <1> 	;
   239                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
   240                              <1> 	; or ctrl+break from console (pseudo) tty
   241                              <1> 	; (!redirection!)
   242                              <1> 	;
   243 00004048 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   244 0000404A 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
   245                              <1> 	;	
   246                              <1> 	; Serial port interrupt handler sets [ptty]
   247                              <1> 	; to the port's tty number (as temporary).
   248                              <1> 	;
   249                              <1> 	; If active process is using a stdin or 
   250                              <1> 	; stdout redirection (by the shell),
   251                              <1>         ; console tty keyboard must be available
   252                              <1> 	; to terminate running process,
   253                              <1> 	; in order to prevent a deadlock. 
   254                              <1> 	;
   255 0000404C 52                  <1> 	push	edx
   256 0000404D 0FB615[97E30000]    <1> 	movzx	edx, byte [u.uno]
   257 00004054 3A82[8BE00000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   258 0000405A 5A                  <1> 	pop	edx
   259 0000405B 7412                <1> 	je	short cbrk2
   260                              <1> cbrk1:
   261 0000405D FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   262                              <1> 	; 06/12/2013
   263 0000405F 3A05[78E30000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   264 00004065 7408                <1> 	je	short cbrk2	
   265 00004067 3A05[79E30000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   266 0000406D 750B                <1> 	jne	short cbrk3	
   267                              <1> cbrk2:
   268                              <1> 	;; 06/12/2013
   269                              <1> 	;mov	ax, [u.quit]
   270                              <1> 	;and	ax, ax
   271                              <1> 	;jz	short cbrk3
   272                              <1> 	;
   273 0000406F 6631C0              <1> 	xor	ax, ax ; 0
   274 00004072 6648                <1> 	dec	ax
   275                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   276 00004074 66A3[8EE30000]      <1> 	mov	[u.quit], ax
   277                              <1> cbrk3:
   278 0000407A 6658                <1> 	pop	ax
   279                              <1> cbrk4:
   280 0000407C C3                  <1> 	retn
  1878                                  %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 0000407D 0FB60D[26D30000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
    25 00004084 80F901              <1> 	cmp	cl, 1
    26 00004087 7301                <1> 	jnb	short load_hd_partition_tables
    27                              <1> 	; No hard disks
    28 00004089 C3                  <1> 	retn
    29                              <1> load_hd_partition_tables:
    30 0000408A 8B35[28D30000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    31 00004090 BF[4ED70000]        <1> 	mov 	edi, PTable_hd0
    32 00004095 B280                <1> 	mov 	dl, 80h
    33                              <1> load_next_hd_partition_table:
    34 00004097 51                  <1> 	push	ecx
    35 00004098 57                  <1> 	push	edi
    36 00004099 56                  <1> 	push	esi ; FDPT (+ DPTE) address
    37 0000409A 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
    38 0000409D 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
    39                              <1> 	;shr	al, 6
    40 0000409F A2[4FD90000]        <1> 	mov 	[HD_LBA_yes], al
    41 000040A4 E81C040000          <1> 	call	load_masterboot
    42 000040A9 7275                <1> 	jc	short pass_pt_this_hard_disk
    43                              <1> 
    44 000040AB BE[0CD70000]        <1> 	mov	esi, PartitionTable
    45 000040B0 89F3                <1> 	mov	ebx, esi
    46                              <1> 	;mov	ecx, 16
    47 000040B2 B110                <1> 	mov	cl, 16
    48 000040B4 F3A5                <1> 	rep 	movsd
    49 000040B6 89DE                <1> 	mov 	esi, ebx 
    50 000040B8 C605[8DCD0000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
    51                              <1> loc_validate_hdp_partition:
    52 000040BF 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
    53 000040C3 7641                <1> 	jna	short loc_validate_next_hdp_partition2
    54 000040C5 56                  <1> 	push	esi ; Masterboot partition table offset
    55 000040C6 52                  <1> 	push	edx ; dl = Physical drive number 
    56 000040C7 FE05[50D90000]      <1> 	inc	byte [PP_Counter]
    57 000040CD 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 000040CF E879010000          <1> 	call 	validate_hd_fat_partition
    63 000040D4 730A                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
    64                              <1> 	;pop	edx
    65                              <1> 	;push	edx
    66 000040D6 8B1424              <1> 	mov	edx, [esp] 
    67 000040D9 E8C5020000          <1> 	call	validate_hd_fs_partition
    68 000040DE 7224                <1> 	jc	short loc_validate_next_hdp_partition1
    69                              <1> loc_set_valid_hdp_partition_entry:
    70 000040E0 8A0D[E2C10000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
    71 000040E6 80C141              <1> 	add 	cl, 'A'
    72                              <1> 	; ESI = Logical dos drive description table address
    73 000040E9 880E                <1> 	mov	[esi+LD_Name], cl
    74 000040EB 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
    75 000040EE 88E0                <1> 	mov	al, ah ; Physical drive number
    76 000040F0 2C80                <1> 	sub	al, 80h
    77 000040F2 C0E002              <1> 	shl	al, 2
    78 000040F5 0404                <1> 	add	al, 4 ; 0 Based
    79 000040F7 2A05[8DCD0000]      <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 000040FD 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 00004100 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
    89                              <1> loc_validate_next_hdp_partition1:
    90 00004104 5A                  <1> 	pop 	edx ; dl = Physical drive number 
    91 00004105 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 00004106 FE0D[8DCD0000]      <1> 	dec	byte [hdc] ; 4 - partition index
    96 0000410C 7412                <1> 	jz	short pass_pt_this_hard_disk
    97 0000410E 83C610              <1> 	add	esi, 16 ; 10h
    98 00004111 EBAC                <1> 	jmp	short loc_validate_hdp_partition
    99                              <1> loc_next_hd_partition_table:
   100 00004113 FEC2                <1> 	inc	dl
   101 00004115 83C620              <1> 	add	esi, 32 ; next FDPT address
   102 00004118 83C740              <1> 	add	edi, 64 ; next partition table destination
   103 0000411B E977FFFFFF          <1>         jmp     load_next_hd_partition_table
   104                              <1> pass_pt_this_hard_disk:
   105 00004120 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
   106 00004121 5F                  <1> 	pop	edi ; Ptable_hd?
   107 00004122 59                  <1> 	pop	ecx
   108 00004123 E2EE                <1> 	loop	loc_next_hd_partition_table
   109 00004125 803D[50D90000]01    <1> 	cmp	byte [PP_Counter], 1
   110 0000412C 7301                <1> 	jnb	short load_extended_dos_partitions
   111                              <1> 	; Empty partition table
   112 0000412E C3                  <1> 	retn 
   113                              <1> load_extended_dos_partitions:
   114 0000412F BE[4ED70000]        <1> 	mov	esi, PTable_hd0
   115 00004134 BF[4ED80000]        <1> 	mov	edi, PTable_ep0
   116 00004139 C605[8DCD0000]80    <1> 	mov	byte [hdc], 80h
   117                              <1> next_hd_extd_partition:
   118 00004140 56                  <1> 	push	esi ; PTable_hd? offset
   119 00004141 57                  <1> 	push	edi ; PTable_ep?
   120                              <1> 	;mov	ecx, 4
   121 00004142 B104                <1> 	mov	cl, 4
   122 00004144 8A15[8DCD0000]      <1> 	mov	dl, byte [hdc]
   123                              <1> hd_check_fs_id_05h:
   124 0000414A 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   125 0000414D 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   126 0000414F 7404                <1> 	je	short loc_set_ep_start_sector
   127 00004151 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   128 00004153 7546                <1> 	jne	short continue_to_check_ep
   129                              <1> loc_set_ep_start_sector:
   130 00004155 FE05[51D90000]      <1> 	inc	byte [EP_Counter]
   131 0000415B 88D4                <1> 	mov	ah, dl ; byte [hdc]
   132 0000415D 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
   133 0000415F 50                  <1> 	push	eax 
   134 00004160 30E4                <1> 	xor	ah, ah  
   135 00004162 2C80                <1> 	sub	al, 80h
   136 00004164 50                  <1> 	push	eax
   137 00004165 C0E002              <1> 	shl	al, 2 ; al = al * 4
   138 00004168 0FB6D8              <1> 	movzx	ebx, al
   139 0000416B 81C3[52D90000]      <1> 	add	ebx, EP_StartSector
   140 00004171 8B4608              <1> 	mov	eax, [esi+ptStartSector]
   141                              <1>         ; EAX = Extended partition's start sector
   142 00004174 8903                <1>         mov	[ebx], eax
   143 00004176 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
   144 00004177 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
   145 00004178 BB[4ED50000]        <1> 	mov	ebx, MasterBootBuff
   146 0000417D 803D[4FD90000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   147 00004184 7240                <1> 	jb	short loc_hd_load_ep_05h
   148 00004186 80FE05              <1> 	cmp	dh, 05h
   149 00004189 743B                <1> 	je	short loc_hd_load_ep_05h
   150                              <1> loc_hd_load_ep_0Fh:
   151                              <1> 	; 04/01/2016
   152 0000418B 51                  <1> 	push	ecx
   153 0000418C 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 0000418F B41B                <1> 	mov	ah, 1Bh ; LBA read
   159 00004191 B001                <1> 	mov	al, 1 ; sector count
   160 00004193 E86EE6FFFF          <1> 	call	int13h
   161 00004198 59                  <1> 	pop	ecx
   162 00004199 733F                <1> 	jnc	short loc_hd_move_ep_table
   163                              <1> continue_to_check_ep:
   164 0000419B 83C610              <1> 	add	esi, 16
   165 0000419E E2AA                <1> 	loop	hd_check_fs_id_05h
   166                              <1> continue_check_ep_next_disk:
   167 000041A0 5F                  <1> 	pop	edi ; PTable_ep?
   168 000041A1 5E                  <1> 	pop	esi ; PTable_hd?
   169 000041A2 A0[26D30000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   170 000041A7 047F                <1> 	add	al, 7Fh
   171 000041A9 3805[8DCD0000]      <1> 	cmp	[hdc], al
   172 000041AF 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
   173 000041B5 83C640              <1> 	add	esi, 64
   174 000041B8 83C740              <1> 	add	edi, 64
   175 000041BB FE05[8DCD0000]      <1> 	inc	byte [hdc]
   176 000041C1 E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
   177                              <1> loc_hd_load_ep_05h:
   178 000041C6 51                  <1> 	push	ecx 
   179 000041C7 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   180 000041CA 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
   181 000041CE 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   182                              <1> 	;mov	ebx, MasterBootBuff
   183 000041D2 E82FE6FFFF          <1> 	call	int13h
   184 000041D7 59                  <1> 	pop	ecx  
   185 000041D8 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 000041DA 8B3C24              <1> 	mov	edi, [esp]        
   190 000041DD BE[0CD70000]        <1>         mov	esi, PartitionTable ; Extended
   191 000041E2 89F3                <1> 	mov	ebx, esi
   192                              <1> 	;mov	ecx, 16
   193 000041E4 B110                <1> 	mov	cl, 16
   194 000041E6 F3A5                <1>        	rep	movsd
   195 000041E8 89DE                <1> 	mov	esi, ebx 
   196                              <1> loc_set_hde_sub_partition_count:
   197 000041EA C605[50D90000]04    <1> 	mov	byte [PP_Counter], 4
   198                              <1> loc_validate_hde_partition:
   199 000041F1 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   200 000041F5 763F                <1> 	jna	short loc_validate_next_hde_partition2
   201 000041F7 56                  <1> 	push	esi ; Extended partition table offset
   202 000041F8 8A15[8DCD0000]      <1> 	mov	dl, byte [hdc]
   203 000041FE 0FB6C2              <1> 	movzx	eax, dl
   204 00004201 2C80                <1> 	sub	al, 80h
   205 00004203 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 00004206 88C1                <1> 	mov	cl, al
   211 00004208 80C104              <1> 	add	cl, 4
   212 0000420B 2A0D[50D90000]      <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 00004211 88D5                <1>       	mov	ch, dl   
   217 00004213 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 00004216 51                  <1> 	push	ecx ; *
   222 00004217 BF[52D90000]        <1> 	mov	edi, EP_StartSector
   223 0000421C 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 0000421E E82A000000          <1> 	call	validate_hd_fat_partition
   228 00004223 59                  <1> 	pop	ecx ; *
   229 00004224 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 00004226 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
   236                              <1> 	;
   237 0000422A 8A0D[E2C10000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   238 00004230 80C141              <1> 	add	cl, 'A'
   239 00004233 880E                <1> 	mov	[esi+LD_Name], cl
   240                              <1> loc_validate_next_hde_partition1:
   241 00004235 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 00004236 FE0D[50D90000]      <1> 	dec	byte [PP_Counter]
   246 0000423C 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
   247 00004242 83C610              <1> 	add 	esi, 16 ; 10h
   248 00004245 EBAA                <1> 	jmp	short loc_validate_hde_partition
   249                              <1> loc_validating_hd_partitions_ok:
   250 00004247 A0[E2C10000]        <1> 	mov	al, [Last_DOS_DiskNo]
   251                              <1> loc_drv_init_retn:
   252 0000424C 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 0000424D 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   275 00004250 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
   276                              <1> 	; 12/02/2016
   277                              <1> 	;jb	short loc_not_a_valid_fat_partition2
   278 00004253 7305                <1>  	jnb	short vhdp_FAT16_32
   279                              <1> 	;
   280 00004255 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)		
   281 00004258 7519                <1> 	jne	short loc_not_a_valid_fat_partition1
   282                              <1> vhdp_FAT16_32:
   283 0000425A B002                <1> 	mov	al, 2
   284 0000425C 7417                <1> 	je	short loc_set_valid_hd_partition_params
   285 0000425E 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   286 00004261 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
   287 00004263 7410                <1> 	je	short loc_set_valid_hd_partition_params
   288                              <1> 
   289 00004265 FEC0                <1> 	inc	al ; 3
   290 00004267 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   291 0000426A 7409                <1> 	je	short loc_set_valid_hd_partition_params
   292 0000426C 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
   293 0000426E 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   294 00004271 7402                <1> 	je	short loc_set_valid_hd_partition_params
   295                              <1> loc_not_a_valid_fat_partition1:
   296 00004273 F9                  <1> 	stc
   297                              <1> loc_not_a_valid_fat_partition2:
   298 00004274 C3                  <1> 	retn
   299                              <1> 
   300                              <1> loc_set_valid_hd_partition_params:
   301 00004275 FE05[E2C10000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   302                              <1> 	;
   303 0000427B 31DB                <1> 	xor	ebx, ebx
   304 0000427D 8A3D[E2C10000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   305 00004283 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   306                              <1> 	;
   307 00004289 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   308 0000428D 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 00004290 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   312                              <1> 	;
   313 00004294 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   314 00004297 09FF                <1> 	or	edi, edi 
   315 00004299 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   316                              <1> loc_add_hd_FAT_ep_start_sector:
   317 0000429B 030F                <1> 	add	ecx, [edi]
   318                              <1> pass_hd_FAT_ep_start_sector_adding:
   319 0000429D 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   320                              <1> loc_hd_FAT_logical_drv_init:
   321 000042A0 89DD                <1> 	mov	ebp, ebx
   322                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   323 000042A2 A0[4FD90000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   324 000042A7 884305              <1> 	mov	[ebx+LD_LBAYes], al
   325 000042AA BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   326 000042AF 08C0                <1> 	or	al, al
   327 000042B1 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 000042B3 B41B                <1> 	mov	ah, 1Bh ; LBA read
   336 000042B5 B001                <1> 	mov	al, 1 ; sector count
   337 000042B7 E84AE5FFFF          <1> 	call	int13h
   338 000042BC 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   339                              <1> loc_not_a_valid_fat_partition3:
   340 000042BE C3                  <1> 	retn
   341                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   342 000042BF 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   343 000042C2 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   344 000042C6 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   345                              <1> 	;mov	ebx, DOSBootSectorBuff
   346 000042CA E837E5FFFF          <1> 	call	int13h
   347 000042CF 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   348                              <1> loc_hd_drv_FAT_boot_validation:
   349                              <1> 	;mov	esi, DOSBootSectorBuff
   350 000042D1 89DE                <1> 	mov	esi, ebx
   351 000042D3 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   352 000042DC 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
   353 000042DE 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   354 000042E2 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
   355 000042E4 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   356 000042E9 770F                <1> 	ja	short loc_hd_FAT16_BPB
   357 000042EB 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   358 000042EF 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
   359                              <1> loc_hd_FAT32_BPB:
   360 000042F1 B92D000000          <1> 	mov	ecx, 45
   361 000042F6 EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
   362                              <1> 	;
   363                              <1> loc_not_a_valid_fat_partition4:
   364 000042F8 F9                  <1> 	stc
   365 000042F9 C3                  <1> 	retn
   366                              <1> 	;
   367                              <1> loc_hd_FAT16_BPB:
   368 000042FA 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   369 000042FE 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   370 00004300 B920000000          <1> 	mov	ecx, 32
   371                              <1> loc_hd_move_FAT_BPB:
   372 00004305 89EF                <1> 	mov 	edi, ebp
   373                              <1> 	;mov	esi, ebx ; Boot sector
   374 00004307 57                  <1> 	push	edi
   375 00004308 83C706              <1> 	add	edi, LD_BPB
   376 0000430B F366A5              <1> 	rep	movsw 
   377 0000430E 5E                  <1> 	pop	esi
   378 0000430F 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   379 00004313 03466C              <1> 	add	eax, [esi+LD_StartSector]
   380 00004316 894660              <1> 	mov	[esi+LD_FATBegin], eax
   381 00004319 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   382 0000431D 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   383                              <1> loc_set_FAT32_RootDirLoc:
   384 0000431F 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   385 00004322 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   386 00004326 F7E3                <1> 	mul	ebx
   387 00004328 034660              <1> 	add	eax, [esi+LD_FATBegin]
   388                              <1> loc_set_FAT32_data_begin:
   389 0000432B 894668              <1> 	mov	[esi+LD_DATABegin], eax
   390 0000432E 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 00004331 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   395 00004334 83E802              <1> 	sub	eax, 2
   396 00004337 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   397                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   398 00004339 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
   399 0000433C F7E3                <1> 	mul	ebx
   400 0000433E 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   401 00004341 EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   402                              <1> 	;
   403                              <1> loc_set_FAT16_RootDirLoc:
   404 00004343 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   405 00004347 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   406 0000434B F7E2                <1> 	mul	edx
   407 0000434D 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   408 00004350 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   409                              <1> loc_set_FAT16_data_begin:
   410 00004353 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   411 00004356 B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
   412                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   413 0000435B 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   414 0000435F F7E2                <1>         mul	edx
   415                              <1> 	;mov	ecx, 511
   416 00004361 66B9FF01            <1> 	mov	cx, 511
   417 00004365 01C8                <1> 	add	eax, ecx
   418 00004367 41                  <1> 	inc	ecx ; 512
   419 00004368 F7F1                <1> 	div	ecx
   420 0000436A 014668              <1> 	add	[esi+LD_DATABegin], eax
   421 0000436D 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   422 00004371 6685C0              <1> 	test	ax, ax
   423 00004374 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
   424                              <1> loc_set_16bit_FAT_total_sectors:
   425 00004376 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   426 00004379 EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
   427                              <1> loc_set_32bit_FAT_total_sectors:
   428 0000437B 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   429 0000437E 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   430                              <1> loc_set_hd_FAT_cluster_count:
   431 00004381 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   432 00004384 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   433 00004387 29D0                <1> 	sub	eax, edx
   434 00004389 31D2                <1> 	xor	edx, edx ; 0
   435 0000438B 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   436 0000438F F7F1                <1>         div	ecx 
   437 00004391 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 00004394 E859010000          <1> 	call	get_free_FAT_sectors
   443 00004399 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   444 0000439B 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   445 0000439E 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 000043A2 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 000043A3 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   472 000043A6 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   473 000043A9 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   474                              <1> loc_set_valid_hd_fs_partition_params:
   475 000043AB FE05[E2C10000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   476 000043B1 30C0                <1> 	xor	al, al ; mov al, 0
   477                              <1> 	;mov	[drv], dl
   478 000043B3 29DB                <1> 	sub	ebx, ebx ; 0
   479 000043B5 8A3D[E2C10000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   480 000043BB 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   481 000043C1 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   482 000043C5 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   483                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   484                              <1> 	;mov	[ebx+LD_FSType], ah
   485 000043C8 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 000043CC 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   490                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   491 000043CE A0[4FD90000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   492 000043D3 884305              <1> 	mov	[ebx+LD_LBAYes], al
   493 000043D6 89DE                <1> 	mov	esi, ebx
   494 000043D8 BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
   495 000043DD 08C0                <1> 	or	al, al
   496 000043DF 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   497                              <1> loc_hd_fs_drv_init_load_bs_chs:
   498 000043E1 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   499 000043E4 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   500 000043E8 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   501                              <1> 	;mov	ebx, DOSBootSectorBuff
   502 000043EC E815E4FFFF          <1> 	call	int13h
   503 000043F1 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   504                              <1> loc_validate_hd_fs_partition_err_retn:
   505 000043F3 C3                  <1> 	retn
   506                              <1> loc_validate_hd_fs_partition_stc_retn:
   507 000043F4 F9                  <1> 	stc
   508 000043F5 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 000043F6 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 000043F9 B41B                <1> 	mov	ah, 1Bh ; LBA read
   518 000043FB B001                <1> 	mov	al, 1 ; sector count
   519 000043FD E804E4FFFF          <1> 	call	int13h
   520 00004402 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 00004404 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   524 00004406 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   525 0000440F 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 00004411 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
   529 00004417 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 00004419 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   533 0000441D 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   534                              <1> 	;
   535 0000441F 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   536                              <1> 	;
   537 00004421 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   538 00004424 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   539                              <1> 	;
   540                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   541 00004427 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   542 0000442A 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   543                              <1> 	;
   544 0000442D 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   545 00004430 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   546                              <1> 	;
   547 00004433 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   548 00004437 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   549 0000443B 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   550 0000443E 6698                <1> 	cbw
   551 00004440 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   552 00004444 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   553                              <1> 	;cbw
   554 00004447 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   555                              <1> 	;
   556 0000444B 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   557 0000444E 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   558 00004451 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   559 00004454 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   560 00004457 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   561 0000445A 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   562 0000445D 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   563 00004460 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   564 00004463 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   565 00004466 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   566                              <1> 	;
   567 00004469 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   568 0000446B 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   569 0000446E 89FE                <1> 	mov	esi, edi
   570                              <1> mread_hd_fs_MAT_sector:
   571                              <1>        ;mov	ebx, DOSBootSectorBuff
   572 00004470 B901000000          <1> 	mov	ecx, 1
   573 00004475 E888790000          <1> 	call	disk_read
   574 0000447A 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   575                              <1> 	; EDI will not be changed
   576 0000447C 89DE                <1> 	mov	esi, ebx
   577                              <1> use_hdfs_mat_sector_params:
   578 0000447E 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   579 00004481 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   580 00004484 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   581 00004487 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   582 0000448A 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   583 0000448D 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   584 00004490 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   585 00004493 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   586 00004496 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   587 00004499 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   588 0000449C 89FE                <1> 	mov	esi, edi   
   589                              <1> read_hd_fs_RDT_sector:
   590 0000449E BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   591                              <1> 	;mov	ecx, 1
   592 000044A3 B101                <1> 	mov	cl, 1
   593 000044A5 E858790000          <1> 	call	disk_read
   594 000044AA 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   595                              <1> 	; EDI will not be changed
   596 000044AC 89DE                <1> 	mov	esi, ebx
   597                              <1> use_hdfs_RDT_sector_params:
   598 000044AE 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   599 000044B1 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   600 000044B4 57                  <1> 	push	edi
   601                              <1> 	;mov	ecx, 16
   602 000044B5 B110                <1> 	mov	cl, 16
   603 000044B7 83C640              <1> 	add	esi, FS_RDT_VolumeName
   604 000044BA 83C72C              <1> 	add	edi, LD_FS_VolumeName
   605 000044BD F3A5                <1> 	rep	movsd ; 64 bytes
   606 000044BF 5E                  <1> 	pop	esi
   607                              <1> 		; Volume Name Reset
   608 000044C0 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 000044C4 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 000044C5 B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
   622 000044C7 E83AE3FFFF          <1> 	call	int13h
   623 000044CC 7301                <1> 	jnc	short pass_reset_error
   624                              <1> harddisk_error:
   625 000044CE C3                  <1>   	retn
   626                              <1> pass_reset_error:
   627 000044CF BB[4ED50000]        <1> 	mov	ebx, MasterBootBuff
   628 000044D4 66B80102            <1> 	mov	ax, 0201h
   629 000044D8 66B90100            <1> 	mov	cx, 1
   630 000044DC 30F6                <1> 	xor	dh, dh
   631 000044DE E823E3FFFF          <1>  	call	int13h
   632 000044E3 72E9                <1> 	jc	short harddisk_error
   633                              <1> 	;
   634 000044E5 66813D[4CD70000]55- <1> 	cmp	word [MBIDCode], 0AA55h
   634 000044ED AA                  <1>
   635 000044EE 7401                <1> 	je	short load_masterboot_ok
   636 000044F0 F9                  <1> 	stc
   637                              <1> load_masterboot_ok:
   638 000044F1 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 000044F2 31C0                <1> 	xor	eax, eax
   653                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
   654                              <1> 	
   655 000044F4 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
   656 000044F8 7650                <1> 	jna	short loc_gfc_get_fat_free_clusters
   657                              <1> 
   658                              <1> 	; 29/02/2016
   659 000044FA 48                  <1> 	dec	eax ; 0FFFFFFFFh
   660 000044FB 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
   661 000044FE 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
   662 00004501 40                  <1> 	inc	eax ; 0
   663                              <1> 	;
   664 00004502 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
   665 00004506 03466C              <1> 	add	eax, [esi+LD_StartSector]
   666                              <1> 
   667 00004509 BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   668 0000450E B901000000          <1> 	mov	ecx, 1
   669 00004513 E8EA780000          <1>  	call	disk_read
   670 00004518 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
   671                              <1> retn_gfc_get_fsinfo_sec:
   672 0000451A C3                  <1> 	retn
   673                              <1> 
   674                              <1> loc_gfc_check_fsinfo_signs:
   675 0000451B BB[62D90000]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
   676 00004520 813B52526141        <1>         cmp     dword [ebx], 41615252h
   677 00004526 7520                <1> 	jne	short retn_gfc_get_fsinfo_stc
   678                              <1> 	;add	ebx, 484
   679                              <1> 	;cmp	dword [ebx], 61417272h
   680 00004528 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   680 00004531 61                  <1>
   681 00004532 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
   682                              <1> 	;add	ebx, 4
   683                              <1> 	;mov	eax, [ebx]
   684 00004534 8B83E8010000        <1> 	mov	eax, [ebx+488]
   685                              <1> 	; 29/02/2016
   686 0000453A 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
   687 0000453D 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
   688 00004543 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
   689                              <1> 	;
   690 00004546 EB12                <1> 	jmp	short retn_from_get_free_fat32_clusters
   691                              <1> 
   692                              <1> retn_gfc_get_fsinfo_stc:
   693 00004548 F9                  <1> 	stc
   694 00004549 C3                  <1> 	retn
   695                              <1> 
   696                              <1> loc_gfc_get_fat_free_clusters:
   697                              <1> 	;mov	eax, 2
   698 0000454A B002                <1> 	mov	al, 2
   699                              <1> 	;mov	[FAT_CurrentCluster], eax
   700                              <1> loc_gfc_loop_get_next_cluster:
   701 0000454C E805500000          <1> 	call	get_next_cluster
   702 00004551 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
   703 00004553 21C0                <1> 	and	eax, eax
   704 00004555 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
   705                              <1>  
   706                              <1> retn_from_get_free_fat_clusters:
   707 00004557 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
   708                              <1> retn_from_get_free_fat32_clusters:
   709 0000455A 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   710 0000455E F7E3                <1>       	mul	ebx
   711                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
   712                              <1> retn_get_free_sectors_calc:
   713 00004560 C3                  <1> 	retn
   714                              <1> 
   715                              <1> loc_gfc_free_fat_clusters_cont:
   716 00004561 09C0                <1> 	or	eax, eax
   717 00004563 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
   718 00004565 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 00004568 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
   723 0000456A 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
   724 0000456D 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
   725 0000456F 40                  <1> 	inc	eax
   726                              <1> 	;mov	[FAT_CurrentCluster], eax
   727 00004570 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 00004572 BE[8ECD0000]        <1> 	mov	esi, fd0_type ; 10/01/2016
   742 00004577 BF00010900          <1> 	mov	edi, Logical_DOSDisks
   743 0000457C 08D2                <1> 	or	dl, dl
   744 0000457E 7407                <1> 	jz	short loc_drv_init_fd0_fd1
   745 00004580 81C700010000        <1> 	add	edi, 100h
   746 00004586 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
   747                              <1> loc_drv_init_fd0_fd1:
   748 00004587 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
   749 0000458B 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
   750                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
   751 0000458E 7221                <1> 	jb	short read_fd_boot_sector_retn
   752 00004590 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
   753                              <1> read_fd_boot_sector:
   754 00004593 30F6                <1> 	xor	dh, dh
   755 00004595 B904000000          <1> 	mov	ecx, 4 ; Retry Count
   756                              <1> read_fd_boot_sector_again:
   757 0000459A 51                  <1> 	push 	ecx
   758                              <1> 	;mov	cx, 1
   759 0000459B B101                <1> 	mov	cl, 1
   760 0000459D 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   761 000045A1 BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   762 000045A6 E85BE2FFFF          <1> 	call	int13h
   763 000045AB 59                  <1> 	pop	ecx
   764 000045AC 7304                <1> 	jnc	short use_fd_boot_sector_params
   765 000045AE E2EA                <1> 	loop	read_fd_boot_sector_again
   766                              <1> 
   767                              <1> read_fd_boot_sector_stc_retn:
   768 000045B0 F9                  <1> 	stc
   769                              <1> read_fd_boot_sector_retn:
   770 000045B1 C3                  <1> 	retn
   771                              <1> 
   772                              <1> use_fd_boot_sector_params:
   773                              <1> 	;mov	esi, DOSBootSectorBuff
   774 000045B2 89DE                <1> 	mov	esi, ebx
   775 000045B4 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   776 000045BD 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
   777 000045BF 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
   778 000045C5 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
   779                              <1> 	;
   780 000045CB 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
   781 000045CE 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   782                              <1> 	;
   783                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   784 000045D1 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   785 000045D4 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
   786                              <1> 	;
   787 000045D7 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
   788 000045DA 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
   789 000045DD 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   790 000045E1 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   791 000045E5 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   792 000045E8 6698                <1> 	cbw
   793 000045EA 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   794 000045EE 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   795                              <1> 	;cbw
   796 000045F1 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   797                              <1> 	;
   798 000045F5 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   799 000045F8 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   800 000045FB 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
   801 000045FE 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
   802 00004601 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   803 00004604 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   804 00004607 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   805 0000460A 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   806 0000460D 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
   807 00004610 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   808                              <1> 	;		
   809 00004613 89FE                <1> 	mov	esi, edi
   810 00004615 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 00004618 B101                <1> 	mov	cl, 1
   816 0000461A E8E9770000          <1> 	call	chs_read
   817 0000461F 89DE                <1> 	mov	esi, ebx
   818 00004621 7301                <1> 	jnc	short use_fdfs_mat_sector_params
   819                              <1> 	;jmp	short read_fd_boot_sector_retn
   820 00004623 C3                  <1> 	retn
   821                              <1> use_fdfs_mat_sector_params:
   822 00004624 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   823 00004627 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   824 0000462A 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   825 0000462D 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   826 00004630 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
   827 00004633 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
   828 00004636 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   829 00004639 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   830                              <1> 	;
   831 0000463C 89FE                <1> 	mov	esi, edi
   832 0000463E 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 00004641 B101                <1> 	mov	cl, 1
   837 00004643 E8C0770000          <1> 	call	chs_read
   838 00004648 89DE                <1> 	mov	esi, ebx
   839 0000464A 7220                <1> 	jc	short read_fd_RDT_sector_retn
   840                              <1> use_fdfs_RDT_sector_params:
   841 0000464C 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   842 0000464F 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   843 00004652 57                  <1> 	push	edi
   844                              <1> 	;mov	ecx, 16
   845 00004653 B110                <1> 	mov	cl, 16	
   846 00004655 83C640              <1> 	add	esi, FS_RDT_VolumeName
   847 00004658 83C72C              <1> 	add	edi, LD_FS_VolumeName
   848 0000465B F3A5                <1> 	rep	movsd ; 64 bytes
   849 0000465D 5E                  <1> 	pop	esi
   850 0000465E C6460300            <1> 	mov	byte [esi+LD_FATType], 0
   851 00004662 C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
   852 00004666 E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
   853                              <1> 
   854                              <1> read_fd_RDT_sector_stc_retn:
   855 0000466B F9                  <1> 	stc
   856                              <1> read_fd_RDT_sector_retn:
   857 0000466C C3                  <1> 	retn
   858                              <1> 
   859                              <1> use_fd_fatfs_boot_sector_params:
   860 0000466D 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   861 00004671 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
   862 00004673 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
   863 00004677 72F3                <1> 	jb	short read_fd_RDT_sector_retn
   864 00004679 57                  <1> 	push	edi
   865 0000467A 83C706              <1> 	add	edi, LD_BPB
   866                              <1> 	;mov	ecx, 16
   867 0000467D B110                <1> 	mov	cl, 16
   868 0000467F F3A5                <1> 	rep	movsd ; 64 bytes 
   869 00004681 5E                  <1> 	pop	esi
   870 00004682 31C0                <1> 	xor	eax, eax
   871 00004684 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
   872 00004687 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
   873 0000468B 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
   874 0000468E F7E1                <1>   	mul	ecx
   875                              <1> 	; edx = 0 !
   876 00004690 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
   877 00004694 66895660            <1> 	mov	[esi+LD_FATBegin], dx
   878                              <1> 	;add	eax, edx
   879 00004698 6601D0              <1> 	add	ax, dx
   880 0000469B 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   881 0000469E 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   882 000046A1 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
   883                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
   884 000046A5 66C1E205            <1> 	shl	dx, 5
   885                              <1> 	;add	edx, 511
   886 000046A9 6681C2FF01          <1> 	add	dx, 511
   887                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
   888 000046AE 66C1EA09            <1> 	shr	dx, 9
   889 000046B2 015668              <1> 	add 	[esi+LD_DATABegin], edx
   890                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   891 000046B5 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   892 000046B9 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   893 000046BC 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
   894                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   895 000046BF 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
   896 000046C2 80F901              <1> 	cmp	cl, 1
   897 000046C5 7605                <1> 	jna	short save_fd_fatfs_cluster_count
   898                              <1> 	;sub	edx, edx
   899 000046C7 6629D2              <1> 	sub	dx, dx ; 0
   900 000046CA F7F1                <1> 	div	ecx
   901                              <1> save_fd_fatfs_cluster_count:
   902 000046CC 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 000046CF 29C0                <1> 	sub	eax, eax ; 0  
   909 000046D1 A2[66DB0000]        <1> 	mov	[FAT_BuffValidData], al ; 0
   910 000046D6 A2[67DB0000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
   911 000046DB A3[6ADB0000]        <1> 	mov	[FAT_BuffSector], eax ; 0
   912                              <1> 
   913                              <1> read_fd_FAT_sectors:
   914 000046E0 BB001C0900          <1>   	mov	ebx, FAT_Buffer
   915 000046E5 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
   916                              <1> 	;mov	ecx, 3
   917 000046E9 B103                <1> 	mov	cl, 3 ; 3 sectors
   918 000046EB E818770000          <1> 	call	chs_read
   919 000046F0 7240                <1> 	jc	short read_fd_FAT_sectors_retn
   920                              <1> use_fd_FAT_sectors:
   921 000046F2 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
   922 000046F5 0441                <1> 	add	al, 'A' 
   923 000046F7 A2[67DB0000]        <1> 	mov	[FAT_BuffDrvName], al 
   924 000046FC C605[66DB0000]01    <1>  	mov	byte [FAT_BuffValidData], 1
   925 00004703 E82B000000          <1> 	call	fd_init_calculate_free_clusters
   926 00004708 7228                <1> 	jc	short read_fd_FAT_sectors_retn
   927                              <1>   
   928                              <1> loc_use_fd_boot_sector_params_FAT:
   929 0000470A C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
   930 0000470E C6460401            <1> 	mov	byte [esi+LD_FSType], 1
   931 00004712 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
   932                              <1> loc_cont_use_fd_boot_sector_params:
   933 00004715 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
   934 00004718 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
   935 0000471B 88FB                <1> 	mov	bl, bh
   936 0000471D 80C341              <1> 	add	bl, 'A'
   937 00004720 881E                <1> 	mov	byte [esi+LD_Name], bl
   938 00004722 C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
   939 00004726 C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
   940 0000472A C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
   941 0000472E C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
   942                              <1> 
   943                              <1> read_fd_FAT_sectors_retn:
   944 00004732 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 00004733 29C0                <1> 	sub	eax, eax
   955 00004735 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
   956 00004738 B002                <1> 	mov	al, 2 ; eax = 2
   957                              <1> 
   958                              <1> fd_init_loop_get_next_cluster:
   959 0000473A E830000000          <1> 	call	fd_init_get_next_cluster
   960 0000473F 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 00004741 6621C0              <1> 	and	ax, ax
   968 00004744 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
   969                              <1> 	;inc	dword [esi+LD_FreeSectors]
   970 00004746 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 0000474A 66A1[62DB0000]      <1> 	mov	ax, [FAT_CurrentCluster]
   975                              <1> 	;cmp	eax, [esi+LD_Clusters]
   976 00004750 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
   977 00004754 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
   978                              <1> 	;inc	eax
   979 00004756 6640                <1> 	inc	ax
   980 00004758 EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
   981                              <1> 
   982                              <1> retn_from_fd_init_calculate_free_clusters:
   983 0000475A 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
   984 0000475D 3C01                <1>   	cmp	al, 1
   985 0000475F 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
   986                              <1> 	;movzx	eax, al
   987 00004761 6698                <1> 	cbw
   988                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
   989 00004763 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
   990                              <1>   	;mul	ecx
   991 00004767 66F7E1              <1> 	mul	cx
   992                              <1> 	;mov	[esi+LD_FreeSectors], eax
   993 0000476A 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
   994                              <1> fd_init_calculate_free_clusters_retn:
   995 0000476E 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 0000476F A3[62DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
  1010                              <1> fd_init_get_next_cluster_readnext:
  1011 00004774 29D2                <1> 	sub	edx, edx ; 0
  1012 00004776 BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1013 0000477B F7F3                <1>   	div	ebx
  1014                              <1>   	; EAX = Count of 3 FAT sectors
  1015                              <1>   	; EDX = Buffer entry index
  1016 0000477D 89C1                <1> 	mov	ecx, eax
  1017                              <1> 	;mov	eax, 3
  1018 0000477F B003                <1> 	mov	al, 3
  1019 00004781 F7E2                <1> 	mul	edx ; Multiply by 3
  1020 00004783 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1021 00004786 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1022 00004788 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1023 0000478E 89C8                <1> 	mov	eax, ecx
  1024                              <1> 	;mov	edx, 3
  1025 00004790 66BA0300            <1> 	mov	dx, 3
  1026 00004794 F7E2                <1> 	mul	edx 
  1027                              <1>   	; EAX = FAT Beginning Sector
  1028                              <1> 	; EDX = 0
  1029 00004796 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1030                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1031                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1032 00004798 3A0D[67DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1033 0000479E 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1034 000047A0 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
  1035 000047A6 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1036                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1037 000047A8 A0[62DB0000]        <1> 	mov	al, [FAT_CurrentCluster]
  1038                              <1> 	;shr	eax, 1
  1039 000047AD D0E8                <1> 	shr	al, 1
  1040 000047AF 668B03              <1> 	mov	ax, [ebx]
  1041 000047B2 7306                <1>   	jnc	short fd_init_gnc_even
  1042 000047B4 66C1E804            <1> 	shr	ax, 4
  1043                              <1> fd_init_gnc_clc_retn:
  1044 000047B8 F8                  <1> 	clc
  1045 000047B9 C3                  <1> 	retn
  1046                              <1> 
  1047                              <1> fd_init_gnc_even:
  1048 000047BA 80E40F              <1> 	and	ah, 0Fh
  1049 000047BD C3                  <1> 	retn
  1050                              <1> 
  1051                              <1> fd_init_load_FAT_sectors0:
  1052 000047BE 880D[67DB0000]      <1> 	mov 	[FAT_BuffDrvName], cl
  1053                              <1> fd_init_load_FAT_sectors1:
  1054 000047C4 C605[66DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1055 000047CB A3[6ADB0000]        <1> 	mov	[FAT_BuffSector], eax
  1056 000047D0 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1057 000047D3 BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1058                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1059 000047D8 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1060 000047DC 662B0D[6ADB0000]    <1> 	sub	cx, [FAT_BuffSector]
  1061                              <1>         ;cmp	ecx, 3
  1062 000047E3 6683F903            <1> 	cmp	cx, 3
  1063 000047E7 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1064                              <1> 	;mov	ecx, 3
  1065 000047E9 B903000000          <1> 	mov	ecx, 3
  1066                              <1> fdinit_pass_fix_sector_count_3:  
  1067 000047EE E815760000          <1> 	call	chs_read
  1068 000047F3 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1069 000047F5 C605[66DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1070                              <1> 		; Drv not ready or read Error !
  1071 000047FC B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1072                              <1> 	;xor	edx, edx
  1073 00004801 C3                  <1> 	retn
  1074                              <1> 
  1075                              <1> fd_init_FAT_sectors_no_load_error:
  1076 00004802 C605[66DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1077 00004809 A1[62DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
  1078 0000480E 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 00004813 89DE                <1> 	mov	esi, ebx
  1096 00004815 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1097 0000481B 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1098 00004821 8A06                <1> 	mov     al, [esi+LD_Name]
  1099 00004823 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1100 00004826 80FC01              <1> 	cmp     ah, 1
  1101 00004829 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1102 0000482B 3C41                <1> 	cmp 	al, 'A'
  1103 0000482D 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1104 0000482F 80FC02              <1> 	cmp 	ah, 2 
  1105 00004832 7708                <1> 	ja      short get_FAT32_root_cluster
  1106                              <1> 	
  1107 00004834 E8784E0000          <1> 	call    load_FAT_root_directory
  1108 00004839 730B                <1> 	jnc     short loc_get_volume_name
  1109                              <1> 
  1110                              <1> loc_gfvn_dir_load_err:
  1111 0000483B C3                  <1> 	retn
  1112                              <1> 
  1113                              <1> get_FAT32_root_cluster:
  1114 0000483C 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1115 0000483F E8F84E0000          <1> 	call    load_FAT_sub_directory
  1116 00004844 7224                <1> 	jc	short loc_get_volume_name_retn
  1117                              <1> 
  1118                              <1> loc_get_volume_name:
  1119 00004846 BE00000800          <1>         mov     esi, Directory_Buffer
  1120 0000484B 6631C9              <1> 	xor	cx, cx ; 0
  1121                              <1> check_root_volume_name:
  1122 0000484E 8A06                <1> 	mov	al, [esi]
  1123 00004850 08C0                <1> 	or      al, al
  1124 00004852 7416                <1> 	jz      short loc_get_volume_name_retn
  1125 00004854 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1126 00004858 7410                <1> 	je      short loc_get_volume_name_retn
  1127 0000485A 663B0D[7BDB0000]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1128 00004861 7308                <1> 	jnb     short pass_check_root_volume_name
  1129 00004863 6641                <1> 	inc     cx
  1130 00004865 83C620              <1> 	add     esi, 32
  1131 00004868 EBE4                <1> 	jmp     short check_root_volume_name
  1132                              <1> 
  1133                              <1> loc_get_volume_name_retn:
  1134 0000486A C3                  <1> 	retn
  1135                              <1>     
  1136                              <1> pass_check_root_volume_name:
  1137 0000486B 803D[77DB0000]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1138 00004872 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1139                              <1> 
  1140 00004874 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1141 00004879 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1142 0000487E 31C0                <1> 	xor	eax, eax
  1143 00004880 8A25[76DB0000]      <1> 	mov	ah, [DirBuff_DRV]
  1144 00004886 80EC41              <1> 	sub	ah, 'A' 
  1145 00004889 01C6                <1> 	add	esi, eax
  1146 0000488B A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  1147 00004890 E8C14C0000          <1> 	call	get_next_cluster
  1148 00004895 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1149                              <1>   	
  1150 00004897 83F801              <1> 	cmp     eax, 1
  1151 0000489A F5                  <1> 	cmc
  1152 0000489B C3                  <1> 	retn
  1153                              <1>   
  1154                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1155 0000489C E89B4E0000          <1> 	call	load_FAT_sub_directory
  1156 000048A1 73A3                <1> 	jnc	short loc_get_volume_name
  1157 000048A3 C3                  <1> 	retn
  1158                              <1> 
  1159                              <1> loc_get_volume_name_retn_xor:
  1160 000048A4 31C0                <1> 	xor 	eax, eax
  1161 000048A6 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 000048A7 B416                <1> 	mov	ah, 16h
  1173 000048A9 E858DFFFFF          <1>   	call	int13h
  1174 000048AE 80FC06              <1> 	cmp	ah, 06h
  1175 000048B1 7405                <1> 	je	short loc_gmc_status_retn
  1176 000048B3 08E4                <1> 	or	ah, ah
  1177 000048B5 7401                <1> 	jz	short loc_gmc_status_retn
  1178                              <1> loc_gmc_status_stc_retn:    
  1179 000048B7 F9                  <1> 	stc
  1180                              <1> loc_gmc_status_retn:
  1181 000048B8 C3                  <1> 	retn
  1879                                  %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: 13/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 000048B9 31DB                <1> 	xor	ebx, ebx
    33 000048BB 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 000048BD BE00010900          <1> 	mov	esi, Logical_DOSDisks
    42 000048C2 01DE                <1> 	add	esi, ebx
    43                              <1> loc_ccdrv_dos_drive_name_check:
    44 000048C4 80FA02              <1> 	cmp	dl, 2
    45 000048C7 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    46                              <1> 
    47 000048C9 8A06                <1> 	mov	al, [esi+LD_Name]
    48 000048CB 2C41                <1> 	sub	al, 'A'
    49 000048CD 38D0                <1> 	cmp	al, dl
    50 000048CF 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    51                              <1> 
    52                              <1> loc_ccdrv_drive_not_ready_err:
    53 000048D1 B815000000          <1> 	mov	eax, 15h ; Drive not ready
    54                              <1> loc_change_current_drive_stc_retn:
    55 000048D6 F9                  <1> 	stc
    56 000048D7 C3                  <1> 	retn  
    57                              <1> 
    58                              <1> loc_ccdrv_dos_drive_name_check_ok:
    59 000048D8 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    60 000048DB 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    61 000048DE 7450                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    62                              <1> 
    63 000048E0 80FA01              <1> 	cmp	dl, 1
    64 000048E3 7778                <1> 	ja	short loc_gmcs_init_drv_hd
    65                              <1> 
    66                              <1> loc_gmcs_init_drv_fd:
    67 000048E5 08E4                <1> 	or	ah, ah 
    68                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    69 000048E7 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    70                              <1> 
    71 000048E9 E8B9FFFFFF          <1> 	call	get_media_change_status
    72 000048EE 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    73                              <1> 
    74 000048F0 20E4                <1> 	and	ah, ah
    75 000048F2 7471                <1> 	jz	short loc_change_current_drv3
    76                              <1> 
    77 000048F4 80F406              <1> 	xor	ah, 6
    78 000048F7 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    79                              <1> 
    80                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    81 000048F9 E8440A0000          <1> 	call	get_volume_serial_number
    82 000048FE 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
    83                              <1> 
    84                              <1> loc_ccdrv_call_fd_init:
    85 00004900 E86DFCFFFF          <1> 	call	floppy_drv_init
    86 00004905 7315                <1> 	jnc	short loc_reset_drv_fd_current_dir
    87                              <1> 
    88                              <1> loc_ccdrv_fdinit_fail_retn:
    89 00004907 C3                  <1> 	retn
    90                              <1> 
    91                              <1> loc_ccdrv_check_vol_serial:
    92 00004908 A3[44D30000]        <1> 	mov	[Current_VolSerial], eax
    93                              <1> 	;mov	dl, bh
    94 0000490D E860FCFFFF          <1> 	call	floppy_drv_init
    95 00004912 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
    96                              <1> 
    97 00004914 3B05[44D30000]      <1> 	cmp	eax, [Current_VolSerial]
    98 0000491A 7445                <1> 	je	short loc_change_current_drv2
    99                              <1> 
   100                              <1> loc_reset_drv_fd_current_dir:
   101 0000491C 31C0                <1> 	xor	eax, eax              
   102 0000491E 88467F              <1>         mov	[esi+LD_CDirLevel], al
   103 00004921 89F7                <1> 	mov	edi, esi
   104 00004923 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   105 00004929 B920000000          <1> 	mov	ecx, 32
   106 0000492E F3AB                <1> 	rep	stosd   
   107                              <1>  
   108                              <1> loc_ccdrv_get_FAT_volume_name_0:
   109 00004930 8A4603              <1> 	mov	al, [esi+LD_FATType]
   110 00004933 08C0                <1> 	or	al, al
   111 00004935 742A                <1> 	jz	short loc_change_current_drv2
   112                              <1> 
   113 00004937 56                  <1> 	push	esi 
   114 00004938 3C02                <1> 	cmp	al, 2
   115 0000493A 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   116                              <1>              
   117                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   118 0000493C 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   119 0000493F EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   120                              <1> 
   121                              <1> loc_ccdrv_get_FAT32_vol_name:
   122 00004941 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   123                              <1> loc_ccdrv_get_FAT_volume_name_1:
   124 00004944 53                  <1> 	push	ebx
   125 00004945 56                  <1> 	push	esi
   126 00004946 E8C8FEFFFF          <1> 	call	get_FAT_volume_name
   127 0000494B 5F                  <1> 	pop	edi
   128 0000494C 5B                  <1> 	pop	ebx
   129                              <1> 	; BL = 0
   130 0000494D 720B                <1> 	jc	short loc_change_current_drv1
   131 0000494F 20C0                <1> 	and	al, al
   132 00004951 7407                <1> 	jz	short loc_change_current_drv1
   133                              <1> 
   134                              <1> loc_ccdrv_move_FAT_volume_name:
   135 00004953 B90B000000          <1> 	mov	ecx, 11
   136 00004958 F3A4                <1> 	rep	movsb
   137                              <1> 
   138                              <1> loc_change_current_drv1:
   139 0000495A 5E                  <1> 	pop	esi
   140 0000495B EB04                <1> 	jmp	short loc_change_current_drv2
   141                              <1> 
   142                              <1> loc_gmcs_init_drv_hd:
   143 0000495D 08E4                <1> 	or	ah, ah
   144 0000495F 7404                <1> 	jz	short loc_change_current_drv3
   145                              <1> 	; BL = 0, BH = Logical DOS drive number
   146                              <1> loc_change_current_drv2:
   147 00004961 C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   148                              <1> loc_change_current_drv3:
   149 00004965 883D[4ED30000]      <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 0000496B 8A4603              <1> 	mov	al, [esi+LD_FATType]
   168 0000496E A2[4DD30000]        <1> 	mov	[Current_FATType], al
   169                              <1> 
   170 00004973 8A26                <1> 	mov	ah, [esi+LD_Name] 
   171 00004975 8825[4FD30000]      <1> 	mov	[Current_Dir_Drv], ah
   172                              <1> 
   173 0000497B 20C0                <1> 	and	al, al
   174 0000497D 741D                <1> 	jz	short loc_restore_FS_current_directory
   175                              <1> 
   176                              <1> loc_restore_FAT_current_directory:
   177 0000497F 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   178 00004982 8825[4CD30000]      <1> 	mov	[Current_Dir_Level], ah
   179 00004988 08E4                <1> 	or	ah, ah
   180 0000498A 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   181                              <1> 
   182 0000498C 0FB6D4              <1> 	movzx	edx, ah
   183 0000498F C0E204              <1> 	shl	dl, 4 ; * 16
   184 00004992 01F2                <1>         add	edx, esi
   185 00004994 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   186 0000499A EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   187                              <1> 
   188                              <1> loc_restore_FS_current_directory:
   189 0000499C E8D64D0000          <1> 	call	load_current_FS_directory 
   190 000049A1 C3                  <1> 	retn 
   191                              <1> 
   192                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   193 000049A2 3C03                <1> 	cmp	al, 3
   194 000049A4 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   195                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   196 000049A6 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   197 000049A9 EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   198                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   199 000049AB 30C0                <1> 	xor	al, al  ; xor eax, eax
   200 000049AD 31D2                <1> 	xor	edx, edx
   201                              <1> loc_ccdrv_check_rootdir_sign:
   202 000049AF 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   203 000049B6 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   204                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   205 000049B8 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   206 000049BE C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   206 000049C7 54                  <1>
   207                              <1> 
   208                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   209 000049C8 A3[48D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   210                              <1> 
   211 000049CD BF[AFDB0000]        <1> 	mov	edi, PATH_Array
   212 000049D2 89F2                <1> 	mov	edx, esi
   213 000049D4 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   214 000049DA B920000000          <1> 	mov	ecx, 32
   215 000049DF F3A5                <1> 	rep	movsd
   216                              <1> 
   217 000049E1 E8852D0000          <1> 	call	change_prompt_dir_string
   218                              <1> 	
   219 000049E6 89D6                <1> 	mov	esi, edx
   220                              <1> 	
   221 000049E8 29C0                <1>         sub	eax, eax
   222                              <1>        ;sub	edx, edx
   223 000049EA BF[4FD30000]        <1> 	mov	edi, Current_Dir_Drv
   224                              <1> 
   225 000049EF A2[E3C10000]        <1> 	mov	[Restore_CDIR], al ; 0
   226 000049F4 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 000049F5 C705[FCDF0000]-     <1> 	mov	dword [mainprog_return_addr], return_from_command_intepreter
   238 000049FB [A94A0000]          <1>
   239                              <1> 
   240                              <1> loc_TRDOS_prompt:
   241 000049FF BF[4ED40000]        <1> 	mov	edi, TextBuffer
   242 00004A04 C6075B              <1> 	mov	byte [edi], "["
   243 00004A07 47                  <1> 	inc	edi
   244 00004A08 BE[36C20000]        <1> 	mov	esi, TRDOSPromptLabel
   245                              <1> get_next_prompt_label_char:
   246 00004A0D 803E20              <1> 	cmp	byte [esi], 20h
   247 00004A10 7203                <1> 	jb	short pass_prompt_label
   248 00004A12 A4                  <1> 	movsb
   249 00004A13 EBF8                <1> 	jmp	short get_next_prompt_label_char
   250                              <1> pass_prompt_label:
   251 00004A15 C6075D              <1> 	mov	byte [edi], "]"
   252 00004A18 47                  <1> 	inc	edi
   253 00004A19 C60720              <1> 	mov	byte [edi], 20h
   254 00004A1C 47                  <1> 	inc	edi
   255 00004A1D BE[4FD30000]        <1> 	mov	esi, Current_Dir_Drv
   256 00004A22 66A5                <1> 	movsw
   257 00004A24 A4                  <1> 	movsb 
   258                              <1> loc_prompt_current_directory:
   259 00004A25 803E20              <1> 	cmp	byte [esi], 20h
   260 00004A28 7203                <1> 	jb	short pass_prompt_current_directory
   261 00004A2A A4                  <1> 	movsb
   262 00004A2B EBF8                <1> 	jmp	short loc_prompt_current_directory  
   263                              <1> pass_prompt_current_directory:
   264 00004A2D C6073E              <1> 	mov	byte [edi], '>'
   265 00004A30 47                  <1> 	inc	edi
   266 00004A31 C60700              <1> 	mov	byte [edi], 0  
   267 00004A34 BE[4ED40000]        <1> 	mov	esi, TextBuffer
   268 00004A39 E876F5FFFF          <1> 	call	print_msg
   269                              <1>         
   270                              <1> 	;sub	bh, bh ; video page = 0
   271                              <1> 	;call	get_cpos ; get cursor position
   272 00004A3E 668B15[A8D20000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   273 00004A45 8815[AED30000]      <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 00004A4B E899000000          <1> 	call	rw_char
   293                              <1> loc_move_command:
   294 00004A50 BE[FED30000]        <1> 	mov	esi, CommandBuffer
   295 00004A55 89F7                <1> 	mov	edi, esi
   296 00004A57 31C9                <1> 	xor	ecx, ecx
   297                              <1> first_command_char:
   298 00004A59 AC                  <1> 	lodsb
   299 00004A5A 3C20                <1> 	cmp	al, 20h
   300 00004A5C 772E                <1> 	ja	short pass_space_control
   301 00004A5E 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   302 00004A60 81FE[4DD40000]      <1> 	cmp	esi, CommandBuffer + 79
   303 00004A66 72F1                <1> 	jb	short first_command_char
   304 00004A68 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   305                              <1> 
   306                              <1> next_command_char:
   307 00004A6A AC                  <1> 	lodsb
   308 00004A6B 3C20                <1> 	cmp	al, 20h
   309 00004A6D 771D                <1> 	ja	short pass_space_control
   310 00004A6F 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   311                              <1> 
   312                              <1> loc_1st_cmd_arg: ; 30/01/2016
   313 00004A71 AC                  <1> 	lodsb
   314 00004A72 3C20                <1> 	cmp	al, 20h
   315 00004A74 74FB                <1> 	je	short loc_1st_cmd_arg
   316 00004A76 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   317                              <1> 	
   318 00004A78 C60700              <1>         mov     byte [edi], 0
   319 00004A7B 47                  <1> 	inc	edi
   320                              <1> 
   321                              <1> loc_move_cmd_arguments:
   322 00004A7C AA                  <1> 	stosb
   323 00004A7D 81FE[4DD40000]      <1> 	cmp	esi, CommandBuffer + 79
   324 00004A83 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   325 00004A85 AC                  <1>         lodsb
   326 00004A86 3C20                <1> 	cmp	al, 20h
   327 00004A88 73F2                <1> 	jnb	short loc_move_cmd_arguments
   328 00004A8A EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   329                              <1> 
   330                              <1> pass_space_control:
   331 00004A8C 3C61                <1> 	cmp	al, 61h
   332 00004A8E 7206                <1> 	jb	short pass_capitalize
   333 00004A90 3C7A                <1> 	cmp	al, 7Ah
   334 00004A92 7702                <1> 	ja	short pass_capitalize
   335 00004A94 24DF                <1> 	and	al, 0DFh
   336                              <1> pass_capitalize:
   337 00004A96 AA                  <1> 	stosb   
   338 00004A97 FEC1                <1> 	inc     cl
   339 00004A99 81FE[4DD40000]      <1>         cmp     esi, CommandBuffer + 79
   340 00004A9F 72C9                <1> 	jb      short next_command_char 
   341                              <1> 
   342                              <1> loc_move_cmd_arguments_ok:
   343 00004AA1 C60700              <1>         mov     byte [edi], 0
   344                              <1>        
   345                              <1> call_command_intepreter:
   346 00004AA4 E8D4080000          <1> 	call    command_interpreter
   347                              <1> 
   348                              <1> return_from_command_intepreter:
   349 00004AA9 B950000000          <1>         mov	ecx, 80
   350                              <1> 	;mov	cx, 80
   351 00004AAE BF[FED30000]        <1> 	mov	edi, CommandBuffer
   352 00004AB3 30C0                <1> 	xor	al, al
   353 00004AB5 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 00004AB7 803D[E6CC0000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   359 00004ABE 741D                <1> 	je	short pass_set_txt_mode
   360                              <1> 
   361 00004AC0 E81AC9FFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   362                              <1> 
   363                              <1> loc_check_active_page:
   364 00004AC5 30C0                <1> 	xor	al, al
   365 00004AC7 3805[B8D20000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   366 00004ACD 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   367                              <1> 	; AL = 0 = video page 0
   368 00004AD3 E8D3C9FFFF          <1> 	call	set_active_page
   369 00004AD8 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   370                              <1> 
   371                              <1> pass_set_txt_mode: 
   372 00004ADD BE[20CF0000]        <1> 	mov	esi, nextline
   373 00004AE2 E8CDF4FFFF          <1> 	call	print_msg
   374 00004AE7 EBDC                <1> 	jmp     short loc_check_active_page
   375                              <1> 
   376                              <1> rw_char:
   377                              <1> 	; 13/05/2016
   378                              <1> 	; 30/01/2016
   379                              <1> 	; 29/01/2016
   380                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   381                              <1> 	; 2004-2005
   382                              <1> 	
   383                              <1> 	; DH = cursor row, DL = cursor column
   384                              <1> 	; BH = 0 = video page number (active page)
   385                              <1> 
   386                              <1> 	;xor	bh, bh ; 0 = video page 0
   387                              <1> 
   388                              <1> readnextchar:
   389 00004AE9 30E4                <1> 	xor     ah, ah
   390 00004AEB E8ACBFFFFF          <1> 	call	int16h
   391 00004AF0 20C0                <1> 	and	al, al
   392 00004AF2 7434                <1> 	jz	short loc_arrow    
   393 00004AF4 3CE0                <1> 	cmp	al, 0E0h          
   394 00004AF6 7430                <1> 	je	short loc_arrow
   395 00004AF8 3C08                <1> 	cmp	al, 08h             
   396 00004AFA 7544                <1> 	jne	short char_return
   397                              <1> loc_back:
   398 00004AFC 3A15[AED30000]      <1> 	cmp	dl, [CursorColumn]
   399 00004B02 76E5                <1> 	jna     short readnextchar
   400                              <1> prev_column:
   401 00004B04 FECA                <1> 	dec	dl
   402                              <1> set_cursor_pos:
   403 00004B06 6652                <1> 	push	dx
   404                              <1> 	;xor	bh, bh ; 0 = video page 0
   405                              <1> 	; DH = Row, DL = Column
   406 00004B08 E866CCFFFF          <1> 	call	_set_cpos ; 17/01/2016
   407 00004B0D 665A                <1>         pop	dx
   408                              <1> 	;movzx	ebx, dl
   409 00004B0F 88D3                <1> 	mov	bl, dl
   410 00004B11 2A1D[AED30000]      <1> 	sub	bl, [CursorColumn] 
   411 00004B17 B020                <1> 	mov	al, 20h
   412 00004B19 8883[FED30000]      <1> 	mov	[CommandBuffer+ebx], al
   413                              <1> 	;sub	bh, bh ; video page 0
   414                              <1> 	;mov	cx, 1
   415 00004B1F B307                <1> 	mov	bl, 7 ; color attribute
   416 00004B21 E885CBFFFF          <1> 	call	_write_c_current ; 17/01/2016
   417                              <1> 	;mov	dx, [CURSOR_POSN]
   418 00004B26 EBC1                <1> 	jmp	short readnextchar
   419                              <1> loc_arrow:    
   420 00004B28 80FC4B              <1> 	cmp	ah, 4Bh
   421 00004B2B 74CF                <1> 	je	short loc_back
   422 00004B2D 80FC53              <1> 	cmp	ah, 53h
   423 00004B30 74CA                <1> 	je      short loc_back
   424 00004B32 80FC4D              <1> 	cmp	ah, 4Dh
   425 00004B35 75B2                <1> 	jne	short readnextchar
   426 00004B37 80FA4F              <1> 	cmp	dl, 79
   427 00004B3A 73AD                <1> 	jnb	short readnextchar
   428 00004B3C FEC2                <1> 	inc	dl
   429 00004B3E EBC6                <1> 	jmp	short set_cursor_pos
   430                              <1> char_return:
   431 00004B40 0FB6DA              <1> 	movzx	ebx, dl
   432 00004B43 2A1D[AED30000]      <1> 	sub	bl, [CursorColumn] 
   433 00004B49 3C20                <1> 	cmp	al, 20h
   434 00004B4B 7220                <1> 	jb	short loc_escape
   435 00004B4D 8883[FED30000]      <1> 	mov	[CommandBuffer+ebx], al
   436 00004B53 80FA4F              <1> 	cmp	dl, 79
   437 00004B56 7391                <1> 	jnb	short readnextchar
   438 00004B58 66BB0700            <1> 	mov	bx, 7 ; color attribute
   439 00004B5C E887CBFFFF          <1> 	call	_write_tty
   440 00004B61 668B15[A8D20000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   441 00004B68 E97CFFFFFF          <1>         jmp     readnextchar
   442                              <1> loc_escape:
   443 00004B6D 3C1B                <1> 	cmp	al, 1Bh
   444 00004B6F 7418                <1> 	je	short rw_char_retn
   445                              <1> 	;
   446 00004B71 3C0D                <1> 	cmp	al, 0Dh ; CR
   447 00004B73 0F8570FFFFFF        <1>         jne     readnextchar
   448                              <1> 	; 13/05/2016
   449 00004B79 66BB0700            <1> 	mov	bx, 7 ; attribute/color (bl)
   450                              <1> 		      ; video page 0 (bh=0)	
   451 00004B7D E866CBFFFF          <1> 	call	_write_tty
   452                              <1> 	;mov	bx, 7  ; attribute/color
   453                              <1> 		      ; video page 0 (bh=0)
   454 00004B82 B00A                <1> 	mov	al, 0Ah ; LF
   455 00004B84 E85FCBFFFF          <1> 	call	_write_tty
   456                              <1> rw_char_retn:
   457 00004B89 C3                  <1> 	retn
   458                              <1> 
   459                              <1> show_date:
   460                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   461                              <1>         ; 2004-2005
   462                              <1> 
   463                              <1> 	;mov	ah, 04h
   464                              <1> 	;call	int1Ah
   465 00004B8A E84FF1FFFF          <1> 	call	RTC_40	; GET RTC DATE
   466                              <1> 
   467 00004B8F 88D0                <1> 	mov	al, dl
   468 00004B91 E8FDBEFFFF          <1>   	call	bcd_to_ascii
   469 00004B96 66A3[2BC30000]      <1> 	mov	[Day], ax
   470                              <1> 
   471 00004B9C 88F0                <1> 	mov	al, dh
   472 00004B9E E8F0BEFFFF          <1>   	call	bcd_to_ascii
   473 00004BA3 66A3[2EC30000]      <1> 	mov	[Month], ax
   474                              <1> 
   475 00004BA9 88E8                <1> 	mov	al, ch
   476 00004BAB E8E3BEFFFF          <1>   	call	bcd_to_ascii
   477 00004BB0 66A3[31C30000]      <1> 	mov	[Century], ax
   478                              <1> 
   479 00004BB6 88C8                <1> 	mov	al, cl
   480 00004BB8 E8D6BEFFFF          <1>   	call	bcd_to_ascii
   481 00004BBD 66A3[33C30000]      <1> 	mov	word [Year], ax
   482                              <1> 
   483 00004BC3 BE[1BC30000]        <1> 	mov	esi, Msg_Show_Date
   484 00004BC8 E8E7F3FFFF          <1> 	call	print_msg
   485                              <1> 
   486 00004BCD C3                  <1> 	retn
   487                              <1> 
   488                              <1> set_date:
   489                              <1> 	; 13/05/2016
   490                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   491                              <1>         ; 2004-2005
   492                              <1> 
   493 00004BCE BE[FFC20000]        <1> 	mov	esi, Msg_Enter_Date
   494 00004BD3 E8DCF3FFFF          <1> 	call	print_msg
   495                              <1> 
   496                              <1> loc_enter_day_1:
   497 00004BD8 30E4                <1> 	xor     ah, ah
   498 00004BDA E8BDBEFFFF          <1> 	call	int16h
   499                              <1> 	; AL = ASCII Code of the Character
   500 00004BDF 3C0D                <1> 	cmp	al, 13
   501 00004BE1 0F84B7010000        <1> 	je	loc_set_date_retn
   502 00004BE7 3C1B                <1> 	cmp	al, 27
   503 00004BE9 0F84AF010000        <1> 	je	loc_set_date_retn
   504 00004BEF A2[2BC30000]        <1> 	mov	[Day], al
   505 00004BF4 3C30                <1> 	cmp	al, '0'
   506 00004BF6 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   507 00004BFC 3C33                <1> 	cmp	al, '3'
   508 00004BFE 0F87A5010000        <1> 	ja	loc_set_date_stc_0
   509                              <1> 	; 13/05/2016
   510                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   511                              <1> 		      ; video page 0 (bh)	
   512 00004C04 B307                <1> 	mov	bl, 7
   513 00004C06 E8DDCAFFFF          <1> 	call	_write_tty
   514                              <1> loc_enter_day_2:
   515 00004C0B 30E4                <1> 	xor     ah, ah
   516 00004C0D E88ABEFFFF          <1> 	call	int16h
   517                              <1> 	; AL = ASCII Code of the Character
   518 00004C12 3C1B                <1> 	cmp	al, 27
   519 00004C14 0F8484010000        <1>         je      loc_set_date_retn
   520 00004C1A A2[2CC30000]        <1> 	mov	[Day+1], al
   521 00004C1F 3C30                <1> 	cmp	al, '0'
   522 00004C21 0F828C010000        <1>         jb      loc_set_date_stc_1
   523 00004C27 3C39                <1> 	cmp	al, '9'
   524 00004C29 0F8784010000        <1>         ja      loc_set_date_stc_1
   525 00004C2F 803D[2BC30000]33    <1> 	cmp	byte [Day], '3'
   526 00004C36 7208                <1> 	jb	short pass_set_day_31
   527 00004C38 3C31                <1> 	cmp	al, '1'
   528 00004C3A 0F8773010000        <1>         ja      loc_set_date_stc_1
   529                              <1> pass_set_day_31:
   530                              <1> 	; 13/05/2016
   531                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   532                              <1> 		      ; video page 0 (bh)	
   533 00004C40 B307                <1> 	mov	bl, 7
   534 00004C42 E8A1CAFFFF          <1> 	call	_write_tty
   535                              <1> loc_enter_separator_1:
   536 00004C47 28E4                <1> 	sub     ah, ah ; 0
   537 00004C49 E84EBEFFFF          <1> 	call	int16h
   538                              <1> 	; AL = ASCII Code of the Character
   539 00004C4E 3C1B                <1> 	cmp	al, 27
   540 00004C50 0F8448010000        <1>         je      loc_set_date_retn
   541 00004C56 3C2D                <1> 	cmp	al, '-'
   542 00004C58 7408                <1> 	je	short pass_set_date_separator_1
   543 00004C5A 3C2F                <1> 	cmp	al, '/'
   544 00004C5C 0F856C010000        <1>         jne     loc_set_date_stc_2
   545                              <1> pass_set_date_separator_1:
   546                              <1> 	; 13/05/2016
   547                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   548                              <1> 		      ; video page 0 (bh)
   549 00004C62 B307                <1> 	mov	bl, 7	
   550 00004C64 E87FCAFFFF          <1> 	call	_write_tty
   551                              <1> loc_enter_month_1:
   552 00004C69 30E4                <1> 	xor     ah, ah ; 0
   553 00004C6B E82CBEFFFF          <1> 	call	int16h
   554                              <1> 	; AL = ASCII Code of the Character
   555 00004C70 3C1B                <1> 	cmp	al, 27
   556 00004C72 0F8426010000        <1>         je      loc_set_date_retn
   557 00004C78 A2[2EC30000]        <1> 	mov	[Month], al
   558 00004C7D 3C30                <1> 	cmp	al, '0'
   559 00004C7F 0F8264010000        <1>         jb      loc_set_date_stc_3
   560 00004C85 3C31                <1> 	cmp	al, '1'
   561 00004C87 0F875C010000        <1>         ja      loc_set_date_stc_3
   562                              <1> 	; 13/05/2016
   563                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   564                              <1> 		      ; video page 0 (bh)	
   565 00004C8D B307                <1> 	mov	bl, 7
   566 00004C8F E854CAFFFF          <1> 	call	_write_tty
   567                              <1> loc_enter_month_2:
   568 00004C94 30E4                <1> 	xor     ah, ah
   569 00004C96 E801BEFFFF          <1> 	call	int16h
   570                              <1> 	; AL = ASCII Code of the Character
   571 00004C9B 3C1B                <1> 	cmp	al, 27
   572 00004C9D 0F84FB000000        <1>         je      loc_set_date_retn
   573 00004CA3 A2[2FC30000]        <1> 	mov	[Month+1], al
   574 00004CA8 3C30                <1> 	cmp	al, '0'
   575 00004CAA 0F8254010000        <1>         jb      loc_set_date_stc_4
   576 00004CB0 3C39                <1> 	cmp	al, '9'
   577 00004CB2 0F874C010000        <1>         ja      loc_set_date_stc_4
   578 00004CB8 803D[2EC30000]31    <1> 	cmp	byte [Month], '1'
   579 00004CBF 7208                <1> 	jb	short pass_set_month_12
   580 00004CC1 3C32                <1> 	cmp	al, '2'
   581 00004CC3 0F873B010000        <1>         ja      loc_set_date_stc_4
   582                              <1> pass_set_month_12:
   583                              <1> 	; 13/05/2016
   584                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   585                              <1> 		      ; video page 0 (bh)
   586 00004CC9 B307                <1> 	mov	bl, 7	
   587 00004CCB E818CAFFFF          <1> 	call	_write_tty
   588                              <1> loc_enter_separator_2:
   589 00004CD0 28E4                <1> 	sub     ah, ah
   590 00004CD2 E8C5BDFFFF          <1> 	call	int16h
   591                              <1> 	; AL = ASCII Code of the Character
   592 00004CD7 3C1B                <1> 	cmp	al, 27
   593 00004CD9 0F84BF000000        <1>         je      loc_set_date_retn
   594 00004CDF 3C2D                <1> 	cmp	al, '-'
   595 00004CE1 7408                <1> 	je	short pass_set_date_separator_2
   596 00004CE3 3C2F                <1> 	cmp	al, '/'
   597 00004CE5 0F8534010000        <1>         jne     loc_set_date_stc_5
   598                              <1> pass_set_date_separator_2:
   599                              <1> 	; 13/05/2016
   600                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   601                              <1> 		      ; video page 0 (bh)	
   602 00004CEB B307                <1> 	mov	bl, 7
   603 00004CED E8F6C9FFFF          <1> 	call	_write_tty
   604                              <1> loc_enter_year_1:
   605 00004CF2 30E4                <1> 	xor    ah, ah
   606 00004CF4 E8A3BDFFFF          <1> 	call	int16h
   607                              <1> 	; AL = ASCII Code of the Character
   608 00004CF9 3C1B                <1> 	cmp	al, 27
   609 00004CFB 0F849D000000        <1>         je      loc_set_date_retn
   610 00004D01 A2[33C30000]        <1> 	mov	[Year], al
   611 00004D06 3C30                <1> 	cmp	al, '0'
   612 00004D08 0F822C010000        <1>         jb      loc_set_date_stc_6
   613 00004D0E 3C39                <1> 	cmp	al, '9'
   614 00004D10 0F8724010000        <1>         ja      loc_set_date_stc_6
   615                              <1> 	; 13/05/2016
   616                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   617                              <1> 		      ; video page 0 (bh)
   618 00004D16 B307                <1> 	mov	bl, 7	
   619 00004D18 E8CBC9FFFF          <1> 	call	_write_tty
   620                              <1> loc_enter_year_2:
   621 00004D1D 30E4                <1> 	xor	ah, ah
   622 00004D1F E878BDFFFF          <1> 	call	int16h
   623                              <1> 	; AL = ASCII Code of the Character
   624 00004D24 3C1B                <1> 	cmp	al, 27
   625 00004D26 7476                <1> 	je	short loc_set_date_retn
   626 00004D28 A2[34C30000]        <1> 	mov	byte [Year+1], al
   627 00004D2D 3C30                <1> 	cmp	al, '0'
   628 00004D2F 0F8220010000        <1>         jb      loc_set_date_stc_7
   629 00004D35 3C39                <1> 	cmp	al, '9'
   630 00004D37 0F8718010000        <1>         ja      loc_set_date_stc_7
   631                              <1> 	; 13/05/2016
   632                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   633                              <1> 		      ; video page 0 (bh)
   634 00004D3D B307                <1> 	mov	bl, 7	
   635 00004D3F E8A4C9FFFF          <1> 	call	_write_tty
   636                              <1> loc_set_date_get_lchar_again:
   637 00004D44 28E4                <1> 	sub	ah, ah ; 0
   638 00004D46 E851BDFFFF          <1> 	call	int16h
   639                              <1> 	; AL = ASCII Code of the Character
   640 00004D4B 3C0D                <1> 	cmp	al, 13 ; ENTER key
   641 00004D4D 7412                <1> 	je	short loc_set_date_progress
   642 00004D4F 3C1B                <1> 	cmp	al, 27 ; ESC key
   643 00004D51 744B                <1> 	je	short loc_set_date_retn
   644                              <1> 	;
   645 00004D53 E82A010000          <1> 	call	check_for_backspace
   646 00004D58 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   647                              <1> 
   648                              <1> loc_set_date_bs_8:
   649 00004D5A E811010000          <1> 	call	write_backspace
   650 00004D5F EBBC                <1> 	jmp	short loc_enter_year_2
   651                              <1> 
   652                              <1> loc_set_date_progress:
   653                              <1> 	; Get Current Date
   654                              <1> 	;mov	ah, 04h
   655                              <1> 	;call	int1Ah
   656 00004D61 E878EFFFFF          <1> 	call	RTC_40	; GET RTC DATE
   657                              <1> 	; CH = century (in BCD)
   658                              <1> 
   659 00004D66 66A1[33C30000]      <1> 	mov	ax, [Year]
   660 00004D6C 662D3030            <1> 	sub	ax, '00'
   661 00004D70 C0E004              <1> 	shl	al, 4 ; * 16
   662 00004D73 88C1                <1> 	mov	cl, al
   663 00004D75 00E1                <1> 	add	cl, ah
   664 00004D77 66A1[2EC30000]      <1> 	mov	ax, [Month]
   665 00004D7D 662D3030            <1> 	sub	ax, '00'
   666 00004D81 C0E004              <1> 	shl	al, 4 ; * 16
   667 00004D84 88C6                <1> 	mov	dh, al
   668 00004D86 00E6                <1> 	add	dh, ah
   669 00004D88 66A1[2BC30000]      <1> 	mov	ax, [Day]
   670 00004D8E 662D3030            <1> 	sub	ax, '00'
   671 00004D92 C0E004              <1> 	shl	al, 4 ; * 16
   672 00004D95 88C2                <1> 	mov	dl, al
   673 00004D97 00E2                <1> 	add	dl, ah
   674                              <1> 
   675                              <1> 	;mov	ah, 05h
   676                              <1> 	;call	int1Ah
   677 00004D99 E86DEFFFFF          <1> 	call	RTC_50	; SET RTC DATE
   678                              <1> 
   679                              <1> loc_set_date_retn:
   680 00004D9E BE[20CF0000]        <1> 	mov	esi, nextline
   681 00004DA3 E80CF2FFFF          <1> 	call	print_msg
   682 00004DA8 C3                  <1> 	retn
   683                              <1> 
   684                              <1> loc_set_date_stc_0:
   685                              <1> 	;xor	bh, bh ; video page 0
   686 00004DA9 E80FCAFFFF          <1> 	call	beeper ; BEEP !
   687 00004DAE E925FEFFFF          <1>         jmp     loc_enter_day_1
   688                              <1> loc_set_date_stc_1:
   689 00004DB3 E8CA000000          <1> 	call	check_for_backspace
   690 00004DB8 740A                <1> 	je	short loc_set_date_bs_1
   691                              <1> 	;xor	bh, bh ; video page 0
   692 00004DBA E8FEC9FFFF          <1> 	call	beeper ; BEEP !
   693 00004DBF E947FEFFFF          <1>         jmp     loc_enter_day_2
   694                              <1> loc_set_date_bs_1:
   695 00004DC4 E8A7000000          <1> 	call	write_backspace
   696 00004DC9 E90AFEFFFF          <1>         jmp     loc_enter_day_1
   697                              <1> loc_set_date_stc_2:
   698 00004DCE E8AF000000          <1> 	call	check_for_backspace
   699 00004DD3 740A                <1> 	je	short loc_set_date_bs_2
   700                              <1> 	;xor	bh, bh ; video page 0
   701 00004DD5 E8E3C9FFFF          <1> 	call	beeper ; BEEP !
   702 00004DDA E968FEFFFF          <1>         jmp     loc_enter_separator_1
   703                              <1> loc_set_date_bs_2:
   704 00004DDF E88C000000          <1> 	call	write_backspace
   705 00004DE4 E922FEFFFF          <1>         jmp     loc_enter_day_2
   706                              <1> loc_set_date_stc_3:
   707 00004DE9 E894000000          <1> 	call	check_for_backspace	
   708 00004DEE 740A                <1> 	je short loc_set_date_bs_3
   709                              <1> 	;xor	bh, bh ; video page 0
   710 00004DF0 E8C8C9FFFF          <1> 	call	beeper ; BEEP !
   711 00004DF5 E96FFEFFFF          <1>         jmp     loc_enter_month_1
   712                              <1> loc_set_date_bs_3:
   713 00004DFA E871000000          <1> 	call	write_backspace
   714 00004DFF E943FEFFFF          <1>         jmp     loc_enter_separator_1
   715                              <1> loc_set_date_stc_4:
   716 00004E04 E879000000          <1> 	call	check_for_backspace	
   717 00004E09 740A                <1> 	je	short loc_set_date_bs_4
   718                              <1> 	;xor	bh, bh ; video page 0
   719 00004E0B E8ADC9FFFF          <1> 	call	beeper ; BEEP !
   720 00004E10 E97FFEFFFF          <1>         jmp     loc_enter_month_2
   721                              <1> loc_set_date_bs_4:
   722 00004E15 E856000000          <1> 	call	write_backspace
   723 00004E1A E94AFEFFFF          <1>         jmp     loc_enter_month_1
   724                              <1> loc_set_date_stc_5:
   725 00004E1F E85E000000          <1> 	call	check_for_backspace
   726 00004E24 740A                <1> 	je	short loc_set_date_bs_5
   727                              <1> 	;xor	bh, bh ; video page 0
   728 00004E26 E892C9FFFF          <1> 	call	beeper ; BEEP !
   729 00004E2B E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   730                              <1> loc_set_date_bs_5:
   731 00004E30 E83B000000          <1> 	call	write_backspace
   732 00004E35 E95AFEFFFF          <1>         jmp     loc_enter_month_2
   733                              <1> loc_set_date_stc_6:
   734 00004E3A E843000000          <1> 	call	check_for_backspace
   735 00004E3F 740A                <1>         je      short  loc_set_date_bs_6
   736                              <1> 	;xor	bh, bh ; video page 0
   737 00004E41 E877C9FFFF          <1> 	call	beeper ; BEEP !
   738 00004E46 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   739                              <1> loc_set_date_bs_6:
   740 00004E4B E820000000          <1> 	call	write_backspace
   741 00004E50 E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   742                              <1> loc_set_date_stc_7:
   743 00004E55 E828000000          <1> 	call	check_for_backspace
   744 00004E5A 740A                <1> 	je	short loc_set_date_bs_7
   745                              <1> 	;xor	bh, bh ; video page 0
   746 00004E5C E85CC9FFFF          <1> 	call	beeper ; BEEP !
   747 00004E61 E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   748                              <1> loc_set_date_bs_7:
   749 00004E66 E805000000          <1> 	call	write_backspace
   750 00004E6B E982FEFFFF          <1>         jmp     loc_enter_year_1
   751                              <1> 
   752                              <1> write_backspace:
   753                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   754 00004E70 B008                <1> 	mov	al, 08h ; BACKSPACE
   755                              <1> 	; 13/05/2016
   756 00004E72 66BB0700            <1> 	mov	bx, 7 ; bl = attribute/color
   757                              <1> 		      ; bh = video page = 0	
   758 00004E76 E86DC8FFFF          <1> 	call	_write_tty
   759 00004E7B B020                <1> 	mov	al, 20h ; BLANK/SPACE char 
   760                              <1> 	;mov	bx, 7 ; attribute/color
   761                              <1> 	;call	_write_c_current
   762                              <1> 	;retn
   763 00004E7D E929C8FFFF          <1> 	jmp	_write_c_current
   764                              <1> 
   765                              <1> check_for_backspace:
   766                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   767 00004E82 663D080E            <1> 	cmp	ax, 0E08h
   768 00004E86 7410                <1> 	je	short cfbs_retn
   769 00004E88 663DE04B            <1> 	cmp	ax, 4BE0h
   770 00004E8C 740A                <1> 	je	short cfbs_retn
   771 00004E8E 663D004B            <1> 	cmp	ax, 4B00h
   772 00004E92 7404                <1> 	je	short cfbs_retn
   773 00004E94 663DE053            <1> 	cmp	ax, 53E0h
   774                              <1> cfbs_retn:
   775 00004E98 C3                  <1> 	retn
   776                              <1> 
   777                              <1> show_time:
   778                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   779                              <1>         ; 2004-2005
   780                              <1> 
   781                              <1> 	;mov	ah, 02h
   782                              <1> 	;call	int1Ah
   783 00004E99 E8CFEDFFFF          <1> 	call	RTC_20	; GET RTC TIME
   784                              <1> 	
   785 00004E9E 88E8                <1> 	mov	al, ch
   786 00004EA0 E8EEBBFFFF          <1> 	call	bcd_to_ascii
   787 00004EA5 66A3[59C30000]      <1> 	mov	[Hour], ax
   788                              <1> 
   789 00004EAB 88C8                <1> 	mov	al, cl
   790 00004EAD E8E1BBFFFF          <1> 	call	bcd_to_ascii
   791 00004EB2 66A3[5CC30000]      <1> 	mov	[Minute], ax
   792                              <1> 
   793 00004EB8 88F0                <1> 	mov	al, dh
   794 00004EBA E8D4BBFFFF          <1> 	call	bcd_to_ascii
   795 00004EBF 66A3[5FC30000]      <1> 	mov	[Second], ax
   796                              <1> 
   797 00004EC5 BE[49C30000]        <1> 	mov	esi, Msg_Show_Time
   798 00004ECA E8E5F0FFFF          <1> 	call	print_msg
   799 00004ECF C3                  <1> 	retn
   800                              <1> 
   801                              <1> set_time:
   802                              <1> 	; 13/05/2016
   803                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   804                              <1>         ; 2004-2005
   805                              <1> 
   806 00004ED0 BE[38C30000]        <1> 	mov 	esi, Msg_Enter_Time
   807 00004ED5 E8DAF0FFFF          <1> 	call	print_msg
   808                              <1> 
   809                              <1> loc_enter_hour_1:
   810 00004EDA 30E4                <1> 	xor     ah, ah
   811 00004EDC E8BBBBFFFF          <1> 	call	int16h
   812                              <1> 	; AL = ASCII Code of the Character
   813 00004EE1 3C0D                <1> 	cmp	al, 13 ; ENTER key
   814 00004EE3 0F84AE010000        <1>         je      loc_set_time_retn
   815 00004EE9 3C1B                <1> 	cmp	al, 27 ; ESC key
   816 00004EEB 0F84A6010000        <1>         je      loc_set_time_retn
   817 00004EF1 A2[59C30000]        <1> 	mov	[Hour], al
   818 00004EF6 3C30                <1> 	cmp	al, '0'
   819 00004EF8 0F82A4010000        <1>         jb      loc_set_time_stc_0
   820 00004EFE 3C32                <1> 	cmp	al, '2'
   821 00004F00 0F879C010000        <1>         ja      loc_set_time_stc_0
   822                              <1> 	; 13/05/2016
   823                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   824                              <1> 		      ; video page 0 (bh)
   825 00004F06 B307                <1> 	mov	bl, 7	
   826 00004F08 E8DBC7FFFF          <1> 	call	_write_tty
   827                              <1> loc_enter_hour_2:
   828 00004F0D 30E4                <1> 	xor     ah, ah
   829 00004F0F E888BBFFFF          <1> 	call	int16h
   830                              <1> 	; AL = ASCII Code of the Character
   831 00004F14 3C1B                <1> 	cmp	al, 27
   832 00004F16 0F847B010000        <1>         je      loc_set_time_retn
   833 00004F1C A2[5AC30000]        <1> 	mov	[Hour+1], al
   834 00004F21 3C30                <1> 	cmp	al, '0'
   835 00004F23 0F8283010000        <1>         jb      loc_set_time_stc_1
   836 00004F29 3C39                <1> 	cmp	al, '9'
   837 00004F2B 0F877B010000        <1> 	ja	loc_set_time_stc_1
   838 00004F31 803D[59C30000]32    <1>         cmp     byte [Hour], '2'
   839 00004F38 7208                <1> 	jb	short pass_set_time_24
   840 00004F3A 3C34                <1> 	cmp	al, '4'
   841 00004F3C 0F876A010000        <1>         ja      loc_set_time_stc_1
   842                              <1> pass_set_time_24:
   843                              <1> 	; 13/05/2016
   844                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   845                              <1> 		      ; video page 0 (bh)
   846 00004F42 B307                <1> 	mov	bl, 7	
   847 00004F44 E89FC7FFFF          <1> 	call	_write_tty
   848                              <1> loc_enter_time_separator_1:
   849 00004F49 28E4                <1> 	sub    ah, ah ; 0
   850 00004F4B E84CBBFFFF          <1> 	call	int16h
   851                              <1> 	; AL = ASCII Code of the Character
   852 00004F50 3C1B                <1> 	cmp	al, 27
   853 00004F52 0F843F010000        <1>         je      loc_set_time_retn
   854 00004F58 3C3A                <1> 	cmp	al, ':'
   855 00004F5A 0F8567010000        <1>         jne     loc_set_time_stc_2
   856                              <1> 	; 13/05/2016
   857                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   858                              <1> 		      ; video page 0 (bh)
   859 00004F60 B307                <1> 	mov	bl, 7	
   860 00004F62 E881C7FFFF          <1> 	call	_write_tty
   861                              <1> loc_enter_minute_1:
   862 00004F67 30E4                <1> 	xor     ah, ah
   863 00004F69 E82EBBFFFF          <1> 	call	int16h
   864                              <1> 	; AL = ASCII Code of the Character
   865 00004F6E 3C1B                <1> 	cmp	al, 27
   866 00004F70 0F8421010000        <1>         je      loc_set_time_retn
   867 00004F76 A2[5CC30000]        <1> 	mov	[Minute], al
   868 00004F7B 3C30                <1> 	cmp	al, '0'
   869 00004F7D 0F825F010000        <1>         jb      loc_set_time_stc_3
   870 00004F83 3C35                <1> 	cmp	al, '5'
   871 00004F85 0F8757010000        <1>         ja      loc_set_time_stc_3
   872                              <1> 	; 13/05/2016
   873                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   874                              <1> 		      ; video page 0 (bh)
   875 00004F8B B307                <1> 	mov	bl, 7	
   876 00004F8D E856C7FFFF          <1> 	call	_write_tty
   877                              <1> loc_enter_minute_2:
   878 00004F92 30E4                <1> 	xor     ah, ah
   879 00004F94 E803BBFFFF          <1> 	call	int16h
   880                              <1> 	; AL = ASCII Code of the Character
   881 00004F99 3C1B                <1> 	cmp	al, 27
   882 00004F9B 0F84F6000000        <1>         je      loc_set_time_retn
   883 00004FA1 A2[5DC30000]        <1> 	mov	[Minute+1], al
   884 00004FA6 3C30                <1> 	cmp	al, '0'
   885 00004FA8 0F824F010000        <1>         jb      loc_set_time_stc_4
   886 00004FAE 3C39                <1> 	cmp	al, '9'
   887 00004FB0 0F8747010000        <1>         ja      loc_set_time_stc_4
   888                              <1> 	; 13/05/2016
   889                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   890                              <1> 		      ; video page 0 (bh)
   891 00004FB6 B307                <1> 	mov	bl, 7	
   892 00004FB8 E82BC7FFFF          <1> 	call	_write_tty
   893                              <1> loc_enter_time_separator_2:
   894 00004FBD 66C705[5FC30000]30- <1> 	mov	word [Second], 3030h
   894 00004FC5 30                  <1>
   895 00004FC6 28E4                <1> 	sub     ah, ah
   896 00004FC8 E8CFBAFFFF          <1> 	call	int16h
   897                              <1> 	; AL = ASCII Code of the Character
   898 00004FCD 3C0D                <1> 	cmp	al, 13
   899 00004FCF 0F8485000000        <1>         je      loc_set_time_progress
   900 00004FD5 3C1B                <1> 	cmp	al, 27
   901 00004FD7 0F84BA000000        <1>         je      loc_set_time_retn
   902 00004FDD 3C3A                <1> 	cmp	al, ':'
   903 00004FDF 0F8533010000        <1>         jne     loc_set_time_stc_5
   904                              <1> 	; 13/05/2016
   905                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   906                              <1> 		      ; video page 0 (bh)
   907 00004FE5 B307                <1> 	mov	bl, 7	
   908 00004FE7 E8FCC6FFFF          <1> 	call	_write_tty
   909                              <1> loc_enter_second_1:
   910 00004FEC 30E4                <1> 	xor     ah, ah
   911 00004FEE E8A9BAFFFF          <1> 	call	int16h
   912                              <1> 	; AL = ASCII Code of the Character
   913 00004FF3 3C0D                <1> 	cmp	al, 13
   914 00004FF5 7463                <1> 	je	short loc_set_time_progress
   915 00004FF7 3C1B                <1> 	cmp	al, 27
   916 00004FF9 0F8498000000        <1>         je      loc_set_time_retn
   917 00004FFF A2[5FC30000]        <1> 	mov	[Second], al
   918 00005004 3C30                <1> 	cmp	al, '0'
   919 00005006 0F8227010000        <1>         jb      loc_set_time_stc_6
   920 0000500C 3C35                <1> 	cmp	al, '5'
   921 0000500E 0F871F010000        <1>         ja      loc_set_time_stc_6
   922                              <1> 	; 13/05/2016
   923                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   924                              <1> 		      ; video page 0 (bh)
   925 00005014 B307                <1> 	mov	bl, 7	
   926 00005016 E8CDC6FFFF          <1> 	call	_write_tty
   927                              <1> loc_enter_second_2:
   928 0000501B 30E4                <1> 	xor     ah, ah
   929 0000501D E87ABAFFFF          <1> 	call	int16h
   930                              <1> 	; AL = ASCII Code of the Character
   931 00005022 3C1B                <1> 	cmp	al, 27
   932 00005024 7471                <1> 	je	short loc_set_time_retn
   933 00005026 3C30                <1> 	cmp	al, '0'
   934 00005028 0F8229010000        <1>         jb      loc_set_time_stc_7
   935 0000502E 3C39                <1> 	cmp	al, '9'
   936 00005030 0F8721010000        <1>         ja      loc_set_time_stc_7
   937                              <1> 	; 13/05/2016
   938                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   939                              <1> 		      ; video page 0 (bh)
   940 00005036 B307                <1> 	mov	bl, 7	
   941 00005038 E8ABC6FFFF          <1> 	call	_write_tty
   942                              <1> loc_set_time_get_lchar_again:
   943 0000503D 28E4                <1> 	sub	ah, ah ; 0
   944 0000503F E858BAFFFF          <1> 	call	int16h
   945                              <1> 	; AL = ASCII Code of the Character
   946 00005044 3C0D                <1> 	cmp	al, 13
   947 00005046 7412                <1> 	je	short loc_set_time_progress
   948 00005048 3C1B                <1> 	cmp	al, 27
   949 0000504A 744B                <1> 	je	short loc_set_time_retn
   950                              <1> 	;
   951 0000504C E831FEFFFF          <1> 	call	check_for_backspace
   952 00005051 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   953                              <1> 
   954                              <1> loc_set_time_bs_8:
   955 00005053 E818FEFFFF          <1> 	call	write_backspace
   956 00005058 EBC1                <1> 	jmp	short loc_enter_second_2
   957                              <1> 
   958                              <1> loc_set_time_progress:
   959                              <1> 	; Get Current Time
   960                              <1> 	;mov 	ah, 02h
   961                              <1> 	;call	int1Ah
   962 0000505A E80EECFFFF          <1> 	call	RTC_20	; GET RTC TIME
   963                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   964                              <1> 
   965 0000505F 66A1[59C30000]      <1> 	mov	ax, [Hour]
   966 00005065 662D3030            <1> 	sub	ax, '00'
   967 00005069 C0E004              <1> 	shl	al, 4 ; * 16
   968 0000506C 88C5                <1> 	mov	ch, al
   969 0000506E 00E5                <1> 	add	ch, ah
   970 00005070 66A1[5CC30000]      <1> 	mov	ax, [Minute]
   971 00005076 662D3030            <1> 	sub	ax, '00'
   972 0000507A C0E004              <1> 	shl	al, 4 ; * 16
   973 0000507D 88C1                <1> 	mov	cl, al
   974 0000507F 00E1                <1> 	add	cl, ah
   975 00005081 66A1[5FC30000]      <1> 	mov	ax, [Second]
   976 00005087 662D3030            <1> 	sub	ax, '00'
   977 0000508B C0E004              <1> 	shl	al, 4 ; * 16
   978 0000508E 88C6                <1> 	mov	dh, al
   979 00005090 00E6                <1> 	add	dh, ah
   980                              <1> 	
   981                              <1> 	;mov	ah, 03h
   982                              <1> 	;call	int1Ah
   983 00005092 E805ECFFFF          <1> 	call	RTC_30	; SET RTC TIME
   984                              <1> 
   985                              <1> loc_set_time_retn:
   986 00005097 BE[20CF0000]        <1> 	mov 	esi, nextline
   987 0000509C E813EFFFFF          <1> 	call	print_msg
   988 000050A1 C3                  <1> 	retn
   989                              <1> 
   990                              <1> loc_set_time_stc_0:
   991                              <1> 	;xor	bh, bh ; video page 0
   992 000050A2 E816C7FFFF          <1> 	call	beeper ; BEEP !
   993 000050A7 E92EFEFFFF          <1>         jmp     loc_enter_hour_1
   994                              <1> loc_set_time_stc_1:
   995 000050AC E8D1FDFFFF          <1> 	call	check_for_backspace
   996 000050B1 740A                <1> 	je	short loc_set_time_bs_1
   997                              <1> 	;xor	bh, bh ; video page 0
   998 000050B3 E805C7FFFF          <1> 	call	beeper ; BEEP !
   999 000050B8 E950FEFFFF          <1>         jmp     loc_enter_hour_2
  1000                              <1> loc_set_time_bs_1:
  1001 000050BD E8AEFDFFFF          <1> 	call	write_backspace
  1002 000050C2 E913FEFFFF          <1>         jmp     loc_enter_hour_1
  1003                              <1> loc_set_time_stc_2:
  1004 000050C7 E8B6FDFFFF          <1> 	call	check_for_backspace
  1005 000050CC 740A                <1> 	je	short loc_set_time_bs_2
  1006                              <1> 	;xor	bh, bh ; video page 0
  1007 000050CE E8EAC6FFFF          <1> 	call	beeper ; BEEP !
  1008 000050D3 E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
  1009                              <1> loc_set_time_bs_2:
  1010 000050D8 E893FDFFFF          <1> 	call	write_backspace
  1011 000050DD E92BFEFFFF          <1>         jmp     loc_enter_hour_2
  1012                              <1> loc_set_time_stc_3:
  1013 000050E2 E89BFDFFFF          <1> 	call	check_for_backspace
  1014 000050E7 740A                <1> 	je	short loc_set_time_bs_3
  1015                              <1> 	;xor	bh, bh ; video page 0
  1016 000050E9 E8CFC6FFFF          <1> 	call	beeper ; BEEP !6
  1017 000050EE E974FEFFFF          <1>         jmp     loc_enter_minute_1
  1018                              <1> loc_set_time_bs_3:
  1019 000050F3 E878FDFFFF          <1> 	call	write_backspace
  1020 000050F8 E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
  1021                              <1> loc_set_time_stc_4:
  1022 000050FD E880FDFFFF          <1> 	call	check_for_backspace
  1023 00005102 740A                <1> 	je	short loc_set_time_bs_4
  1024                              <1> 	;xor	bh, bh ; video page 0
  1025 00005104 E8B4C6FFFF          <1> 	call	beeper ; BEEP !
  1026 00005109 E984FEFFFF          <1>         jmp     loc_enter_minute_2
  1027                              <1> loc_set_time_bs_4:
  1028 0000510E E85DFDFFFF          <1> 	call	write_backspace
  1029 00005113 E94FFEFFFF          <1>         jmp     loc_enter_minute_1
  1030                              <1> loc_set_time_stc_5:
  1031 00005118 E865FDFFFF          <1> 	call	check_for_backspace
  1032 0000511D 740A                <1> 	je	short loc_set_time_bs_5
  1033                              <1> 	;xor	bh, bh ; video page 0
  1034 0000511F E899C6FFFF          <1> 	call	beeper ; BEEP !
  1035 00005124 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1036                              <1> loc_set_time_bs_5:
  1037 00005129 E842FDFFFF          <1> 	call	write_backspace
  1038 0000512E E95FFEFFFF          <1>         jmp     loc_enter_minute_2
  1039                              <1> loc_set_time_stc_6:
  1040 00005133 E84AFDFFFF          <1> 	call	check_for_backspace
  1041 00005138 7413                <1> 	je	short loc_set_time_bs_6
  1042                              <1> 	;xor	bh, bh ; video page 0
  1043 0000513A E87EC6FFFF          <1> 	call	beeper ; BEEP !
  1044 0000513F 66C705[5FC30000]30- <1> 	mov	word [Second], 3030h
  1044 00005147 30                  <1>
  1045 00005148 E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1046                              <1> loc_set_time_bs_6:
  1047 0000514D E81EFDFFFF          <1> 	call	write_backspace
  1048 00005152 E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1049                              <1> loc_set_time_stc_7:
  1050 00005157 E826FDFFFF          <1> 	call	check_for_backspace
  1051 0000515C 740A                <1> 	je	short loc_set_time_bs_7
  1052                              <1> 	;xor	bh, bh ; video page 0
  1053 0000515E E85AC6FFFF          <1> 	call	beeper ; BEEP !
  1054 00005163 E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1055                              <1> loc_set_time_bs_7:
  1056 00005168 E803FDFFFF          <1> 	call	write_backspace
  1057 0000516D E97AFEFFFF          <1>         jmp     loc_enter_second_1
  1058                              <1> 
  1059                              <1> print_volume_info:
  1060                              <1> 	; 01/03/2016
  1061                              <1> 	; 08/02/2016
  1062                              <1> 	; 06/02/2016
  1063                              <1> 	; 04/02/2016
  1064                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
  1065                              <1> 	; 25/10/2009
  1066                              <1> 	;
  1067                              <1> 	; "Volume Serial No: "
  1068                              <1>  	;
  1069                              <1> 	; INPUT  : AL = DOS Drive Number
  1070                              <1> 	; OUTPUT : AH = FS Type
  1071                              <1> 	;          AL = DOS Drive Name
  1072                              <1> 	; CF = 0 -> OK
  1073                              <1> 	; CF = 1 -> Drive not ready 
  1074                              <1> 
  1075 00005172 88C4                <1> 	mov	ah, al
  1076 00005174 28C0                <1> 	sub	al, al
  1077 00005176 0FB7F0              <1> 	movzx	esi, ax	
  1078 00005179 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1079 0000517F 8A06                <1> 	mov	al, [esi]
  1080 00005181 3C41                <1> 	cmp	al, 'A'  
  1081 00005183 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1082 00005185 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1083 00005188 C3                  <1> 	retn
  1084                              <1> 
  1085                              <1> loc_pvi_set_vol_name:
  1086 00005189 A2[93C30000]        <1> 	mov	[Vol_Drv_Name], al
  1087 0000518E 56                  <1> 	push	esi
  1088 0000518F E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1089 00005194 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1090 00005196 5E                  <1> 	pop	esi
  1091 00005197 C3                  <1> 	retn
  1092                              <1> 
  1093                              <1> loc_pvi_mvn_ok:
  1094 00005198 8B3424              <1> 	mov	esi, [esp]
  1095 0000519B 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1096 0000519F 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1097 000051A1 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1098 000051A4 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1099 000051A8 EB07                <1> 	jmp	short loc_vol_size_mul32
  1100                              <1> loc_pvi_fat_vol_size:
  1101 000051AA 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1102 000051AD 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1103                              <1> loc_vol_size_mul32:
  1104 000051B1 F7E3                <1> 	mul	ebx
  1105 000051B3 09D2                <1> 	or	edx, edx
  1106 000051B5 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1107                              <1> loc_vol_size_in_bytes:
  1108 000051B7 B9[71C30000]        <1> 	mov	ecx, VolSize_Bytes
  1109 000051BC EB0D                <1> 	jmp	short loc_write_vol_size_str
  1110                              <1> loc_vol_size_in_kbytes:
  1111 000051BE 66BB0004            <1> 	mov	bx, 1024
  1112 000051C2 F7F3                <1> 	div	ebx
  1113 000051C4 B9[64C30000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1114 000051C9 31D2                <1> 	xor	edx, edx ; 0
  1115                              <1> loc_write_vol_size_str:
  1116 000051CB 890D[87DB0000]      <1> 	mov	[VolSize_Unit1], ecx
  1117                              <1> 	; 
  1118 000051D1 BF[9DDB0000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1119                              <1>         ;mov	byte [edi], 0
  1120 000051D6 B90A000000          <1> 	mov	ecx, 10
  1121                              <1> loc_write_vol_size_chr:
  1122 000051DB F7F1                <1> 	div	ecx
  1123 000051DD 80C230              <1> 	add	dl, '0'
  1124 000051E0 4F                  <1> 	dec	edi	
  1125 000051E1 8817                <1> 	mov	[edi], dl
  1126 000051E3 85C0                <1> 	test	eax, eax
  1127 000051E5 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1128 000051E7 28D2                <1> 	sub	dl, dl ; 0
  1129 000051E9 EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1130                              <1> 
  1131                              <1> loc_write_vol_size_str_ok:
  1132 000051EB 893D[8FDB0000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1133                              <1> 	;
  1134 000051F1 BF[7CC30000]        <1> 	mov	edi, Vol_FS_Name
  1135 000051F6 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1136 000051F9 20C9                <1> 	and	cl, cl ; 0 ?
  1137 000051FB 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1138 000051FD 66C7075452          <1> 	mov	word [edi], 'TR'
  1139 00005202 C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1140                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1141 00005209 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1142 0000520D 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1143 00005210 EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1144                              <1> 
  1145                              <1> loc_write_vol_FAT_str_1:
  1146 00005212 66B83332            <1> 	mov	ax, '32' ; FAT32
  1147 00005216 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1148 00005219 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1149 0000521B 66B83132            <1> 	mov	ax, '12' ; FAT12
  1150 0000521F 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1151 00005221 B436                <1> 	mov	ah, '6'  ; FAT16
  1152                              <1> loc_write_vol_FAT_str_2:
  1153 00005223 C70746415420        <1> 	mov	dword [edi], 'FAT '
  1154 00005229 66894704            <1> 	mov	word [edi+4], ax
  1155                              <1> 	;
  1156                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1157 0000522D 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1158 00005231 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1159                              <1> 
  1160                              <1> loc_vol_freespace_recalc0:
  1161                              <1> 	; 01/03/2016
  1162 00005234 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1163 00005237 720F                <1> 	jb	short loc_vol_freespace_mul32
  1164                              <1> 	;inc	eax ; 0
  1165 00005239 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1166 0000523B 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1167 0000523D 53                  <1> 	push	ebx
  1168 0000523E 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1169 00005242 E88B490000          <1> 	call	calculate_fat_freespace
  1170 00005247 5B                  <1> 	pop	ebx
  1171                              <1> 
  1172                              <1> loc_vol_freespace_mul32:
  1173 00005248 F7E3                <1> 	mul	ebx
  1174 0000524A 09D2                <1> 	or	edx, edx
  1175 0000524C 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1176                              <1> loc_vol_fspace_in_bytes:
  1177 0000524E B9[71C30000]        <1> 	mov	ecx, VolSize_Bytes
  1178 00005253 EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1179                              <1> loc_vol_fspace_in_kbytes:
  1180 00005255 66BB0004            <1> 	mov	bx, 1024
  1181 00005259 F7F3                <1> 	div	ebx
  1182 0000525B B9[64C30000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1183 00005260 31D2                <1> 	xor	edx, edx ; 0
  1184                              <1> loc_write_vol_fspace_str:
  1185 00005262 890D[8BDB0000]      <1> 	mov	[VolSize_Unit2], ecx
  1186                              <1> 	;	
  1187 00005268 BF[ADDB0000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1188                              <1>         ;mov	byte [edi], 0
  1189 0000526D B90A000000          <1> 	mov	ecx, 10
  1190                              <1> loc_write_vol_fspace_chr:
  1191 00005272 F7F1                <1> 	div	ecx
  1192 00005274 80C230              <1> 	add	dl, '0'
  1193 00005277 4F                  <1> 	dec	edi	
  1194 00005278 8817                <1> 	mov	[edi], dl
  1195 0000527A 85C0                <1> 	test	eax, eax
  1196 0000527C 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1197 0000527E 28D2                <1> 	sub	dl, dl ; 0
  1198 00005280 EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1199                              <1> 
  1200                              <1> loc_write_vol_fspace_str_ok:
  1201 00005282 893D[9FDB0000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1202                              <1> 	;
  1203 00005288 BE[7AC30000]        <1> 	mov	esi, Volume_in_drive
  1204 0000528D E822EDFFFF          <1> 	call	print_msg
  1205 00005292 BE[BAC30000]        <1> 	mov	esi, Vol_Name
  1206 00005297 E818EDFFFF          <1> 	call	print_msg
  1207 0000529C BE[20CF0000]        <1> 	mov	esi, nextline
  1208 000052A1 E80EEDFFFF          <1> 	call	print_msg
  1209                              <1> 	;
  1210 000052A6 BE[1BC40000]        <1> 	mov	esi, Vol_Total_Sector_Header
  1211 000052AB E804EDFFFF          <1> 	call	print_msg
  1212 000052B0 8B35[8FDB0000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1213 000052B6 E8F9ECFFFF          <1> 	call	print_msg
  1214 000052BB 8B35[87DB0000]      <1> 	mov	esi, [VolSize_Unit1]
  1215 000052C1 E8EEECFFFF          <1> 	call	print_msg
  1216                              <1> 	;
  1217 000052C6 BE[2CC40000]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1218 000052CB E8E4ECFFFF          <1> 	call	print_msg
  1219 000052D0 8B35[9FDB0000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1220 000052D6 E8D9ECFFFF          <1> 	call	print_msg
  1221 000052DB 8B35[8BDB0000]      <1> 	mov	esi, [VolSize_Unit2]
  1222 000052E1 E8CEECFFFF          <1> 	call	print_msg
  1223                              <1> 	;
  1224 000052E6 5E                  <1> 	pop	esi
  1225                              <1> 	
  1226                              <1> 	;mov	ah, [esi+LD_FSType]
  1227                              <1> 	;mov	al, [esi+LD_FATType]
  1228 000052E7 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1229                              <1> 
  1230 000052EB C3                  <1> 	retn
  1231                              <1> 
  1232                              <1> move_volume_name_and_serial_no:
  1233                              <1> 	; 08/02/2016  (TRDOS 386 = TRDOS v2.0)
  1234                              <1> 	; this routine will be called by
  1235                              <1> 	; "print_volume_info" and "print_directory"
  1236                              <1> 	; INPUT ->
  1237                              <1> 	;	ESI = Logical DOS drv descripton table address
  1238                              <1> 	; OUTPUT ->
  1239                              <1> 	;	*Volume name will be moved to text area
  1240                              <1> 	;	*Volume serial number will be converted to
  1241                              <1> 	;	 text and will be moved to text area
  1242                              <1> 	;   cf = 1 -> invalid/unknown dos drive
  1243                              <1> 	;   cf = 0 -> ecx = 0
  1244                              <1> 	;
  1245                              <1> 	; (eax, edx, ecx, esi, edi will be changed)
  1246                              <1> 
  1247 000052EC BF[BAC30000]        <1> 	mov 	edi, Vol_Name
  1248                              <1> 
  1249                              <1> 	;mov	ah, [esi+LD_FSType]
  1250                              <1> 	;mov	al, [esi+LD_FATType]
  1251 000052F1 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1252 000052F5 80FCA1              <1> 	cmp	ah, 0A1h
  1253 000052F8 7418                <1> 	je	short mvn_2
  1254 000052FA 08E4                <1> 	or	ah, ah
  1255 000052FC 7404                <1> 	jz	short mvn_0
  1256 000052FE 08C0                <1> 	or	al, al
  1257 00005300 7504                <1> 	jnz	short mvn_1
  1258                              <1> mvn_0:
  1259 00005302 8A06                <1> 	mov	al, [esi]
  1260 00005304 F9                  <1> 	stc
  1261 00005305 C3                  <1> 	retn
  1262                              <1> mvn_1:
  1263 00005306 3C02                <1> 	cmp	al, 2
  1264 00005308 7717                <1> 	ja	short mvn_3 
  1265                              <1> 	;or	al, al
  1266                              <1> 	;jz	short mvn_2
  1267 0000530A 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1268 0000530D 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1269 00005310 EB15                <1> 	jmp	short mvn_4
  1270                              <1> mvn_2:
  1271 00005312 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1272 00005315 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1273 00005318 B910000000          <1> 	mov	ecx, 16
  1274 0000531D F3A5                <1> 	rep	movsd
  1275 0000531F EB10                <1> 	jmp	short mvn_5
  1276                              <1> mvn_3:
  1277 00005321 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1278 00005324 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1279                              <1> mvn_4:
  1280 00005327 B90B000000          <1> 	mov	ecx, 11
  1281 0000532C F3A4                <1> 	rep	movsb
  1282 0000532E C60700              <1> 	mov	byte [edi], 0
  1283                              <1> mvn_5:
  1284                              <1> 	;mov	[Current_VolSerial], eax  
  1285 00005331 E8D8C5FFFF          <1> 	call	dwordtohex
  1286 00005336 8915[0FC40000]      <1> 	mov	[Vol_Serial1], edx
  1287 0000533C A3[14C40000]        <1> 	mov	[Vol_Serial2], eax
  1288                              <1> 	; ecx = 0
  1289 00005341 C3                  <1> 	retn
  1290                              <1> 
  1291                              <1> get_volume_serial_number:
  1292                              <1> 	; 19/01/2016 (TRDOS 386 = TRDOS v2.0)
  1293                              <1> 	; 08/08/2010
  1294                              <1> 	;
  1295                              <1> 	; INPUT -> DL = Logical DOS Drive number
  1296                              <1> 	; OUTPUT -> EAX = Volume serial number
  1297                              <1> 	;          BL= FAT Type	    
  1298                              <1> 	;          BH = Logical DOS drv Number (DL input)
  1299                              <1> 	; cf = 1 -> Drive not ready
  1300                              <1> 
  1301 00005342 31DB                <1> 	xor	ebx, ebx
  1302 00005344 88D7                <1> 	mov	bh, dl
  1303 00005346 3815[E2C10000]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1304 0000534C 7304                <1> 	jnb	short loc_gvsn_start
  1305                              <1> loc_gvsn_stc_retn:
  1306 0000534E 31C0                <1> 	xor	eax, eax
  1307 00005350 F9                  <1> 	stc 
  1308 00005351 C3                  <1>         retn 
  1309                              <1> loc_gvsn_start:
  1310 00005352 56                  <1> 	push	esi
  1311 00005353 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1312 00005358 01DE                <1> 	add	esi, ebx
  1313 0000535A 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1314 0000535D 20DB                <1> 	and	bl, bl
  1315 0000535F 740F                <1> 	jz	short loc_gvsn_fs
  1316 00005361 80FB02              <1> 	cmp	bl, 2
  1317 00005364 7705                <1> 	ja	short loc_gvsn_fat32
  1318                              <1> loc_gvsn_fat:
  1319 00005366 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1320 00005369 EB0E                <1> 	jmp	short loc_gvsn_return
  1321                              <1> loc_gvsn_fat32: 
  1322 0000536B 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1323 0000536E EB09                <1> 	jmp	short loc_gvsn_return 
  1324                              <1> loc_gvsn_fs:
  1325 00005370 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1326 00005374 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1327 00005376 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1328                              <1> loc_gvsn_return:
  1329 00005379 8B06                <1> 	mov	eax, [esi]
  1330 0000537B 5E                  <1> 	pop	esi
  1331 0000537C C3                  <1> 	retn
  1332                              <1> 
  1333                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ]
  1334                              <1> ; 09/11/2011
  1335                              <1> ; 29/01/2005
  1336                              <1> 
  1337                              <1> command_interpreter:
  1338                              <1> 	; 13/05/2016
  1339                              <1> 	; 07/05/2016
  1340                              <1> 	; 04/03/2016
  1341                              <1> 	; 04/02/2016
  1342                              <1> 	; 03/02/2016
  1343                              <1> 	; 30/01/2016
  1344                              <1> 	; 29/01/2016 (TRDOS 386 = TRDOS 2.0)
  1345                              <1> 	; 15/09/2011         
  1346                              <1> 	; 29/01/2005
  1347                              <1>         
  1348                              <1> 	; Input: ecx = command word length (CL)
  1349                              <1> 	;	 CommandBuffer = Command string offset
  1350                              <1>  
  1351 0000537D C605[40DC0000]00    <1> 	mov	byte [Program_Exit],0
  1352 00005384 80F904              <1> 	cmp	cl, 4
  1353 00005387 0F87AE020000        <1>         ja      c_6
  1354 0000538D 0F822E010000        <1>         jb      c_2
  1355                              <1> c_4:
  1356                              <1> 
  1357                              <1> cmp_cmd_exit:
  1358 00005393 BF[50C20000]        <1> 	mov	edi, Cmd_Exit
  1359 00005398 E8C9030000          <1> 	call	cmp_cmd	
  1360 0000539D 7208                <1> 	jc	short cmp_cmd_date
  1361                              <1> 
  1362 0000539F C605[40DC0000]01    <1>         mov     byte [Program_Exit], 1
  1363 000053A6 C3                  <1>         retn
  1364                              <1> 
  1365                              <1> cmp_cmd_date:
  1366 000053A7 B104                <1> 	mov	cl, 4
  1367 000053A9 BF[6CC20000]        <1> 	mov	edi, Cmd_Date
  1368 000053AE E8B3030000          <1> 	call	cmp_cmd	
  1369 000053B3 720B                <1>         jc	short cmp_cmd_time
  1370                              <1> 	
  1371 000053B5 E8D0F7FFFF          <1> 	call	show_date
  1372 000053BA E80FF8FFFF          <1> 	call	set_date
  1373 000053BF C3                  <1> 	retn
  1374                              <1> 
  1375                              <1> cmp_cmd_time:
  1376 000053C0 B104                <1> 	mov	cl, 4
  1377 000053C2 BF[71C20000]        <1> 	mov	edi, Cmd_Time
  1378 000053C7 E89A030000          <1>    	call	cmp_cmd	
  1379 000053CC 720B                <1> 	jc	short cmp_cmd_show
  1380                              <1> 
  1381 000053CE E8C6FAFFFF          <1> 	call	show_time
  1382 000053D3 E8F8FAFFFF          <1> 	call	set_time
  1383 000053D8 C3                  <1> 	retn
  1384                              <1> 
  1385                              <1> cmp_cmd_show:
  1386 000053D9 B104                <1> 	mov	cl, 4
  1387 000053DB BF[82C20000]        <1> 	mov	edi, Cmd_Show
  1388 000053E0 E881030000          <1>    	call	cmp_cmd	
  1389 000053E5 0F83F6090000        <1>         jnc     show_file
  1390                              <1> 
  1391                              <1> cmp_cmd_echo:
  1392 000053EB B104                <1> 	mov	cl, 4
  1393 000053ED BF[C7C20000]        <1> 	mov	edi, Cmd_Echo
  1394 000053F2 E86F030000          <1>    	call	cmp_cmd	
  1395 000053F7 721B                <1> 	jc	short cmp_cmd_copy
  1396                              <1> 
  1397                              <1> 	; 14/04/2016
  1398 000053F9 56                  <1> 	push	esi
  1399                              <1> cmd_echo_asciiz:
  1400 000053FA 46                  <1>         inc	esi
  1401 000053FB 8A06                <1> 	mov	al, [esi]
  1402 000053FD 3C20                <1> 	cmp	al, 20h
  1403 000053FF 73F9                <1> 	jnb	short cmd_echo_asciiz
  1404 00005401 C60600              <1> 	mov	byte [esi], 0                 
  1405 00005404 5E                  <1> 	pop	esi  
  1406 00005405 E8AAEBFFFF          <1> 	call	print_msg
  1407 0000540A BE[91CF0000]        <1> 	mov	esi, NextLine
  1408                              <1> 	;call	print_msg   
  1409                              <1> 	;retn
  1410 0000540F E9A0EBFFFF          <1> 	jmp	print_msg
  1411                              <1> 
  1412                              <1> cmp_cmd_copy:
  1413 00005414 B104                <1> 	mov	cl, 4
  1414 00005416 BF[A5C20000]        <1> 	mov	edi, Cmd_Copy
  1415 0000541B E846030000          <1>    	call	cmp_cmd	
  1416 00005420 0F8301180000        <1> 	jnc	copy_file
  1417                              <1> 
  1418                              <1> cmp_cmd_move:
  1419 00005426 B104                <1> 	mov	cl, 4
  1420 00005428 BF[AAC20000]        <1> 	mov	edi, Cmd_Move
  1421 0000542D E834030000          <1>    	call	cmp_cmd	
  1422 00005432 0F8395160000        <1> 	jnc	move_file
  1423                              <1> 
  1424                              <1> cmp_cmd_path:
  1425 00005438 B104                <1> 	mov	cl, 4
  1426 0000543A BF[AFC20000]        <1> 	mov	edi, Cmd_Path
  1427 0000543F E822030000          <1>    	call	cmp_cmd	
  1428 00005444 0F83351A0000        <1> 	jnc	set_get_path
  1429                              <1> 
  1430                              <1> cmp_cmd_beep:
  1431 0000544A B104                <1> 	mov	cl, 4
  1432 0000544C BF[E5C20000]        <1> 	mov	edi, Cmd_Beep
  1433 00005451 E810030000          <1>    	call	cmp_cmd	
  1434 00005456 720B                <1> 	jc	short cmp_cmd_find
  1435                              <1> 	; 13/05/2016
  1436 00005458 8A3D[B8D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  1437 0000545E E95AC3FFFF          <1> 	jmp	beeper
  1438                              <1> 
  1439                              <1> cmp_cmd_find:
  1440 00005463 B104                <1> 	mov	cl, 4
  1441 00005465 BF[B9C20000]        <1> 	mov	edi, Cmd_Find
  1442 0000546A E8F7020000          <1>    	call	cmp_cmd	
  1443 0000546F 0F82D4020000        <1>         jc      cmp_cmd_external
  1444                              <1> 
  1445                              <1> 	;call	find_and_list_files
  1446 00005475 E9EC220000          <1> 	jmp	find_and_list_files
  1447                              <1> 	;retn
  1448                              <1> 
  1449                              <1> c_1:
  1450 0000547A AD                  <1> 	lodsd
  1451                              <1> cmp_cmd_help:
  1452 0000547B 3C3F                <1> 	cmp	al, '?'
  1453 0000547D 751D                <1>         jne     short cmp_cmd_remark
  1454                              <1> 
  1455 0000547F BE[42C20000]        <1> 	mov	esi, Command_List
  1456                              <1> cmd_help_next_w:
  1457 00005484 E82BEBFFFF          <1> 	call	print_msg
  1458                              <1> 
  1459 00005489 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1460 0000548C 7232                <1> 	jb	short cmd_help_retn
  1461                              <1> 	
  1462 0000548E 56                  <1> 	push	esi
  1463 0000548F BE[20CF0000]        <1> 	mov	esi, nextline
  1464 00005494 E81BEBFFFF          <1> 	call	print_msg
  1465 00005499 5E                  <1> 	pop	esi
  1466 0000549A EBE8                <1> 	jmp	short cmd_help_next_w	
  1467                              <1> 
  1468                              <1> cmp_cmd_remark:
  1469 0000549C 3C2A                <1> 	cmp	al, '*'
  1470 0000549E 0F85A5020000        <1>         jne     cmp_cmd_external
  1471 000054A4 46                  <1> 	inc	esi
  1472 000054A5 BF[B0D30000]        <1> 	mov	edi, Remark
  1473 000054AA 8A06                <1> 	mov	al, [esi]
  1474 000054AC 3C20                <1> 	cmp	al, 20h
  1475 000054AE 7707                <1> 	ja	short cmd_remark_write
  1476 000054B0 89FE                <1> 	mov	esi, edi ; Remark
  1477 000054B2 E9FDEAFFFF          <1> 	jmp	print_msg
  1478                              <1> 
  1479                              <1> cmd_remark_write:
  1480 000054B7 AA                  <1> 	stosb
  1481 000054B8 AC                  <1> 	lodsb
  1482 000054B9 3C20                <1> 	cmp	al, 20h
  1483 000054BB 73FA                <1> 	jnb	short cmd_remark_write
  1484 000054BD C60700              <1> 	mov	byte [edi], 0
  1485                              <1> 
  1486                              <1> cmd_help_retn:
  1487                              <1> cmd_remark_retn:
  1488                              <1> cd_retn:
  1489 000054C0 C3                  <1> 	retn
  1490                              <1> 
  1491                              <1> c_2:
  1492 000054C1 80F902              <1> 	cmp	cl, 2
  1493 000054C4 0F87B1000000        <1>         ja      c_3
  1494 000054CA BE[FED30000]        <1> 	mov	esi, CommandBuffer
  1495 000054CF 72A9                <1> 	jb	short c_1
  1496                              <1> 
  1497                              <1> cmp_cmd_cd:
  1498 000054D1 66AD                <1> 	lodsw
  1499 000054D3 663D4344            <1> 	cmp	ax, 'CD'
  1500 000054D7 7553                <1> 	jne	short cmp_cmd_drive
  1501 000054D9 46                  <1>         inc	esi
  1502                              <1> cd_0:
  1503 000054DA 668B06              <1> 	mov	ax, [esi]	
  1504 000054DD 3C20                <1> 	cmp	al, 20h
  1505 000054DF 76DF                <1> 	jna	short cd_retn
  1506                              <1> 	; 10/02/2016
  1507 000054E1 80FC3A              <1> 	cmp	ah, ':'
  1508 000054E4 7504                <1> 	jne	short cd_1
  1509 000054E6 46                  <1> 	inc	esi
  1510 000054E7 46                  <1> 	inc	esi
  1511 000054E8 EB4B                <1> 	jmp	short cd_2
  1512                              <1> 
  1513                              <1> cd_1:	; change current directory
  1514                              <1> 	; 29/11/2009
  1515                              <1> 	; AH = CDh	; to separate 'CD' command from others
  1516                              <1> 			; for restoring current directory
  1517                              <1> 			; 0CDh sign is for saving cdir into 
  1518                              <1> 			; DOS drv description table cdir area
  1519                              <1> 	
  1520 000054EA B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1521                              <1> 
  1522 000054EC E85A230000          <1> 	call	change_current_directory
  1523 000054F1 0F8374220000        <1>         jnc     change_prompt_dir_string
  1524                              <1> 
  1525                              <1> cd_error_messages:
  1526 000054F7 3C03                <1> 	cmp	al, 3
  1527 000054F9 740C                <1> 	je	short cd_path_not_found
  1528 000054FB 3C15                <1> 	cmp	al, 15h 
  1529 000054FD 745B                <1> 	je	short cd_drive_not_ready
  1530 000054FF 3C18                <1> 	cmp	al, 18h ; Bad request structure length 
  1531 00005501 746C                <1> 	je	short cd_command_failed
  1532 00005503 3C1A                <1> 	cmp	al, 1Ah ; Unknown media type, non-DOS disk
  1533 00005505 7468                <1>         je      short cd_command_failed
  1534                              <1> 
  1535                              <1> cd_path_not_found:
  1536 00005507 6650                <1> 	push	ax	
  1537 00005509 BE[EEC40000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1538 0000550E E8A1EAFFFF          <1> 	call	print_msg
  1539 00005513 6658                <1> 	pop	ax
  1540 00005515 3A25[4CD30000]      <1> 	cmp	ah, [Current_Dir_Level]
  1541 0000551B 0F834A220000        <1>         jnb     change_prompt_dir_string
  1542 00005521 8825[4CD30000]      <1> 	mov	[Current_Dir_Level], ah
  1543 00005527 E93F220000          <1>         jmp     change_prompt_dir_string   
  1544                              <1> 
  1545                              <1> cmp_cmd_drive: ; change current drive
  1546                              <1> 	; C:, D:, E: etc.
  1547 0000552C 80FC3A              <1> 	cmp	ah, ':'
  1548 0000552F 0F8514020000        <1>         jne     cmp_cmd_external
  1549                              <1> 
  1550                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1551 00005535 803E20              <1> 	cmp	byte [esi], 20h
  1552 00005538 0F8715020000        <1>         ja      loc_cmd_failed
  1553                              <1> 
  1554 0000553E 24DF                <1> 	and	al, 0DFh
  1555 00005540 2C41                <1> 	sub	al, 'A'
  1556 00005542 0F820B020000        <1>         jc      loc_cmd_failed
  1557                              <1> 
  1558 00005548 3A05[E2C10000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1559 0000554E 770A                <1>         ja	short cd_drive_not_ready
  1560                              <1> 	
  1561 00005550 88C2                <1> 	mov	dl, al
  1562 00005552 E862F3FFFF          <1> 	call 	change_current_drive
  1563 00005557 7201                <1> 	jc	short cd_drive_not_ready	
  1564 00005559 C3                  <1> 	retn
  1565                              <1> 
  1566                              <1> cd_drive_not_ready:
  1567 0000555A BE[ABC40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1568 0000555F E850EAFFFF          <1> 	call	print_msg
  1569                              <1> 
  1570                              <1> cd_fail_drive_restart:
  1571 00005564 8A15[4ED30000]      <1> 	mov	dl, [Current_Drv]
  1572                              <1> 	;call 	change_current_drive
  1573 0000556A E94AF3FFFF          <1>         jmp     change_current_drive
  1574                              <1> 	;retn
  1575                              <1> 
  1576                              <1> cd_command_failed:
  1577 0000556F BE[8CC40000]        <1> 	mov	esi, Msg_Bad_Command
  1578 00005574 E83BEAFFFF          <1> 	call	print_msg
  1579 00005579 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1580                              <1> 
  1581                              <1> c_3:
  1582                              <1> cmp_cmd_dir:
  1583 0000557B BF[42C20000]        <1> 	mov	edi, Cmd_Dir
  1584 00005580 E8E1010000          <1> 	call	cmp_cmd	
  1585 00005585 0F8380020000        <1> 	jnc	print_directory_list
  1586                              <1> 
  1587                              <1> cmp_cmd_cls:
  1588 0000558B B103                <1> 	mov	cl, 3
  1589 0000558D BF[7EC20000]        <1> 	mov	edi, Cmd_Cls
  1590 00005592 E8CF010000          <1> 	call	cmp_cmd	
  1591 00005597 0F832DEAFFFF        <1>         jnc	clear_screen
  1592                              <1> 
  1593                              <1> cmp_cmd_ver:
  1594 0000559D B103                <1> 	mov	cl, 3
  1595 0000559F BF[4CC20000]        <1> 	mov	edi, Cmd_Ver
  1596 000055A4 E8BD010000          <1> 	call	cmp_cmd	
  1597 000055A9 720A                <1> 	jc	short cmp_cmd_mem
  1598                              <1> 
  1599 000055AB BE[EAC10000]        <1> 	mov	esi, mainprog_Version
  1600                              <1> 	;call	print_msg
  1601 000055B0 E9FFE9FFFF          <1> 	jmp	print_msg
  1602                              <1> 	;retn
  1603                              <1> 
  1604                              <1> cmp_cmd_mem:
  1605 000055B5 B103                <1> 	mov	cl, 3
  1606 000055B7 BF[B4C20000]        <1> 	mov	edi, Cmd_Mem
  1607 000055BC E8A5010000          <1> 	call	cmp_cmd	
  1608 000055C1 0F8392C2FFFF        <1> 	jnc	memory_info
  1609                              <1> 
  1610                              <1> cmp_cmd_del:
  1611 000055C7 B103                <1> 	mov	cl, 3
  1612 000055C9 BF[87C20000]        <1> 	mov	edi, Cmd_Del
  1613 000055CE E893010000          <1> 	call	cmp_cmd	
  1614 000055D3 0F83340F0000        <1>         jnc     delete_file
  1615                              <1> 
  1616                              <1> cmp_cmd_set:
  1617 000055D9 B103                <1> 	mov	cl, 3
  1618 000055DB BF[7AC20000]        <1> 	mov	edi, Cmd_Set
  1619 000055E0 E881010000          <1> 	call	cmp_cmd	
  1620 000055E5 0F830C180000        <1>         jnc     set_get_env
  1621                              <1> 
  1622                              <1> cmp_cmd_run:
  1623 000055EB B103                <1> 	mov	cl, 3
  1624 000055ED BF[76C20000]        <1> 	mov	edi, Cmd_Run
  1625 000055F2 E86F010000          <1> 	call	cmp_cmd	
  1626                              <1> 	; 07/05/2016
  1627 000055F7 0F824C010000        <1>         jc      cmp_cmd_external
  1628 000055FD E9431E0000          <1> 	jmp	load_and_execute_file
  1629                              <1> c_5:
  1630                              <1> cmp_cmd_mkdir:
  1631 00005602 BF[9FC20000]        <1> 	mov	edi, Cmd_Mkdir
  1632 00005607 E85A010000          <1> 	call	cmp_cmd	
  1633 0000560C 0F83930A0000        <1>         jnc     make_directory
  1634                              <1> 
  1635                              <1> cmp_cmd_rmdir:
  1636 00005612 B105                <1> 	mov	cl, 5
  1637 00005614 BF[99C20000]        <1> 	mov	edi, Cmd_Rmdir
  1638 00005619 E848010000          <1> 	call	cmp_cmd	
  1639 0000561E 0F83A00B0000        <1>         jnc     delete_directory
  1640                              <1> 
  1641                              <1> cmp_cmd_chdir:
  1642 00005624 B105                <1> 	mov	cl, 5
  1643 00005626 BF[DFC20000]        <1> 	mov	edi, Cmd_Chdir
  1644 0000562B E836010000          <1> 	call	cmp_cmd	
  1645 00005630 0F8213010000        <1>         jc      cmp_cmd_external
  1646                              <1> 
  1647 00005636 E99FFEFFFF          <1> 	jmp	cd_0
  1648                              <1> 
  1649                              <1> c_6:
  1650 0000563B 80F906              <1> 	cmp	cl, 6
  1651 0000563E 0F87DF000000        <1>         ja      c_8
  1652 00005644 72BC                <1> 	jb	short c_5
  1653                              <1> cmp_cmd_prompt:
  1654 00005646 BF[55C20000]        <1> 	mov	edi, Cmd_Prompt
  1655 0000564B E816010000          <1> 	call	cmp_cmd	
  1656 00005650 722E                <1>         jc	short cmp_cmd_volume
  1657                              <1> get_prompt_name_fchar:
  1658 00005652 AC                  <1> 	lodsb
  1659 00005653 3C20                <1> 	cmp	al, 20h
  1660 00005655 74FB                <1> 	je	short get_prompt_name_fchar
  1661 00005657 7712                <1> 	ja	short loc_change_prompt_label
  1662 00005659 BE[36C20000]        <1> 	mov	esi, TRDOSPromptLabel
  1663 0000565E C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1664 00005664 66C746045300        <1>        	mov	word [esi+4], "S" 
  1665                              <1> loc_cmd_prompt_return:
  1666 0000566A C3                  <1> 	retn
  1667                              <1> loc_change_prompt_label:
  1668 0000566B 66B90B00            <1> 	mov	cx, 11
  1669 0000566F BF[36C20000]        <1> 	mov	edi, TRDOSPromptLabel
  1670                              <1> put_char_new_prompt_label:
  1671 00005674 AA                  <1> 	stosb
  1672 00005675 AC                  <1> 	lodsb
  1673 00005676 3C20                <1> 	cmp	al, 20h
  1674 00005678 7202                <1> 	jb	short pass_put_new_prompt_label
  1675 0000567A E2F8                <1> 	loop	put_char_new_prompt_label
  1676                              <1> pass_put_new_prompt_label:
  1677 0000567C C60700              <1> 	mov	byte [edi], 0
  1678 0000567F C3                  <1> 	retn
  1679                              <1> 
  1680                              <1> cmp_cmd_volume:
  1681 00005680 B106                <1> 	mov	cl, 6
  1682 00005682 BF[5CC20000]        <1> 	mov	edi, Cmd_Volume
  1683 00005687 E8DA000000          <1> 	call	cmp_cmd	
  1684 0000568C 7255                <1>         jc	short cmp_cmd_attrib
  1685                              <1> 
  1686                              <1> cmd_vol1:
  1687 0000568E AC                  <1> 	lodsb
  1688 0000568F 3C20                <1> 	cmp	al, 20h
  1689 00005691 7707                <1> 	ja	short cmd_vol2
  1690 00005693 A0[4ED30000]        <1> 	mov	al, [Current_Drv]
  1691 00005698 EB3D                <1> 	jmp	short cmd_vol4
  1692                              <1> cmd_vol2:
  1693 0000569A 3C41                <1> 	cmp	al, 'A'
  1694 0000569C 0F82B1000000        <1>         jb      loc_cmd_failed
  1695 000056A2 3C7A                <1> 	cmp	al, 'z'
  1696 000056A4 0F87A9000000        <1>         ja      loc_cmd_failed
  1697 000056AA 3C5A                <1> 	cmp	al, 'Z'
  1698 000056AC 760A                <1> 	jna	short cmd_vol3
  1699 000056AE 3C61                <1> 	cmp	al, 'a'
  1700 000056B0 0F829D000000        <1>         jb      loc_cmd_failed
  1701 000056B6 24DF                <1> 	and	al, 0DFh
  1702                              <1> cmd_vol3:
  1703 000056B8 8A26                <1> 	mov	ah, [esi]
  1704 000056BA 80FC3A              <1> 	cmp	ah, ':'
  1705 000056BD 0F8590000000        <1>         jne     loc_cmd_failed
  1706 000056C3 2C41                <1> 	sub	al, 'A'
  1707 000056C5 3A05[E2C10000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1708 000056CB 760A                <1> 	jna	short cmd_vol4
  1709                              <1> 
  1710 000056CD BE[ABC40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1711 000056D2 E9DDE8FFFF          <1> 	jmp	print_msg
  1712                              <1> 	
  1713                              <1> cmd_vol4:
  1714 000056D7 E896FAFFFF          <1> 	call	print_volume_info
  1715 000056DC 0F8278FEFFFF        <1>         jc      cd_drive_not_ready
  1716 000056E2 C3                  <1> 	retn
  1717                              <1> 
  1718                              <1> cmp_cmd_attrib:
  1719 000056E3 B106                <1> 	mov	cl, 6
  1720 000056E5 BF[8BC20000]        <1> 	mov	edi, Cmd_Attrib
  1721 000056EA E877000000          <1> 	call	cmp_cmd	
  1722 000056EF 0F83380F0000        <1>         jnc     set_file_attributes
  1723                              <1> 
  1724                              <1> cmp_cmd_rename:
  1725 000056F5 B106                <1> 	mov	cl, 6
  1726 000056F7 BF[92C20000]        <1> 	mov	edi, Cmd_Rename
  1727 000056FC E865000000          <1> 	call	cmp_cmd	
  1728 00005701 0F836E110000        <1>         jnc     rename_file
  1729                              <1> 
  1730                              <1> cmp_cmd_device:
  1731 00005707 B106                <1> 	mov	cl, 6
  1732 00005709 BF[D0C20000]        <1> 	mov	edi, Cmd_Device
  1733 0000570E E853000000          <1> 	call	cmp_cmd	
  1734 00005713 7234                <1>         jc	short cmp_cmd_external
  1735                              <1> 
  1736 00005715 C3                  <1> 	retn
  1737                              <1> 
  1738                              <1> c_7:
  1739                              <1> cmp_cmd_devlist:
  1740 00005716 BF[D7C20000]        <1> 	mov	edi, Cmd_DevList
  1741 0000571B E846000000          <1> 	call	cmp_cmd	
  1742 00005720 7227                <1>         jc	short cmp_cmd_external
  1743                              <1> 
  1744 00005722 C3                  <1> 	retn
  1745                              <1> 
  1746                              <1> c_8:
  1747 00005723 80F908              <1>         cmp	cl, 8
  1748 00005726 7721                <1> 	ja	short cmp_cmd_external
  1749 00005728 72EC                <1> 	jb	short c_7
  1750                              <1> 
  1751                              <1> cmp_cmd_longname:
  1752 0000572A BF[63C20000]        <1> 	mov	edi, Cmd_LongName
  1753 0000572F E832000000          <1> 	call	cmp_cmd	
  1754 00005734 0F8351060000        <1>         jnc     get_and_print_longname
  1755                              <1> 
  1756                              <1> cmp_cmd_readfile:
  1757 0000573A B108                <1> 	mov	cl, 8
  1758 0000573C BF[BEC20000]        <1> 	mov	edi, Cmd_ReadFile
  1759 00005741 E820000000          <1> 	call	cmp_cmd	
  1760 00005746 7201                <1>         jc	short cmp_cmd_external
  1761                              <1> 
  1762                              <1> loc_cmd_return:
  1763 00005748 C3                  <1> 	retn
  1764                              <1> 
  1765                              <1> cmp_cmd_external:
  1766                              <1> 	; 07/05/2016
  1767                              <1> 	; 22/04/2016
  1768 00005749 BE[FED30000]        <1> 	mov	esi, CommandBuffer
  1769 0000574E E9F21C0000          <1> 	jmp	loc_run_check_filename 
  1770                              <1> 
  1771                              <1> loc_cmd_failed:
  1772 00005753 803D[FED30000]20    <1> 	cmp	byte [CommandBuffer], 20h
  1773 0000575A 76EC                <1> 	jna	short loc_cmd_return
  1774 0000575C BE[8CC40000]        <1> 	mov	esi, Msg_Bad_Command
  1775                              <1> ;	call	print_msg
  1776                              <1> ;loc_cmd_return:
  1777                              <1> ;	retn
  1778 00005761 E94EE8FFFF          <1> 	jmp	print_msg
  1779                              <1> 
  1780                              <1> cmp_cmd:
  1781                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1782 00005766 BE[FED30000]        <1>          mov	esi, CommandBuffer
  1783                              <1>          ; edi = internal command word (ASCIIZ)
  1784                              <1> 	 ; ecx = command length (<=8)
  1785                              <1> cmp_cmd_1:
  1786 0000576B AC                  <1> 	lodsb
  1787 0000576C AE                  <1> 	scasb
  1788 0000576D 750D                <1> 	jne	short cmp_cmd_3
  1789 0000576F E2FA                <1> 	loop	cmp_cmd_1
  1790 00005771 AC                  <1>  	lodsb
  1791 00005772 3C20                <1> 	cmp	al, 20h
  1792 00005774 7703                <1> 	ja	short cmp_cmd_2
  1793 00005776 30C0                <1> 	xor	al, al
  1794                              <1> 	; ZF = 1 -> internal command word matches
  1795 00005778 C3                  <1> 	retn
  1796                              <1> cmp_cmd_2:
  1797                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1798 00005779 58                  <1> 	pop	eax ; no return to the caller from here 
  1799 0000577A EBCD                <1> 	jmp	cmp_cmd_external	
  1800                              <1> cmp_cmd_3:
  1801 0000577C F9                  <1> 	stc
  1802                              <1> 	; CF = 1 -> internal command word does not match
  1803 0000577D C3                  <1> 	retn
  1804                              <1> 
  1805                              <1> loc_run_cmd_failed:
  1806                              <1> 	; 15/03/2016
  1807                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1808                              <1> 	; 07/12/2009 (CMD_INTR.ASM)	
  1809                              <1> 	; 29/11/2009
  1810                              <1> 
  1811 0000577E E855000000          <1> 	call	restore_cdir_after_cmd_fail
  1812                              <1> 
  1813                              <1> loc_run_cmd_failed_cmp_al:
  1814                              <1> 	; End of Restore_CDIR code (29/11/2009)
  1815                              <1> 
  1816 00005783 3C01                <1> 	cmp	al, 1
  1817 00005785 74CC                <1> 	je	loc_cmd_failed
  1818                              <1> loc_run_dir_not_found:
  1819 00005787 3C03                <1> 	cmp	al, 3
  1820 00005789 750A                <1> 	jne	short loc_run_file_notfound_msg
  1821                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1822 0000578B BE[EEC40000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1823 00005790 E91FE8FFFF          <1> 	jmp	print_msg
  1824                              <1> 
  1825                              <1> loc_run_file_notfound_msg:
  1826 00005795 3C02                <1> 	cmp	al, 2 ; File not found
  1827 00005797 750A                <1> 	jne	short loc_run_file_drv_read_err
  1828                              <1> 
  1829                              <1> loc_print_file_notfound_msg: 
  1830 00005799 BE[05C50000]        <1>         mov     esi, Msg_File_Not_Found
  1831                              <1> 	;call	proc_printmsg
  1832                              <1> 	;retn
  1833 0000579E E911E8FFFF          <1> 	jmp	print_msg
  1834                              <1> 
  1835                              <1> loc_run_file_drv_read_err:
  1836                              <1> 	; Err: 1Eh (Read fault)
  1837 000057A3 3C1E                <1> 	cmp	al, 1Eh ; Drive not ready or read error
  1838 000057A5 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1839                              <1> 	;
  1840 000057A7 3C15                <1> 	cmp	al, 15h ; Drive not ready (or read error)
  1841 000057A9 750A                <1> 	jne	short loc_run_file_toobig
  1842                              <1> 
  1843                              <1> loc_run_file_print_drv_read_err:
  1844 000057AB BE[ABC40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1845 000057B0 E9FFE7FFFF          <1> 	jmp	print_msg
  1846                              <1> 
  1847                              <1> loc_run_file_toobig:
  1848 000057B5 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1849 000057B7 750A                <1> 	jne	short loc_run_misc_error
  1850 000057B9 BE[4DC50000]        <1> 	mov	esi, Msg_Insufficient_Memory
  1851 000057BE E9F1E7FFFF          <1> 	jmp	print_msg
  1852                              <1> 
  1853                              <1> 	; 15/03/2016
  1854                              <1> print_misc_error_msg:
  1855                              <1> loc_run_misc_error:
  1856                              <1> 	; AL = Error code
  1857 000057C3 E806C1FFFF          <1> 	call	bytetohex
  1858 000057C8 66A3[81C50000]      <1>         mov     [error_code_hex], ax
  1859                              <1> 	
  1860 000057CE BE[64C50000]        <1> 	mov	esi, Msg_Error_Code 
  1861                              <1> 	;call	print_msg 
  1862                              <1> 	;retn
  1863                              <1> 
  1864 000057D3 E9DCE7FFFF          <1> 	jmp	print_msg
  1865                              <1> 
  1866                              <1> restore_cdir_after_cmd_fail:
  1867                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1868 000057D8 50                  <1> 	push	eax
  1869 000057D9 8A3D[AEDB0000]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1870                              <1> 				; of the 'run' command.
  1871 000057DF 3A3D[4ED30000]      <1> 	cmp	bh, [Current_Drv]
  1872 000057E5 7409                <1> 	je	short loc_run_restore_cdir
  1873 000057E7 88FA                <1> 	mov	dl, bh
  1874 000057E9 E8CBF0FFFF          <1> 	call	change_current_drive 
  1875 000057EE EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1876                              <1> 
  1877                              <1> loc_run_restore_cdir:
  1878 000057F0 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1879 000057F7 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1880 000057F9 30DB                <1> 	xor	bl, bl
  1881 000057FB 0FB7F3              <1> 	movzx	esi, bx
  1882 000057FE 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1883 00005804 E862F1FFFF          <1> 	call	restore_current_directory
  1884                              <1> 
  1885                              <1> loc_run_err_pass_restore_cdir:
  1886 00005809 58                  <1> 	pop	eax
  1887 0000580A C3                  <1> 	retn
  1888                              <1> 
  1889                              <1> print_directory_list:
  1890                              <1> 	; 10/02/2016
  1891                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1892                              <1> 	; 06/12/2009 ('cmp_cmd_dir')	
  1893                              <1> 	;
  1894 0000580B 66C705[F0DC0000]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1894 00005813 08                  <1>
  1895 00005814 A0[4ED30000]        <1> 	mov	al, [Current_Drv]
  1896 00005819 A2[AEDB0000]        <1> 	mov	[RUN_CDRV], al
  1897                              <1> get_dfname_fchar:
  1898 0000581E AC                  <1> 	lodsb
  1899 0000581F 3C20                <1> 	cmp	al, 20h
  1900 00005821 74FB                <1> 	je	short get_dfname_fchar
  1901 00005823 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1902 00005829 3C2D                <1> 	cmp	al, '-'
  1903 0000582B 7542                <1> 	jne	short loc_print_dir_call_flt
  1904                              <1> get_next_attr_char:
  1905 0000582D AC                  <1> 	lodsb
  1906 0000582E 3C20                <1> 	cmp	al, 20h
  1907 00005830 74FB                <1> 	je	short get_next_attr_char
  1908 00005832 0F821BFFFFFF        <1>         jb      loc_cmd_failed
  1909 00005838 24DF                <1> 	and	al, 0DFh
  1910 0000583A 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1911 0000583C 7512                <1> 	jne	short pass_only_directories
  1912 0000583E AC                  <1> 	lodsb
  1913 0000583F 3C20                <1> 	cmp	al, 20h
  1914 00005841 0F870CFFFFFF        <1>         ja      loc_cmd_failed
  1915 00005847 800D[F0DC0000]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1916 0000584E EB18                <1> 	jmp	short get_dfname_fchar_attr
  1917                              <1> pass_only_directories:
  1918 00005850 3C46                <1> 	cmp	al, 'F'	; files only ?
  1919 00005852 0F85B0000000        <1>         jne     check_attr_s
  1920 00005858 AC                  <1> 	lodsb
  1921 00005859 3C20                <1> 	cmp	al, 20h
  1922 0000585B 0F87F2FEFFFF        <1>         ja      loc_cmd_failed
  1923 00005861 800D[F1DC0000]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1924                              <1> get_dfname_fchar_attr:
  1925 00005868 AC                  <1> 	lodsb
  1926 00005869 3C20                <1> 	cmp	al, 20h
  1927 0000586B 74FB                <1> 	je	short get_dfname_fchar_attr
  1928 0000586D 725E                <1> 	jb	short loc_print_dir_call_all
  1929                              <1> 
  1930                              <1> loc_print_dir_call_flt:
  1931 0000586F 4E                  <1> 	dec	esi
  1932 00005870 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  1933 00005875 E8E5250000          <1> 	call	parse_path_name
  1934 0000587A 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1935 0000587C 3C01                <1> 	cmp	al, 1
  1936 0000587E 0F87FAFEFFFF        <1>         ja      loc_run_cmd_failed
  1937                              <1> 
  1938                              <1> loc_print_dir_change_drv_1:
  1939 00005884 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  1940                              <1> loc_print_dir_change_drv_2:
  1941 0000588A 3A15[AEDB0000]      <1> 	cmp	dl, [RUN_CDRV]
  1942 00005890 740B                <1> 	je	short loc_print_dir_change_directory 
  1943 00005892 E822F0FFFF          <1> 	call	change_current_drive
  1944 00005897 0F82E1FEFFFF        <1>         jc      loc_run_cmd_failed
  1945                              <1> loc_print_dir_change_directory:
  1946 0000589D 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1947 000058A4 761D                <1> 	jna	short pass_print_dir_change_directory
  1948                              <1> 
  1949 000058A6 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  1950 000058AC BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  1951 000058B1 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1952 000058B3 E8931F0000          <1> 	call	change_current_directory
  1953 000058B8 0F82C0FEFFFF        <1>         jc      loc_run_cmd_failed
  1954                              <1> 
  1955                              <1> loc_print_dir_change_prompt_dir_string:
  1956 000058BE E8A81E0000          <1> 	call	change_prompt_dir_string
  1957                              <1> 
  1958                              <1> pass_print_dir_change_directory:
  1959 000058C3 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  1960 000058C8 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1961 000058CB 7706                <1> 	ja	short loc_print_dir_call
  1962                              <1> 
  1963                              <1> loc_print_dir_call_all:
  1964 000058CD C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1965                              <1> loc_print_dir_call:
  1966 000058D3 E87E000000          <1> 	call	print_directory
  1967                              <1> 
  1968 000058D8 8A15[AEDB0000]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1969 000058DE 3A15[4ED30000]      <1> 	cmp	dl, [Current_Drv]
  1970 000058E4 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1971 000058E6 E8CEEFFFFF          <1> 	call	change_current_drive 
  1972 000058EB C3                  <1> 	retn
  1973                              <1> 
  1974                              <1> loc_print_dir_call_restore_cdir_retn:
  1975 000058EC 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1976 000058F3 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  1977                              <1> 
  1978 000058F5 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1979 000058FA 31C0                <1> 	xor	eax, eax
  1980 000058FC 88D4                <1> 	mov	ah, dl
  1981 000058FE 01C6                <1> 	add	esi, eax
  1982                              <1> 
  1983 00005900 E866F0FFFF          <1> 	call	restore_current_directory
  1984                              <1> 
  1985                              <1> pass_print_dir_call_restore_cdir_retn:
  1986 00005905 C3                  <1> 	retn
  1987                              <1> 
  1988                              <1> check_attr_s_cap:
  1989 00005906 24DF                <1> 	and	al, 0DFh
  1990                              <1> check_attr_s:
  1991 00005908 3C53                <1> 	cmp	al, 'S'
  1992 0000590A 7514                <1> 	jne	short pass_attr_s
  1993 0000590C 800D[F0DC0000]04    <1> 	or	byte [AttributesMask], 4 ; system
  1994 00005913 AC                  <1> 	lodsb
  1995 00005914 3C20                <1> 	cmp	al, 20h
  1996 00005916 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  1997 0000591C 72AF                <1> 	jb	short loc_print_dir_call_all
  1998 0000591E 24DF                <1> 	and	al, 0DFh
  1999                              <1> pass_attr_s:
  2000 00005920 3C48                <1> 	cmp	al, 'H'
  2001 00005922 7514                <1> 	jne	short pass_attr_h
  2002 00005924 800D[F0DC0000]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  2003                              <1> pass_attr_shr:
  2004 0000592B AC                  <1> 	lodsb
  2005 0000592C 3C20                <1> 	cmp	al, 20h
  2006 0000592E 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  2007 00005934 7297                <1> 	jb	short loc_print_dir_call_all
  2008 00005936 EBCE                <1> 	jmp	short check_attr_s_cap
  2009                              <1> 
  2010                              <1> pass_attr_h:
  2011 00005938 3C52                <1> 	cmp	al, 'R'
  2012 0000593A 7509                <1> 	jne	short pass_attr_r
  2013 0000593C 800D[F0DC0000]01    <1> 	or	byte [AttributesMask], 1 ; read only
  2014 00005943 EBE6                <1> 	jmp	short pass_attr_shr
  2015                              <1> 
  2016                              <1> pass_attr_r:
  2017 00005945 3C41                <1> 	cmp	al, 'A'
  2018 00005947 0F8506FEFFFF        <1>         jne     loc_cmd_failed
  2019 0000594D 800D[F0DC0000]20    <1> 	or	byte [AttributesMask], 20h ; archive
  2020 00005954 EBD5                <1> 	jmp	short pass_attr_shr
  2021                              <1> 
  2022                              <1> print_directory:
  2023                              <1> 	; 13/05/2016
  2024                              <1> 	; 11/02/2016
  2025                              <1> 	; 10/02/2016
  2026                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2027                              <1> 	; 30/10/2010 ('proc_print_directory')	
  2028                              <1> 	; 19/09/2009
  2029                              <1> 	; 2005 
  2030                              <1> 	; INPUT ->
  2031                              <1> 	;	ESI = Asciiz File/Dir Name Address
  2032                              <1> 
  2033 00005956 56                  <1> 	push	esi
  2034                              <1> 
  2035 00005957 29C0                <1> 	sub	eax, eax
  2036                              <1> 
  2037 00005959 66A3[7CDD0000]      <1> 	mov	word [Dir_Count], ax ; 0
  2038 0000595F 66A3[7ADD0000]      <1> 	mov 	word [File_Count], ax ; 0
  2039 00005965 A3[7EDD0000]        <1> 	mov 	dword [Total_FSize], eax ; 0
  2040                              <1> 
  2041 0000596A E85BE6FFFF          <1> 	call    clear_screen
  2042                              <1> 	
  2043 0000596F 31C9                <1> 	xor	ecx, ecx	
  2044 00005971 8A2D[4ED30000]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  2045 00005977 A0[4FD30000]        <1> 	mov     al, [Current_Dir_Drv] 
  2046 0000597C A2[A9C30000]        <1> 	mov     [Dir_Drive_Name], al
  2047 00005981 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2048 00005986 01CE                <1> 	add	esi, ecx
  2049                              <1> 
  2050 00005988 E85FF9FFFF          <1> 	call	move_volume_name_and_serial_no
  2051 0000598D 730C                <1> 	jnc	short print_dir_strlen_check
  2052                              <1> 
  2053 0000598F 5E                  <1> 	pop	esi
  2054 00005990 8A3D[B8D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  2055                              <1> 	;call	beeper
  2056                              <1> 	;retn
  2057 00005996 E922BEFFFF          <1> 	jmp	beeper  ; beep ! and return
  2058                              <1> 
  2059                              <1> print_dir_strlen_check:
  2060 0000599B BE[51D30000]        <1> 	mov	esi, Current_Dir_Root
  2061 000059A0 BF[46C40000]        <1> 	mov	edi, Dir_Str_Root
  2062                              <1> 	
  2063                              <1> 	;xor	ecx, ecx
  2064 000059A5 8A0D[ADD30000]      <1>         mov     cl, [Current_Dir_StrLen]
  2065 000059AB FEC1                <1> 	inc	cl
  2066 000059AD 80F940              <1> 	cmp	cl, 64
  2067 000059B0 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2068 000059B2 46                  <1> 	inc	esi
  2069 000059B3 01CE                <1> 	add	esi, ecx
  2070 000059B5 83EE40              <1> 	sub	esi, 64 
  2071 000059B8 47                  <1> 	inc	edi
  2072 000059B9 B82E2E2E20          <1> 	mov	eax, '... ' 
  2073 000059BE AB                  <1> 	stosd
  2074                              <1>  
  2075                              <1> pass_print_dir_strlen_shorting:
  2076 000059BF F3A4                <1> 	rep	movsb
  2077                              <1> 
  2078 000059C1 BE[9CC30000]        <1> 	mov	esi, Dir_Drive_Str
  2079 000059C6 E8E9E5FFFF          <1> 	call	print_msg
  2080                              <1> 
  2081 000059CB BE[FBC30000]        <1> 	mov	esi, Vol_Serial_Header
  2082 000059D0 E8DFE5FFFF          <1> 	call	print_msg
  2083                              <1> 
  2084 000059D5 BE[3BC40000]        <1> 	mov	esi, Dir_Str_Header
  2085 000059DA E8D5E5FFFF          <1> 	call	print_msg
  2086                              <1> 	
  2087 000059DF BE[1ECF0000]        <1> 	mov	esi, next2line
  2088 000059E4 E8CBE5FFFF          <1> 	call	print_msg
  2089                              <1> 
  2090                              <1> loc_print_dir_first_file:
  2091 000059E9 C605[91DD0000]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2092 000059F0 66A1[F0DC0000]      <1> 	mov	ax, [AttributesMask]
  2093 000059F6 5E                  <1> 	pop	esi
  2094                              <1> 
  2095 000059F7 E859020000          <1> 	call	find_first_file
  2096 000059FC 0F826F010000        <1>         jc      loc_dir_ok
  2097                              <1> 	 
  2098                              <1> loc_dfname_use_this:
  2099                              <1> 	; bl =	File Attributes (bh = Long Name Entry Length)
  2100 00005A02 F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2101 00005A05 741B                <1> 	jz	short loc_not_dir
  2102                              <1> 
  2103 00005A07 66FF05[7CDD0000]    <1> 	inc	word [Dir_Count]
  2104 00005A0E 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2105 00005A10 BE[88C50000]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2106 00005A15 BF[9FC50000]        <1> 	mov	edi, Dir_Or_FileSize
  2107                              <1> 	; move 10 bytes
  2108 00005A1A A5                  <1> 	movsd
  2109 00005A1B A5                  <1> 	movsd
  2110 00005A1C 66A5                <1> 	movsw	    	
  2111 00005A1E 89D6                <1> 	mov	esi, edx
  2112 00005A20 EB36                <1> 	jmp     short loc_dir_attribute
  2113                              <1> 
  2114                              <1> loc_not_dir:
  2115 00005A22 66FF05[7ADD0000]    <1> 	inc	word [File_Count]
  2116 00005A29 0105[7EDD0000]      <1> 	add	[Total_FSize], eax
  2117                              <1> 
  2118 00005A2F B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2119 00005A34 89CF                <1> 	mov	edi, ecx
  2120 00005A36 81C7[9FC50000]      <1> 	add	edi, Dir_Or_FileSize
  2121                              <1> loc_dir_rdivide:
  2122 00005A3C 29D2                <1> 	sub	edx, edx
  2123 00005A3E F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2124 00005A40 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2125 00005A43 4F                  <1> 	dec	edi
  2126 00005A44 8817                <1> 	mov     [edi], dl
  2127 00005A46 21C0                <1> 	and	eax, eax
  2128 00005A48 75F2                <1> 	jnz	short loc_dir_rdivide
  2129                              <1> 
  2130                              <1> loc_dir_fill_space:
  2131 00005A4A 81FF[9FC50000]      <1> 	cmp     edi, Dir_Or_FileSize
  2132 00005A50 7606                <1> 	jna     short loc_dir_attribute
  2133 00005A52 4F                  <1> 	dec     edi
  2134 00005A53 C60720              <1> 	mov     byte [edi], 20h
  2135 00005A56 EBF2                <1> 	jmp     short loc_dir_fill_space
  2136                              <1> 
  2137                              <1> loc_dir_attribute:
  2138 00005A58 C705[AAC50000]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2138 00005A60 2020                <1>
  2139                              <1> 
  2140 00005A62 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2141 00005A65 7207                <1> 	jb	short loc_dir_pass_arch
  2142 00005A67 C605[ADC50000]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2143                              <1> 
  2144                              <1> loc_dir_pass_arch:
  2145 00005A6E 80E307              <1> 	and	bl, 7
  2146 00005A71 7428                <1> 	jz	short loc_dir_file_name
  2147 00005A73 88DF                <1> 	mov	bh, bl
  2148 00005A75 80E303              <1> 	and	bl, 3
  2149 00005A78 38DF                <1> 	cmp	bh, bl
  2150 00005A7A 7607                <1> 	jna	short loc_dir_pass_s
  2151 00005A7C C605[AAC50000]53    <1> 	mov	byte [File_Attribute], 'S'
  2152                              <1> 
  2153                              <1> loc_dir_pass_s:
  2154 00005A83 80E302              <1> 	and     bl,2
  2155 00005A86 7407                <1> 	jz      short loc_dir_pass_h
  2156 00005A88 C605[ABC50000]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2157                              <1> loc_dir_pass_h:
  2158 00005A8F 80E701              <1> 	and     bh,1
  2159 00005A92 7407                <1> 	jz      short loc_dir_file_name
  2160 00005A94 C605[ACC50000]52    <1> 	mov     byte [File_Attribute+2], 'R'
  2161                              <1> loc_dir_file_name:
  2162                              <1> 	;mov     bx, [esi+18h] ; Date
  2163                              <1> 	;mov     dx, [esi+16h] ; Time
  2164 00005A9B 8B5E16              <1> 	mov	ebx, [esi+16h]
  2165 00005A9E 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2166 00005AA0 BF[92C50000]        <1> 	mov     edi, File_Name
  2167                              <1> 	; move 8 bytes
  2168 00005AA5 A5                  <1> 	movsd
  2169 00005AA6 A5                  <1> 	movsd
  2170 00005AA7 C60720              <1> 	mov	byte [edi], 20h
  2171 00005AAA 47                  <1> 	inc	edi
  2172                              <1> 	; move 3 bytes
  2173 00005AAB 66A5                <1> 	movsw
  2174 00005AAD A4                  <1> 	movsb
  2175 00005AAE 89CE                <1> 	mov	esi, ecx
  2176                              <1> 
  2177                              <1> Dir_Time_start:
  2178                              <1> 	;mov	ax, dx		; Time
  2179 00005AB0 6689D8              <1> 	mov	ax, bx
  2180 00005AB3 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2181 00005AB7 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2182 00005ABB D40A                <1> 	aam			; Q([AL]/10)->AH
  2183                              <1> 				; R([AL]/10)->AL
  2184                              <1> 				; [AL]+[AH]= Minute as BCD
  2185 00005ABD 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2186 00005AC1 86E0                <1> 	xchg	ah, al
  2187 00005AC3 66A3[BDC50000]      <1> 	mov	[File_Minute], ax
  2188                              <1> 
  2189                              <1> 	;mov	al, dh
  2190 00005AC9 88F8                <1> 	mov	al, bh
  2191 00005ACB C0E803              <1> 	shr	al, 3		; shift right 3 times
  2192 00005ACE D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2193 00005AD0 660D3030            <1> 	or	ax, '00'
  2194 00005AD4 86E0                <1> 	xchg	ah, al
  2195 00005AD6 66A3[BAC50000]      <1> 	mov     [File_Hour], ax
  2196                              <1> 
  2197 00005ADC C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2198                              <1> 	
  2199                              <1> Dir_Date_start:
  2200 00005ADF 6689D8              <1> 	mov	ax, bx		; Date
  2201 00005AE2 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2202 00005AE6 D40A                <1> 	aam			; Q([AL]/10)->AH
  2203                              <1> 				; R([AL]/10)->AL
  2204                              <1> 				; [AL]+[AH]= Day as BCD
  2205 00005AE8 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2206 00005AEC 86C4                <1> 	xchg	al, ah
  2207                              <1> 
  2208 00005AEE 66A3[AFC50000]      <1> 	mov	[File_Day], ax
  2209                              <1> 
  2210 00005AF4 6689D8              <1> 	mov	ax, bx
  2211 00005AF7 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2212 00005AFB 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2213 00005AFF D40A                <1> 	aam
  2214 00005B01 660D3030            <1> 	or	ax, '00'
  2215 00005B05 86E0                <1> 	xchg	ah, al
  2216 00005B07 66A3[B2C50000]      <1> 	mov	[File_Month], ax
  2217                              <1> 
  2218 00005B0D 6689D8              <1> 	mov	ax, bx
  2219 00005B10 66C1E809            <1> 	shr     ax, 9
  2220 00005B14 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2221 00005B18 6605BC07            <1> 	add	ax, 1980
  2222                              <1> 
  2223 00005B1C B10A                <1> 	mov	cl, 10
  2224 00005B1E F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2225 00005B20 80CC30              <1> 	or	ah, '0'
  2226 00005B23 8825[B8C50000]      <1> 	mov	[File_Year+3], ah
  2227 00005B29 D40A                <1> 	aam
  2228 00005B2B 86E0                <1> 	xchg	ah, al
  2229 00005B2D 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2230 00005B30 8825[B7C50000]      <1> 	mov	[File_Year+2], ah
  2231 00005B36 D40A                <1> 	aam
  2232 00005B38 86C4                <1> 	xchg	al, ah
  2233 00005B3A 660D3030            <1> 	or	ax, '00'
  2234 00005B3E 66A3[B5C50000]      <1> 	mov	[File_Year], ax
  2235                              <1> 
  2236                              <1> loc_show_line:
  2237 00005B44 56                  <1> 	push	esi
  2238 00005B45 BE[92C50000]        <1> 	mov     esi, File_Name
  2239 00005B4A E865E4FFFF          <1> 	call	print_msg
  2240 00005B4F BE[20CF0000]        <1> 	mov	esi, nextline
  2241 00005B54 E85BE4FFFF          <1> 	call	print_msg
  2242 00005B59 5E                  <1> 	pop	esi
  2243                              <1> 
  2244 00005B5A FE0D[91DD0000]      <1> 	dec	byte [PrintDir_RowCounter]
  2245 00005B60 0F84D4000000        <1>         jz      pause_dir_scroll
  2246                              <1> 
  2247                              <1> loc_next_entry:
  2248 00005B66 E899010000          <1> 	call	find_next_file
  2249 00005B6B 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2250                              <1> 
  2251                              <1> loc_dir_ok:
  2252 00005B71 B90A000000          <1> 	mov     ecx, 10
  2253 00005B76 66A1[7CDD0000]      <1> 	mov	ax, [Dir_Count]
  2254 00005B7C BF[D3C50000]        <1> 	mov	edi, Decimal_Dir_Count
  2255 00005B81 6639C8              <1> 	cmp	ax, cx ; 10
  2256 00005B84 7216                <1> 	jb	short pass_ddc
  2257 00005B86 47                  <1> 	inc	edi
  2258 00005B87 6683F864            <1> 	cmp	ax, 100
  2259 00005B8B 720F                <1> 	jb	short pass_ddc
  2260 00005B8D 47                  <1> 	inc	edi
  2261 00005B8E 663DE803            <1> 	cmp	ax, 1000
  2262 00005B92 7208                <1> 	jb	short pass_ddc
  2263 00005B94 47                  <1> 	inc	edi
  2264 00005B95 663D1027            <1> 	cmp	ax, 10000
  2265 00005B99 7201                <1> 	jb	short pass_ddc
  2266 00005B9B 47                  <1> 	inc	edi
  2267                              <1> pass_ddc:
  2268 00005B9C 886F01              <1> 	mov     [edi+1], ch ; 0
  2269                              <1> loc_ddc_rediv:
  2270 00005B9F 31D2                <1> 	xor     edx, edx
  2271 00005BA1 66F7F1              <1> 	div     cx	; 10
  2272 00005BA4 80C230              <1> 	add     dl, '0'
  2273 00005BA7 8817                <1> 	mov     [edi], dl
  2274 00005BA9 4F                  <1> 	dec     edi
  2275 00005BAA 6609C0              <1> 	or	ax, ax
  2276 00005BAD 75F0                <1> 	jnz	short loc_ddc_rediv
  2277                              <1> 
  2278 00005BAF 66A1[7ADD0000]      <1> 	mov     ax, [File_Count]
  2279 00005BB5 BF[C2C50000]        <1> 	mov     edi, Decimal_File_Count
  2280 00005BBA 6639C8              <1> 	cmp     ax, cx ; 10
  2281 00005BBD 7216                <1> 	jb      short pass_dfc
  2282 00005BBF 47                  <1> 	inc     edi
  2283 00005BC0 6683F864            <1> 	cmp     ax, 100
  2284 00005BC4 720F                <1> 	jb      short pass_dfc
  2285 00005BC6 47                  <1> 	inc     edi
  2286 00005BC7 663DE803            <1> 	cmp     ax, 1000
  2287 00005BCB 7208                <1> 	jb      short pass_dfc
  2288 00005BCD 47                  <1> 	inc     edi
  2289 00005BCE 663D1027            <1> 	cmp     ax, 10000
  2290 00005BD2 7201                <1> 	jb      short pass_dfc
  2291 00005BD4 47                  <1> 	inc     edi
  2292                              <1> pass_dfc:
  2293                              <1> 	;mov    cx, 10
  2294 00005BD5 886F01              <1> 	mov     [edi+1], ch ; 00
  2295                              <1> loc_dfc_rediv:
  2296                              <1> 	;xor	dx, dx
  2297 00005BD8 30D2                <1> 	xor	dl, dl
  2298 00005BDA 66F7F1              <1> 	div	cx
  2299 00005BDD 80C230              <1> 	add	dl, '0'
  2300 00005BE0 8817                <1> 	mov	[edi], dl
  2301 00005BE2 4F                  <1> 	dec	edi
  2302 00005BE3 6609C0              <1> 	or	ax, ax
  2303 00005BE6 75F0                <1> 	jnz	short loc_dfc_rediv
  2304                              <1> 
  2305 00005BE8 BF[90DD0000]        <1> 	mov     edi, TFS_Dec_End
  2306                              <1>         ;mov    byte [edi], 0
  2307 00005BED A1[7EDD0000]        <1> 	mov     eax, [Total_FSize]
  2308                              <1> 	;mov    ecx, 10
  2309                              <1> rediv_tfs_hex:
  2310                              <1> 	;sub	edx, edx
  2311 00005BF2 28D2                <1> 	sub	dl, dl
  2312 00005BF4 F7F1                <1> 	div	ecx
  2313 00005BF6 80C230              <1> 	add	dl, '0'
  2314 00005BF9 4F                  <1> 	dec     edi
  2315 00005BFA 8817                <1> 	mov     [edi], dl
  2316 00005BFC 21C0                <1> 	and	eax, eax
  2317 00005BFE 75F2                <1> 	jnz	short rediv_tfs_hex
  2318                              <1> 	
  2319 00005C00 893D[82DD0000]      <1> 	mov	[TFS_Dec_Begin], edi
  2320 00005C06 BE[C0C50000]        <1> 	mov	esi, Decimal_File_Count_Header
  2321 00005C0B E8A4E3FFFF          <1> 	call	print_msg
  2322 00005C10 BE[C8C50000]        <1> 	mov	esi, str_files
  2323 00005C15 E89AE3FFFF          <1> 	call	print_msg
  2324 00005C1A BE[D9C50000]        <1> 	mov	esi, str_dirs
  2325 00005C1F E890E3FFFF          <1> 	call	print_msg
  2326 00005C24 8B35[82DD0000]      <1> 	mov	esi, [TFS_Dec_Begin]
  2327 00005C2A E885E3FFFF          <1> 	call	print_msg
  2328 00005C2F BE[EAC50000]        <1> 	mov	esi, str_bytes
  2329 00005C34 E87BE3FFFF          <1> 	call	print_msg
  2330                              <1> 
  2331 00005C39 C3                  <1> 	retn
  2332                              <1> 
  2333                              <1> pause_dir_scroll:
  2334 00005C3A 28E4                <1> 	sub	ah, ah           
  2335 00005C3C E85BAEFFFF          <1> 	call	int16h
  2336 00005C41 3C1B                <1> 	cmp	al, 1Bh
  2337 00005C43 0F8428FFFFFF        <1>         je      loc_dir_ok
  2338 00005C49 C605[91DD0000]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2339 00005C50 E911FFFFFF          <1>         jmp     loc_next_entry
  2340                              <1> 
  2341                              <1> find_first_file:
  2342                              <1> 	; 11/02/2015
  2343                              <1> 	; 10/02/2016
  2344                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2345                              <1> 	; 09/10/2011
  2346                              <1> 	; 17/09/2009
  2347                              <1> 	; 2005
  2348                              <1> 	; INPUT ->
  2349                              <1> 	;	ESI = ASCIIZ File/Dir Name Address (in Current Directory)
  2350                              <1> 	;	AL = Attributes AND mask (The AND result must be equal to AL)
  2351                              <1> 	;	      bit 0 = Read Only
  2352                              <1> 	;	      bir 1 = Hidden
  2353                              <1> 	;	      bit 2 = System
  2354                              <1> 	;	      bit 3 = Volume Label
  2355                              <1> 	;	      bit 4 = Directory
  2356                              <1> 	;	      bit 5 = Archive
  2357                              <1> 	;	      bit 6 = Reserved, must be 0
  2358                              <1> 	;	      bit 7 = Reserved, must be 0
  2359                              <1> 	;       AH = Attributes Negative AND mask (The AND result must be ZERO)
  2360                              <1> 	;
  2361                              <1> 	; OUTPUT ->
  2362                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2363                              <1> 	;	CF = 0 ->
  2364                              <1> 	;	     ESI = Directory Entry (FindFile_DirEntry) Location
  2365                              <1> 	;	     EDI = Directory Buffer Directory Entry Location
  2366                              <1> 	;	     EAX = File Size
  2367                              <1> 	;	      BL = Attributes of The File/Directory
  2368                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2369                              <1> 	;             DX > 0 : Ambiguous filename chars are used
  2370                              <1> 	;
  2371                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2372                              <1> 
  2373 00005C55 66A3[42DD0000]      <1> 	mov	[FindFile_AttributesMask], ax
  2374 00005C5B BF[44DD0000]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2375 00005C60 31C0                <1> 	xor	eax, eax
  2376 00005C62 B90B000000          <1> 	mov	ecx, 11
  2377 00005C67 F3AB                <1> 	rep	stosd	; 44 bytes
  2378                              <1> 	;stosw		; +2 bytes 
  2379                              <1> 	    
  2380 00005C69 BF[34DD0000]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2381 00005C6E 39FE                <1> 	cmp	esi, edi
  2382 00005C70 7408                <1> 	je	short loc_fff_mfn_ok
  2383 00005C72 89FA                <1> 	mov	edx, edi 
  2384                              <1> 	 ; move 13 bytes
  2385 00005C74 A5                  <1> 	movsd
  2386 00005C75 A5                  <1> 	movsd
  2387 00005C76 A5                  <1> 	movsd
  2388 00005C77 AA                  <1> 	stosb
  2389 00005C78 89D6                <1> 	mov	esi, edx
  2390                              <1> loc_fff_mfn_ok:
  2391 00005C7A BF[E3DC0000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2392 00005C7F E810210000          <1> 	call	convert_file_name
  2393 00005C84 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2394                              <1> 
  2395 00005C86 66A1[42DD0000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2396                              <1> 	;xor	ecx, ecx
  2397 00005C8C 30C9                <1> 	xor	cl, cl  
  2398 00005C8E E80C1E0000          <1> 	call	locate_current_dir_file
  2399 00005C93 726E                <1> 	jc	short loc_fff_retn
  2400                              <1> 	; EDI = Directory Entry
  2401                              <1> 	; EBX = Directory Buffer Entry Index/Number
  2402                              <1> 
  2403                              <1> loc_fff_fnf_ln_check:
  2404 00005C95 30ED                <1> 	xor	ch, ch 
  2405 00005C97 80F60F              <1> 	xor	dh, 0Fh
  2406 00005C9A 7408                <1> 	jz	short loc_fff_longname_yes
  2407 00005C9C 882D[41DD0000]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2408 00005CA2 EB0C                <1> 	jmp	short loc_fff_longname_no
  2409                              <1> 
  2410                              <1> loc_fff_longname_yes:
  2411                              <1> 	;inc	byte [FindFile_LongNameYes]
  2412 00005CA4 8A0D[4EDC0000]      <1> 	mov	cl, [LFN_EntryLength]  
  2413 00005CAA 880D[41DD0000]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2414                              <1> 
  2415                              <1> loc_fff_longname_no:
  2416                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2417 00005CB0 66891D[6CDD0000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2418 00005CB7 6689C2              <1> 	mov	dx, ax ; Ambigouos Filename chars used sign > 0
  2419                              <1> 
  2420 00005CBA A0[4ED30000]        <1> 	mov	al, [Current_Drv]
  2421 00005CBF A2[F2DC0000]        <1> 	mov	[FindFile_Drv], al 
  2422                              <1> 
  2423 00005CC4 A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2424 00005CC9 A3[64DD0000]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2425                              <1> 
  2426 00005CCE A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2427 00005CD3 A3[68DD0000]        <1> 	mov	[FindFile_DirCluster], eax
  2428                              <1> 
  2429 00005CD8 66FF05[6EDD0000]    <1> 	inc	word [FindFile_MatchCounter]
  2430                              <1> 
  2431 00005CDF 89FB                <1> 	mov	ebx, edi
  2432 00005CE1 89FE                <1> 	mov	esi, edi
  2433 00005CE3 BF[44DD0000]        <1> 	mov	edi, FindFile_DirEntry
  2434 00005CE8 89F8                <1> 	mov	eax, edi
  2435 00005CEA B108                <1> 	mov	cl, 8
  2436 00005CEC F3A5                <1> 	rep	movsd
  2437 00005CEE 89C6                <1> 	mov	esi, eax
  2438 00005CF0 89DF                <1> 	mov	edi, ebx
  2439                              <1> 
  2440 00005CF2 A1[60DD0000]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2441                              <1> 
  2442 00005CF7 8A1D[4FDD0000]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2443 00005CFD 8A3D[41DD0000]      <1> 	mov	bh, [FindFile_LongNameYes]
  2444                              <1> 
  2445                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  2446                              <1> 	;mov	[FindFile_DirEntryNumber], cx
  2447                              <1> 	;mov	cx, [FindFile_DirEntryNumber]
  2448                              <1> 	; ecx = 0
  2449                              <1> 
  2450                              <1> loc_fff_retn:
  2451 00005D03 C3                  <1> 	retn
  2452                              <1> 
  2453                              <1> find_next_file:
  2454                              <1> 	; 10/02/2016
  2455                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2456                              <1> 	; 06/02/2011
  2457                              <1> 	; 17/09/2009
  2458                              <1> 	; 2005
  2459                              <1> 	; INPUT ->
  2460                              <1> 	;	NONE, Find First File Parameters
  2461                              <1> 	; OUTPUT ->
  2462                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2463                              <1> 	;	CF = 0 -> 
  2464                              <1> 	;	    ESI = Directory Entry (FindFile_DirEntry) Location
  2465                              <1> 	;	    EDI = Directory Buffer Directory Entry Location
  2466                              <1> 	;	    EAX = File Size
  2467                              <1> 	;	      BL = Attributes of The File/Directory
  2468                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2469                              <1> 	;             DX > 0 : Ambiguous filename chars are used 
  2470                              <1> 	;
  2471                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2472                              <1> 
  2473 00005D04 66833D[6EDD0000]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2474 00005D0C 7707                <1> 	ja	short loc_start_search_next_file
  2475                              <1> 
  2476                              <1> loc_fnf_stc_retn:
  2477 00005D0E F9                  <1> 	stc
  2478                              <1> loc_fnf_ax12h_retn:
  2479 00005D0F B812000000          <1> 	mov	eax, 12h ; 18, No More files
  2480                              <1> ;loc_fnf_retn:
  2481 00005D14 C3                  <1> 	retn
  2482                              <1> 
  2483                              <1> loc_start_search_next_file:
  2484 00005D15 668B1D[6CDD0000]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2485 00005D1C 6643                <1> 	inc	bx
  2486 00005D1E 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2487 00005D25 7719                <1> 	ja	short loc_cont_search_next_file
  2488                              <1> 
  2489                              <1> loc_fnf_search:
  2490 00005D27 BE[E3DC0000]        <1> 	mov	esi, Dir_Entry_Name
  2491 00005D2C 66A1[42DD0000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2492 00005D32 6631C9              <1> 	xor	cx, cx
  2493 00005D35 E8671E0000          <1> 	call	find_directory_entry
  2494 00005D3A 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2495                              <1> 
  2496                              <1> loc_cont_search_next_file:
  2497 00005D40 31DB                <1> 	xor	ebx, ebx
  2498 00005D42 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  2499 00005D48 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2500 00005D4D 01DE                <1> 	add	esi, ebx
  2501                              <1> 
  2502 00005D4F 803D[4CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2503 00005D56 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2504 00005D58 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2505 00005D5C 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2506 00005D5E EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2507                              <1>  
  2508                              <1> loc_fnf_check_FAT_type:
  2509 00005D60 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2510 00005D64 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2511                              <1> 
  2512                              <1> loc_fnf_check_next_cluster:
  2513 00005D66 A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2514 00005D6B E8E6370000          <1> 	call	get_next_cluster
  2515 00005D70 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2516 00005D72 09C0                <1> 	or	eax, eax
  2517 00005D74 7498                <1> 	jz	short loc_fnf_stc_retn
  2518                              <1> 	;mov	eax, 15h ;Drive not ready or read error
  2519 00005D76 F5                  <1>  	cmc	;stc
  2520                              <1> loc_fnf_retn:
  2521 00005D77 C3                  <1> 	retn
  2522                              <1> 
  2523                              <1> loc_fnf_load_next_dir_cluster:
  2524 00005D78 E8BF390000          <1> 	call	load_FAT_sub_directory
  2525 00005D7D 72F8                <1> 	jc	short loc_fnf_retn
  2526 00005D7F 6631DB              <1> 	xor	bx, bx
  2527 00005D82 66891D[6CDD0000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2528 00005D89 EB9C                <1> 	jmp	short loc_fnf_search
  2529                              <1> 
  2530                              <1> get_and_print_longname:
  2531                              <1> 	; 13/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2532                              <1> 	; 24/01/2010
  2533                              <1> 	; 17/10/2009 (CMD_INTR.ASM, 'cmp_cmd_longname')
  2534                              <1> get_longname_fchar:
  2535 00005D8B 803E20              <1> 	cmp	byte [esi], 20h
  2536 00005D8E 7701                <1> 	ja	short loc_find_longname
  2537                              <1> 	;jb	short loc_longname_retn
  2538                              <1> 	;inc	esi
  2539                              <1> 	;je	short get_longname_fchar
  2540                              <1> ;loc_longname_retn:
  2541 00005D90 C3                  <1> 	retn
  2542                              <1> loc_find_longname:
  2543 00005D91 E872210000          <1> 	call	find_longname
  2544 00005D96 7320                <1> 	jnc	short loc_print_longname
  2545                              <1> 	
  2546 00005D98 08C0                <1> 	or	al, al
  2547 00005D9A 7412                <1> 	jz	short loc_longname_not_found
  2548                              <1> 	  
  2549 00005D9C 3C15                <1> 	cmp	al, 15h
  2550 00005D9E 0F84B6F7FFFF        <1> 	je	cd_drive_not_ready
  2551                              <1> 
  2552                              <1> loc_ln_file_dir_not_found:
  2553 00005DA4 BE[17C50000]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2554                              <1> 	;call	print_msg	
  2555                              <1>         ;retn
  2556 00005DA9 E906E2FFFF          <1> 	jmp	print_msg
  2557                              <1> 
  2558                              <1> loc_longname_not_found:
  2559 00005DAE BE[36C50000]        <1>         mov     esi, Msg_LongName_Not_Found
  2560                              <1> 	;call	print_msg	
  2561                              <1>         ;retn
  2562 00005DB3 E9FCE1FFFF          <1> 	jmp	print_msg
  2563                              <1> 
  2564                              <1> loc_print_longname:
  2565                              <1> 	;mov	esi, LongFileName
  2566 00005DB8 BF[4ED40000]        <1> 	mov	edi, TextBuffer
  2567 00005DBD 57                  <1> 	push	edi 
  2568 00005DBE 3C00                <1> 	cmp	al, 0
  2569 00005DC0 7708                <1> 	ja	short loc_print_longname_1
  2570                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2571 00005DC2 AC                  <1> 	lodsb
  2572 00005DC3 AA                  <1> 	stosb  
  2573 00005DC4 08C0                <1> 	or	al, al
  2574 00005DC6 75FA                <1> 	jnz	short loc_print_FS_longname
  2575 00005DC8 EB07                <1> 	jmp	short loc_print_longname_2
  2576                              <1> 	;
  2577                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2578 00005DCA 66AD                <1> 	lodsw
  2579 00005DCC AA                  <1> 	stosb  
  2580 00005DCD 08C0                <1> 	or	al, al
  2581 00005DCF 75F9                <1> 	jnz	short loc_print_longname_1
  2582                              <1> 	;
  2583                              <1> loc_print_longname_2:	
  2584 00005DD1 5E                  <1> 	pop	esi
  2585 00005DD2 E8DDE1FFFF          <1> 	call	print_msg
  2586 00005DD7 BE[20CF0000]        <1>   	mov	esi, nextline
  2587                              <1> 	;call	print_msg
  2588                              <1> 	;retn
  2589 00005DDC E9D3E1FFFF          <1> 	jmp	print_msg	
  2590                              <1> 
  2591                              <1> show_file:
  2592                              <1> 	; 18/02/2016
  2593                              <1> 	; 17/02/2016
  2594                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2595                              <1> 	; 13/09/2011 (CMD_INTR.ASM, 'cmp_cmd_show')
  2596                              <1> 	; 08/11/2009
  2597                              <1> 
  2598                              <1> loc_show_parse_path_name:
  2599 00005DE1 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  2600 00005DE6 E874200000          <1> 	call	parse_path_name
  2601 00005DEB 0F8262F9FFFF        <1> 	jc	loc_cmd_failed
  2602                              <1> 
  2603                              <1> loc_show_check_filename_exists:
  2604 00005DF1 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  2605 00005DF6 803E20              <1> 	cmp	byte [esi], 20h
  2606 00005DF9 0F8654F9FFFF        <1> 	jna	loc_cmd_failed
  2607                              <1> 
  2608                              <1> 	; 15/02/2016 (invalid file name check)
  2609 00005DFF E809020000          <1> 	call	check_filename 	
  2610 00005E04 730A                <1> 	jnc	short loc_show_change_drv
  2611                              <1> 
  2612 00005E06 BE[00C60000]        <1> 	mov	esi, Msg_invalid_name_chars
  2613 00005E0B E9A4E1FFFF          <1> 	jmp	print_msg
  2614                              <1>    
  2615                              <1> loc_show_change_drv:
  2616 00005E10 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  2617 00005E16 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  2618 00005E1C 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  2619 00005E22 38F2                <1> 	cmp	dl, dh
  2620 00005E24 740B                <1> 	je	short loc_show_change_directory
  2621 00005E26 E88EEAFFFF          <1> 	call	change_current_drive
  2622                              <1> 	;jc	loc_file_rw_cmd_failed
  2623 00005E2B 0F824DF9FFFF        <1> 	jc	loc_run_cmd_failed
  2624                              <1> 
  2625                              <1> loc_show_change_directory:
  2626 00005E31 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2627 00005E38 7618                <1> 	jna	short loc_findload_showfile
  2628                              <1> 
  2629 00005E3A FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2630 00005E40 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  2631 00005E45 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2632 00005E47 E8FF190000          <1> 	call	change_current_directory
  2633                              <1> 	;jc	loc_file_rw_cmd_failed
  2634 00005E4C 0F822CF9FFFF        <1> 	jc	loc_run_cmd_failed
  2635                              <1> 
  2636                              <1> ;loc_show_change_prompt_dir_string:
  2637                              <1> 	;call	change_prompt_dir_string
  2638                              <1> 
  2639                              <1> loc_findload_showfile:
  2640                              <1> 	; 15/02/2016
  2641 00005E52 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  2642 00005E57 BF[E3DC0000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2643 00005E5C E8331F0000          <1> 	call	convert_file_name
  2644 00005E61 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2645                              <1> 
  2646 00005E63 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2647                              <1> 	; Directory attribute : 10h
  2648                              <1> 	; Volume name attribute: 8h
  2649 00005E65 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2650                              <1> 	;
  2651 00005E67 6631C9              <1> 	xor	cx, cx  
  2652 00005E6A E8301C0000          <1> 	call	locate_current_dir_file
  2653                              <1> 	;jc	loc_file_rw_cmd_failed
  2654 00005E6F 0F8209F9FFFF        <1> 	jc	loc_run_cmd_failed
  2655                              <1> 
  2656                              <1> loc_show_load_file:
  2657                              <1> 	; EDI = Directory Entry
  2658 00005E75 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2659 00005E79 C1E010              <1> 	shl	eax, 16
  2660 00005E7C 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2661 00005E80 A3[9CDD0000]        <1> 	mov	[Show_Cluster], eax
  2662 00005E85 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2663 00005E88 21C0                <1> 	and	eax, eax ; Empty file !
  2664 00005E8A 0F8491000000        <1>         jz      end_of_show_file 
  2665 00005E90 A3[A0DD0000]        <1> 	mov	[Show_FileSize], eax
  2666 00005E95 31C0                <1> 	xor	eax, eax
  2667 00005E97 A3[A4DD0000]        <1> 	mov	[Show_FilePointer], eax ; 0
  2668 00005E9C 66A3[A8DD0000]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2669 00005EA2 29DB                <1> 	sub	ebx, ebx
  2670 00005EA4 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  2671 00005EAA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2672 00005EAF 01DE                <1> 	add	esi, ebx
  2673 00005EB1 8935[98DD0000]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2674                              <1> 
  2675 00005EB7 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2676 00005EBB 7713                <1> 	ja	short loc_show_calculate_cluster_size
  2677                              <1> 	; Singlix FS
  2678                              <1> 	; First Cluster Number is FDT number (in compatibility buffer)
  2679 00005EBD 8B15[9CDD0000]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2680 00005EC3 8915[94DD0000]      <1> 	mov	[Show_FDT], edx
  2681 00005EC9 31C0                <1> 	xor	eax, eax
  2682 00005ECB A3[9CDD0000]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2683                              <1> 				    ; (next time it will be 1)			
  2684                              <1> loc_show_calculate_cluster_size:
  2685 00005ED0 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec] ; FAT 12-16-32 (512)
  2686                              <1> 	; BX = 512 = [esi+LD_FS_BytesPerSec] ; Singlix FS	
  2687 00005ED4 8A4613              <1> 	mov	al, [esi+LD_BPB+BPB_SecPerClust] ; FAT 12-16-32 (<= 128)
  2688                              <1> 	; AL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  2689 00005ED7 F7E3                <1> 	mul	ebx	
  2690                              <1> 
  2691                              <1> 	;cmp	eax, 65536 ; non-compatible (very big) cluster size
  2692                              <1> 	;ja	short end_of_show_file	
  2693 00005ED9 66A3[AADD0000]      <1> 	mov	[Show_ClusterSize], ax
  2694                              <1> 
  2695                              <1> loc_start_show_file:
  2696 00005EDF BE[20CF0000]        <1> 	mov	esi, nextline
  2697 00005EE4 E8CBE0FFFF          <1> 	call	print_msg
  2698                              <1> 
  2699 00005EE9 A1[9CDD0000]        <1> 	mov	eax, [Show_Cluster]
  2700 00005EEE C605[ACDD0000]17    <1> 	mov	byte [Show_RowCount], 23
  2701                              <1> 
  2702                              <1> 	; 17/02/2016
  2703 00005EF5 8B35[98DD0000]      <1> 	mov	esi, [Show_LDDDT]
  2704                              <1> 
  2705                              <1> loc_show_next_cluster:
  2706                              <1> 	; 15/02/2016
  2707 00005EFB BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2708                              <1> 	; ESI = Logical DOS drv description table address
  2709 00005F00 E875380000          <1> 	call	read_cluster
  2710                              <1> 	;jc	loc_file_rw_cmd_failed
  2711 00005F05 0F8273F8FFFF        <1> 	jc	loc_run_cmd_failed
  2712                              <1> 
  2713 00005F0B 31DB                <1> 	xor 	ebx, ebx
  2714                              <1> loc_show_next_byte:
  2715 00005F0D 803D[ACDD0000]00    <1> 	cmp	byte [Show_RowCount], 0
  2716 00005F14 7521                <1> 	jne	short pass_show_wait_for_key
  2717 00005F16 30E4                <1> 	xor	ah, ah
  2718 00005F18 E87FABFFFF          <1> 	call	int16h
  2719 00005F1D 3C1B                <1> 	cmp	al, 1Bh
  2720 00005F1F 750F                <1> 	jne	short pass_exit_show
  2721                              <1> end_of_show_file:
  2722                              <1> pass_show_file:
  2723 00005F21 BE[20CF0000]        <1> 	mov	esi, nextline
  2724 00005F26 E889E0FFFF          <1> 	call	print_msg
  2725 00005F2B E94D010000          <1> 	jmp	loc_file_rw_restore_retn
  2726                              <1> 
  2727                              <1> pass_exit_show:
  2728 00005F30 C605[ACDD0000]14    <1> 	mov	byte [Show_RowCount], 20
  2729                              <1> pass_show_wait_for_key:
  2730 00005F37 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2731 00005F3D 8A03                <1> 	mov	al, [ebx]
  2732 00005F3F 3C0D                <1> 	cmp	al, 0Dh
  2733 00005F41 0F8590000000        <1>         jne     loc_show_check_tab_space
  2734 00005F47 FE0D[ACDD0000]      <1> 	dec	byte [Show_RowCount]
  2735                              <1> pass_show_dec_rowcount:
  2736 00005F4D B307                <1> 	mov	bl, 7 ; (light gray character color, black background)
  2737 00005F4F 8A3D[B8D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2738 00005F55 E88EB7FFFF          <1> 	call	_write_tty
  2739                              <1> loc_show_check_eof:
  2740 00005F5A FF05[A4DD0000]      <1> 	inc	dword [Show_FilePointer]
  2741 00005F60 A1[A4DD0000]        <1> 	mov	eax, [Show_FilePointer]
  2742 00005F65 3B05[A0DD0000]      <1> 	cmp	eax, [Show_FileSize]
  2743 00005F6B 73B4                <1> 	jnb	short end_of_show_file
  2744 00005F6D 66FF05[A8DD0000]    <1> 	inc	word [Show_ClusterPointer]
  2745 00005F74 0FB71D[A8DD0000]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2746                              <1> 
  2747                              <1> 	; 17/02/2016
  2748                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2749 00005F7B 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2750 00005F80 758B                <1> 	jnz	short loc_show_next_byte
  2751                              <1> 
  2752                              <1> 	; 16/02/2016
  2753 00005F82 8B35[98DD0000]      <1> 	mov	esi, [Show_LDDDT]
  2754                              <1> 	;
  2755 00005F88 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2756 00005F8C 7719                <1> 	ja	short loc_show_check_fat_cluster_size
  2757                              <1> 
  2758                              <1> 	; Singlix FS
  2759                              <1> 	; 1 sector, more... (cluster size = 1 sector)
  2760 00005F8E A1[9CDD0000]        <1> 	mov	eax, [Show_Cluster]
  2761 00005F93 40                  <1> 	inc	eax
  2762 00005F94 A3[9CDD0000]        <1> 	mov	[Show_Cluster], eax
  2763                              <1> 
  2764 00005F99 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2765 00005F9C 0F856BFFFFFF        <1>         jnz	loc_show_next_byte
  2766 00005FA2 E954FFFFFF          <1> 	jmp     loc_show_next_cluster
  2767                              <1> 	 
  2768                              <1> loc_show_check_fat_cluster_size:
  2769                              <1> 	; 17/02/2016
  2770 00005FA7 663B1D[AADD0000]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2771 00005FAE 0F8259FFFFFF        <1>         jb	loc_show_next_byte
  2772 00005FB4 66C705[A8DD0000]00- <1> 	mov	word [Show_ClusterPointer], 0
  2772 00005FBC 00                  <1>
  2773                              <1> 
  2774 00005FBD A1[9CDD0000]        <1> 	mov	eax, [Show_Cluster]
  2775                              <1> 	;mov	esi, [Show_LDDDT]
  2776                              <1> loc_show_get_next_cluster:
  2777 00005FC2 E88F350000          <1> 	call	get_next_cluster
  2778                              <1> 	;jc	loc_file_rw_cmd_failed
  2779 00005FC7 0F82B1F7FFFF        <1> 	jc	loc_run_cmd_failed
  2780                              <1> loc_show_update_ccluster:
  2781 00005FCD A3[9CDD0000]        <1> 	mov	[Show_Cluster], eax			
  2782 00005FD2 E924FFFFFF          <1>         jmp     loc_show_next_cluster
  2783                              <1> 
  2784                              <1> loc_show_check_tab_space:
  2785 00005FD7 3C09                <1> 	cmp	al, 09h
  2786 00005FD9 0F856EFFFFFF        <1>         jne     pass_show_dec_rowcount
  2787                              <1> loc_show_put_tab_space:
  2788 00005FDF 8A3D[B8D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2789 00005FE5 E8AAB4FFFF          <1> 	call	get_cpos
  2790                              <1> 	; dl = cursor column
  2791 00005FEA 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2792                              <1> 	;shr	bh, 1 ; [ACTIVE_PAGE]
  2793 00005FED 8A3D[B8D20000]      <1> 	mov	bh, [ACTIVE_PAGE]
  2794 00005FF3 B307                <1> 	mov	bl, 7 ; color attribute
  2795                              <1> loc_show_put_space_chars:
  2796 00005FF5 B020                <1> 	mov	al, 20h ; space
  2797                              <1> 	;mov	bh, [ACTIVE_PAGE] ; [ptty]
  2798                              <1> 	;mov	bl, 7 ; color attribute
  2799 00005FF7 6652                <1> 	push	dx
  2800 00005FF9 E8EAB6FFFF          <1> 	call	_write_tty
  2801 00005FFE 665A                <1> 	pop	dx
  2802                              <1> 	; 18/02/2016
  2803 00006000 80FA07              <1> 	cmp	dl, 7
  2804 00006003 0F8351FFFFFF        <1> 	jnb	loc_show_check_eof
  2805 00006009 FEC2                <1> 	inc	dl
  2806 0000600B EBE8                <1> 	jmp	short loc_show_put_space_chars
  2807                              <1> 
  2808                              <1> check_filename:
  2809                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2810                              <1> 	; 07/08/2010 (FILE.ASM, 'proc_check_filename')
  2811                              <1> 	; 10/07/2010
  2812                              <1> 	; Derived from 'proc_check_filename'
  2813                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2814                              <1> 	;
  2815                              <1> 	; INPUT -> 
  2816                              <1> 	;	ESI = Dot File Name Location
  2817                              <1> 	; OUTPUT ->
  2818                              <1> 	;	cf = 1 -> error code in AL
  2819                              <1> 	;	     AL = 0Bh -> Invalid file name   
  2820                              <1> 	;	cf = 0 -> valid file name
  2821                              <1> 	; 
  2822                              <1> 	;(EAX, ECX, EDI will be changed)
  2823                              <1> 
  2824                              <1> check_invalid_filename_chars:
  2825                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2826                              <1> 	; 10/07/2010 (FILE.ASM, 'proc_check_invalid_filename_chars')
  2827                              <1> 	; 10/02/2010
  2828                              <1> 	; Derived from 'proc_check_invalid_filename_chars'
  2829                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2830                              <1> 	;
  2831                              <1> 	; INPUT -> 
  2832                              <1> 	;	ESI = ASCIIZ FileName
  2833                              <1> 	; OUTPUT ->
  2834                              <1> 	;	cf = 1 -> invalid
  2835                              <1> 	;	cf = 0 -> valid
  2836                              <1> 	; 
  2837                              <1> 	;(EAX, ECX, ESI, EDI will be changed)
  2838                              <1>   
  2839 0000600D 56                  <1> 	push	esi
  2840                              <1> 
  2841 0000600E BF[EBC20000]        <1>         mov     edi, invalid_fname_chars
  2842 00006013 AC                  <1> 	lodsb
  2843                              <1> check_filename_next_char:
  2844 00006014 B914000000          <1> 	mov	ecx, sizeInvFnChars
  2845 00006019 BF[EBC20000]        <1> 	mov	edi, invalid_fname_chars
  2846                              <1> loc_scan_invalid_filename_char:
  2847 0000601E AE                  <1> 	scasb 
  2848 0000601F 741F                <1> 	je	short loc_invalid_filename_stc 
  2849 00006021 E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2850 00006023 AC                  <1> 	lodsb
  2851 00006024 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2852 00006026 77EC                <1> 	ja	short check_filename_next_char
  2853                              <1> 
  2854                              <1> check_filename_dot:
  2855 00006028 8B3424              <1> 	mov	esi, [esp]
  2856                              <1> 
  2857 0000602B B421                <1> 	mov	ah, 21h
  2858 0000602D B908000000          <1> 	mov	ecx, 8
  2859                              <1> loc_check_filename_next_char:
  2860 00006032 AC                  <1> 	lodsb
  2861 00006033 3C2E                <1> 	cmp	al, 2Eh
  2862 00006035 7511                <1> 	jne	short pass_check_fn_dot_check
  2863                              <1> loc_check_filename_ext_0:
  2864 00006037 AC                  <1> 	lodsb
  2865 00006038 38E0                <1> 	cmp	al, ah ; 21h
  2866 0000603A 7205                <1> 	jb	short loc_invalid_filename
  2867 0000603C 3C2E                <1> 	cmp	al, 2Eh
  2868 0000603E 7519                <1> 	jne	short loc_check_filename_ext_1
  2869                              <1> 
  2870                              <1> loc_invalid_filename_stc:
  2871                              <1> loc_check_fn_stc_rtn:
  2872 00006040 F9                  <1> 	stc
  2873                              <1> loc_invalid_filename:
  2874 00006041 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  2875                              <1> 	; Invalid file name chars
  2876                              <1> loc_check_fn_rtn:
  2877 00006046 5E                  <1> 	pop	esi
  2878 00006047 C3                  <1> 	retn
  2879                              <1> 
  2880                              <1> pass_check_fn_dot_check:
  2881 00006048 38E0                <1> 	cmp	al, ah ; 21h
  2882 0000604A 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2883 0000604C E2E4                <1> 	loop	loc_check_filename_next_char
  2884 0000604E AC                  <1> 	lodsb
  2885 0000604F 38E0                <1> 	cmp	al, ah ; 21h
  2886 00006051 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2887 00006053 3C2E                <1> 	cmp	al, 2Eh
  2888 00006055 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2889 00006057 EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2890                              <1> 
  2891                              <1> loc_check_filename_ext_1:
  2892 00006059 AC                  <1> 	lodsb
  2893 0000605A 38E0                <1> 	cmp	al, ah ; 21h
  2894 0000605C 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2895 0000605E 3C2E                <1> 	cmp	al, 2Eh
  2896 00006060 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2897 00006062 AC                  <1> 	lodsb
  2898 00006063 38E0                <1> 	cmp	al, ah ; 21h
  2899 00006065 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2900 00006067 3C2E                <1> 	cmp	al, 2Eh
  2901 00006069 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2902 0000606B AC                  <1> 	lodsb
  2903 0000606C 38E0                <1> 	cmp	al, ah ; 21h
  2904 0000606E 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2905                              <1> 
  2906                              <1> loc_check_fn_clc_rtn:
  2907 00006070 5E                  <1> 	pop	esi
  2908 00006071 F8                  <1> 	clc
  2909 00006072 C3                  <1> 	retn
  2910                              <1> 
  2911                              <1> loc_print_deleted_message:
  2912 00006073 BE[D5C60000]        <1> 	mov	esi, Msg_Deleted
  2913 00006078 E837DFFFFF          <1> 	call	print_msg
  2914                              <1> 
  2915                              <1> 	;clc
  2916                              <1> 
  2917                              <1> loc_file_rw_restore_retn:
  2918                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2919                              <1> 	; 28/02/2010 (CMD_INTR.ASM)
  2920                              <1> loc_file_rw_cmd_failed:
  2921 0000607D 9C                  <1> 	pushf 
  2922 0000607E E855F7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2923 00006083 9D                  <1> 	popf
  2924 00006084 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2925 00006086 C3                  <1> 	retn
  2926                              <1> 
  2927                              <1> loc_permission_denied:
  2928                              <1> 	; 27/02/2016
  2929 00006087 BE[E2C60000]        <1> 	mov	esi, Msg_Permission_Denied
  2930 0000608C E823DFFFFF          <1> 	call	print_msg
  2931 00006091 EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2932                              <1> 
  2933                              <1> loc_file_rw_check_write_fault:
  2934 00006093 3C1D                <1> 	cmp	al, 1Dh ; Write Fault
  2935 00006095 0F85E8F6FFFF        <1>         jne     loc_run_cmd_failed_cmp_al
  2936 0000609B BE[CCC40000]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2937                              <1> 	;call	print_msg
  2938                              <1> 	;retn
  2939 000060A0 E90FDFFFFF          <1> 	jmp	print_msg
  2940                              <1> 
  2941                              <1> make_directory:
  2942                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2943                              <1> 	; 12/03/2011 (CMD_INTR.ASM, 'cmp_cmd_mkdir')
  2944                              <1> 	; 14/08/2010
  2945                              <1> 	; 10/07/2010
  2946                              <1> 	; 29/11/2009
  2947                              <1> 	;
  2948                              <1> get_mkdir_fchar:
  2949                              <1> 	; esi = directory name
  2950 000060A5 803E20              <1> 	cmp	byte [esi], 20h
  2951 000060A8 7701                <1>         ja	short loc_mkdir_parse_path_name
  2952                              <1> 
  2953                              <1> loc_mkdir_nodirname_retn:
  2954 000060AA C3                  <1> 	retn
  2955                              <1> 
  2956                              <1> loc_mkdir_parse_path_name:
  2957 000060AB BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  2958 000060B0 E8AA1D0000          <1>         call    parse_path_name
  2959 000060B5 0F8298F6FFFF        <1> 	jc	loc_cmd_failed
  2960                              <1> 
  2961                              <1> loc_mkdir_check_dirname_exists:
  2962 000060BB BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  2963 000060C0 803E20              <1> 	cmp	byte [esi], 20h
  2964 000060C3 0F868AF6FFFF        <1> 	jna	loc_cmd_failed
  2965 000060C9 8935[B0DD0000]      <1> 	mov	[DelFile_FNPointer], esi
  2966 000060CF E839FFFFFF          <1> 	call	check_filename
  2967 000060D4 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  2968                              <1> 
  2969                              <1> loc_mkdir_drv:
  2970 000060D6 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  2971 000060DC 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  2972                              <1> 	
  2973 000060E2 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  2974 000060E8 38F2                <1> 	cmp	dl, dh
  2975 000060EA 7407                <1> 	je	short loc_mkdir_change_directory
  2976                              <1> 
  2977 000060EC E8C8E7FFFF          <1> 	call	change_current_drive
  2978 000060F1 728A                <1> 	jc	loc_file_rw_cmd_failed
  2979                              <1> 
  2980                              <1> loc_mkdir_change_directory:
  2981 000060F3 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2982 000060FA 7614                <1> 	jna	short loc_mkdir_find_directory
  2983                              <1> 
  2984 000060FC FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2985 00006102 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  2986 00006107 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2987 00006109 E83D170000          <1> 	call	change_current_directory
  2988 0000610E 722E                <1> 	jc	short loc_mkdir_check_error_code
  2989                              <1> 
  2990                              <1> ;loc_mkdir_change_prompt_dir_string:
  2991                              <1> 	;call	change_prompt_dir_string
  2992                              <1> 
  2993                              <1> loc_mkdir_find_directory:
  2994                              <1> 	;mov	esi, FindFile_Name
  2995 00006110 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  2996                              <1> 	;xor	eax, eax
  2997 00006116 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  2998 00006119 E837FBFFFF          <1> 	call	find_first_file
  2999 0000611E 721E                <1> 	jc	short loc_mkdir_check_error_code
  3000                              <1> 
  3001                              <1> loc_mkdir_directory_found:
  3002 00006120 BE[2DC60000]        <1> 	mov	esi, Msg_Name_Exists
  3003 00006125 E88ADEFFFF          <1> 	call	print_msg
  3004                              <1> 
  3005 0000612A E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3006                              <1> 
  3007                              <1> loc_mkdir_invalid_dir_name_chars:
  3008 0000612F BE[00C60000]        <1> 	mov	esi, Msg_invalid_name_chars
  3009 00006134 E87BDEFFFF          <1> 	call	print_msg
  3010                              <1> 
  3011 00006139 E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3012                              <1> 
  3013                              <1> loc_mkdir_check_error_code:
  3014 0000613E 3C02                <1> 	cmp	al, 2
  3015                              <1> 	;je	short loc_mkdir_directory_not_found
  3016 00006140 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  3017 00006142 F9                  <1> 	stc
  3018 00006143 E935FFFFFF          <1>         jmp     loc_file_rw_cmd_failed
  3019                              <1> 
  3020                              <1> loc_mkdir_directory_not_found:
  3021                              <1> loc_mkdir_ask_for_yes_no:
  3022 00006148 BE[4EC60000]        <1> 	mov	esi, Msg_DoYouWantMkdir
  3023 0000614D E862DEFFFF          <1> 	call	print_msg
  3024 00006152 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3025 00006158 E857DEFFFF          <1> 	call	print_msg
  3026 0000615D BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  3027 00006162 E84DDEFFFF          <1> 	call	print_msg
  3028                              <1> 
  3029 00006167 C605[77C60000]20    <1> 	mov	byte [Y_N_nextline], 20h
  3030                              <1> 
  3031                              <1> loc_mkdir_ask_again:
  3032 0000616E 30E4                <1> 	xor	ah, ah
  3033 00006170 E827A9FFFF          <1> 	call	int16h
  3034 00006175 3C1B                <1> 	cmp	al, 1Bh
  3035                              <1> 	;je	short loc_do_not_make_directory
  3036 00006177 7447                <1> 	je	short loc_mkdir_y_n_escape
  3037 00006179 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  3038 0000617B 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  3039 0000617D 7404                <1> 	je	short loc_mkdir_yes_make_directory
  3040 0000617F 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3041 00006181 75EB                <1> 	jne	short loc_mkdir_ask_again
  3042                              <1> 
  3043                              <1> loc_do_not_make_directory:
  3044                              <1> loc_mkdir_yes_make_directory:
  3045 00006183 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  3046 00006188 6650                <1> 	push	ax
  3047 0000618A BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  3048 0000618F E820DEFFFF          <1> 	call	print_msg
  3049 00006194 6658                <1> 	pop	ax
  3050                              <1> 	;cmp	al, 'Y' ; 'yes'
  3051                              <1> 	;cmc
  3052                              <1>         ;jnc	loc_file_rw_restore_retn
  3053 00006196 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3054 00006198 0F84DFFEFFFF        <1>         je	loc_file_rw_restore_retn  
  3055                              <1> 
  3056                              <1> loc_mkdir_call_make_sub_directory:
  3057 0000619E 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3058 000061A4 B110                <1> 	mov	cl, 10h ; Directory attributes 
  3059 000061A6 E8B31D0000          <1> 	call	make_sub_directory
  3060                              <1> loc_rename_file_ok: ; 06/03/2016
  3061 000061AB 0F82CCFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  3062                              <1> move_source_file_to_destination_OK:
  3063 000061B1 BE[7BC60000]        <1> 	mov	esi, Msg_OK
  3064 000061B6 E8F9DDFFFF          <1> 	call	print_msg
  3065 000061BB E9BDFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3066                              <1> 
  3067                              <1> loc_mkdir_y_n_escape:
  3068 000061C0 B04E                <1> 	mov	al, 'N' ; 'no'
  3069 000061C2 EBBF                <1> 	jmp	short loc_do_not_make_directory
  3070                              <1> 
  3071                              <1> delete_directory:
  3072                              <1> 	; 06/03/2016
  3073                              <1> 	; 01/03/2016
  3074                              <1> 	; 29/02/2016
  3075                              <1> 	; 28/02/2016
  3076                              <1> 	; 27/02/2016
  3077                              <1> 	; 26/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3078                              <1> 	; 16/10/2010 (CMD_INTR.ASM, 'cmp_cmd_rmdir')
  3079                              <1> 	; 05/06/2010
  3080                              <1> 	;
  3081                              <1> get_rmdir_fchar:
  3082                              <1> 	; esi = directory name
  3083 000061C4 803E20              <1> 	cmp	byte [esi], 20h
  3084 000061C7 7701                <1>         ja	short loc_rmdir_parse_path_name
  3085                              <1> 
  3086                              <1> loc_rmdir_nodirname_retn:
  3087 000061C9 C3                  <1> 	retn
  3088                              <1> 
  3089                              <1> loc_rmdir_parse_path_name:
  3090 000061CA BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  3091 000061CF E88B1C0000          <1> 	call	parse_path_name
  3092 000061D4 0F8279F5FFFF        <1> 	jc	loc_cmd_failed
  3093                              <1> 
  3094                              <1> loc_rmdir_check_dirname_exists:
  3095 000061DA BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3096 000061DF 803E20              <1> 	cmp	byte [esi], 20h
  3097 000061E2 0F866BF5FFFF        <1> 	jna	loc_cmd_failed
  3098 000061E8 8935[B0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3099                              <1> 
  3100                              <1> loc_rmdir_drv:
  3101 000061EE 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  3102 000061F4 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3103                              <1> 
  3104 000061FA 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  3105 00006200 38F2                <1> 	cmp	dl, dh
  3106 00006202 740B                <1> 	je	short loc_rmdir_change_directory
  3107                              <1> 
  3108 00006204 E8B0E6FFFF          <1> 	call	change_current_drive
  3109 00006209 0F826EFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3110                              <1> 
  3111                              <1> loc_rmdir_change_directory:
  3112 0000620F 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3113 00006216 7614                <1> 	jna	short loc_rmdir_find_directory
  3114                              <1> 
  3115 00006218 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3116 0000621E BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  3117 00006223 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3118 00006225 E821160000          <1> 	call	change_current_directory
  3119 0000622A 7211                <1> 	jc	short loc_rmdir_check_error_code
  3120                              <1> 
  3121                              <1> ;loc_rmdir_change_prompt_dir_string:
  3122                              <1> 	;call	change_prompt_dir_string
  3123                              <1> 
  3124                              <1> loc_rmdir_find_directory:
  3125                              <1> 	;mov	esi, FindFile_Name
  3126 0000622C 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3127 00006232 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3128 00006236 E81AFAFFFF          <1> 	call	find_first_file
  3129 0000623B 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3130                              <1> 
  3131                              <1> loc_rmdir_check_error_code:
  3132 0000623D 3C02                <1> 	cmp	al, 2
  3133 0000623F 740B                <1> 	je	short loc_rmdir_directory_not_found
  3134 00006241 F9                  <1> 	stc
  3135 00006242 E936FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3136                              <1> 
  3137                              <1> loc_rmdir_ambgfn_check:
  3138 00006247 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3139 0000624A 740F                <1> 	jz	short loc_rmdir_directory_found
  3140                              <1> 
  3141                              <1> loc_rmdir_directory_not_found:
  3142 0000624C BE[EEC40000]        <1> 	mov	esi, Msg_Dir_Not_Found
  3143 00006251 E85EDDFFFF          <1> 	call	print_msg
  3144                              <1> 
  3145 00006256 E922FEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3146                              <1> 
  3147                              <1> loc_rmdir_directory_found:
  3148 0000625B 80E307              <1> 	and	bl, 07h ; Attributes
  3149 0000625E 0F8523FEFFFF        <1> 	jnz	loc_permission_denied
  3150                              <1> 
  3151                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3152                              <1>        ;mov	bh, [LongName_EntryLength]
  3153 00006264 883D[BADD0000]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3154                              <1> 	; edi = Directory Entry Offset (DirBuff)
  3155                              <1> 	; esi = Directory Entry (FFF Structure)
  3156                              <1> 	;mov	[DelFile_DirEntryAddr], edi ; not required
  3157                              <1> 	;mov	ax, [edi+20] ; First Cluster High Word
  3158                              <1>         ;shl	eax, 16
  3159                              <1> 	;mov	ax, [edi+26] ; First Cluster Low Word
  3160                              <1> 	; ROOT Dir First Cluster = 0
  3161                              <1>         ;cmp	eax, 2
  3162                              <1> 	;jb	loc_update_direntry_1
  3163                              <1> 
  3164                              <1> pass_rmdir_fc_check:
  3165 0000626A 57                  <1> 	push	edi ; * (29/02/2016)
  3166                              <1> 
  3167 0000626B BE[81C60000]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3168 00006270 E83FDDFFFF          <1> 	call	print_msg
  3169 00006275 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3170 0000627B E834DDFFFF          <1> 	call	print_msg
  3171 00006280 BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  3172 00006285 E82ADDFFFF          <1> 	call	print_msg
  3173                              <1> 
  3174                              <1> loc_rmdir_ask_again:
  3175 0000628A 30E4                <1> 	xor	ah, ah
  3176 0000628C E80BA8FFFF          <1> 	call	int16h
  3177 00006291 3C1B                <1> 	cmp	al, 1Bh
  3178                              <1> 	;je	short loc_do_not_delete_directory
  3179 00006293 0F8498000000        <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3180 00006299 24DF                <1> 	and	al, 0DFh
  3181 0000629B A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  3182 000062A0 3C59                <1> 	cmp	al, 'Y'
  3183 000062A2 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3184 000062A4 3C4E                <1> 	cmp	al, 'N'
  3185 000062A6 75E2                <1> 	jne	short loc_rmdir_ask_again
  3186                              <1> 
  3187                              <1> loc_do_not_delete_directory:
  3188                              <1> loc_rmdir_yes_delete_directory:
  3189 000062A8 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  3190 000062AD 6650                <1> 	push	ax
  3191 000062AF BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  3192 000062B4 E8FBDCFFFF          <1> 	call	print_msg
  3193 000062B9 6658                <1> 	pop	ax
  3194 000062BB 5F                  <1> 	pop	edi ; * (29/02/2016)
  3195                              <1> 	;cmp	al, 'Y' ; 'yes'
  3196                              <1> 	;cmc
  3197                              <1>         ;jnc	loc_file_rw_restore_retn
  3198 000062BC 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3199 000062BE 0F84B9FDFFFF        <1>         je	loc_file_rw_restore_retn  
  3200                              <1> 
  3201                              <1> loc_rmdir_delete_short_name_check_dir_empty:
  3202                              <1> 	; EDI = Directory buffer entry offset/address 
  3203 000062C4 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3204 000062C8 C1E010              <1>         shl	eax, 16
  3205 000062CB 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3206                              <1> 
  3207 000062CF A3[B4DD0000]        <1> 	mov 	[DelFile_FCluster], eax
  3208                              <1> 
  3209                              <1> 	;mov	bx, [DirBuff_EntryCounter]
  3210 000062D4 668B1D[6CDD0000]    <1> 	mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3211 000062DB 66891D[B8DD0000]    <1> 	mov	[DelFile_EntryCounter], bx
  3212                              <1> 
  3213 000062E2 29DB                <1>     	sub	ebx, ebx
  3214 000062E4 8A3D[F2DC0000]      <1> 	mov	bh, [FindFile_Drv]
  3215 000062EA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3216 000062EF 01DE                <1> 	add	esi, ebx
  3217                              <1> 
  3218 000062F1 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3219 000062F7 743F                <1> 	je	short loc_rmdir_delete_fs_directory
  3220                              <1> 
  3221                              <1> 	;cmp	byte [esi+LD_FATType], 1
  3222                              <1> 	;jnb	short loc_rmdir_get__last_cluster_0
  3223                              <1> 	;mov	eax, 0Bh ; Invalid Format
  3224                              <1> 	;jmp	loc_file_rw_cmd_failed
  3225                              <1>   
  3226                              <1> ;loc_rmdir_get_last_cluster_0:
  3227 000062F9 8B15[7DDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  3228 000062FF 8915[E4DD0000]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3229                              <1> 
  3230 00006305 893D[E0DD0000]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3231                              <1> 
  3232                              <1> 	; 01/03/2016
  3233 0000630B C705[6EDB0000]0000- <1> 	mov	dword [FAT_ClusterCounter], 0 ; Reset
  3233 00006313 0000                <1>
  3234                              <1> 
  3235                              <1> loc_rmdir_get_last_cluster:
  3236 00006315 E8373A0000          <1> 	call	get_last_cluster
  3237 0000631A 0F82B8000000        <1>         jc      loc_rmdir_cmd_failed
  3238                              <1> 	
  3239 00006320 3B05[B4DD0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3240 00006326 752F                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3241                              <1> 
  3242 00006328 C605[DFDD0000]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3243 0000632F EB2D                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3244                              <1> 
  3245                              <1> loc_rmdir_y_n_escape:
  3246 00006331 B04E                <1> 	mov	al, 'N' ; 'no'
  3247 00006333 E970FFFFFF          <1>         jmp     loc_do_not_delete_directory
  3248                              <1> 
  3249                              <1> loc_rmdir_delete_fs_directory:
  3250 00006338 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3251 0000633C 0F8545FDFFFF        <1> 	jne	loc_permission_denied
  3252                              <1> 
  3253 00006342 E821140000          <1> 	call	delete_fs_directory
  3254 00006347 0F8326FDFFFF        <1> 	jnc	loc_print_deleted_message
  3255                              <1> 
  3256 0000634D 09C0                <1> 	or	eax, eax
  3257 0000634F 745D                <1> 	jz	loc_rmdir_directory_not_empty_2         
  3258 00006351 F9                  <1> 	stc
  3259 00006352 E926FDFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3260                              <1>  
  3261                              <1> loc_rmdir_multi_dir_clusters:
  3262 00006357 C605[DFDD0000]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3263                              <1> 
  3264                              <1> pass_rmdir_multi_dir_clusters:
  3265 0000635E A3[E8DD0000]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3266 00006363 890D[ECDD0000]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3267                              <1> 
  3268                              <1> loc_rmdir_load_fat_sub_directory:
  3269 00006369 E8CE330000          <1> 	call	load_FAT_sub_directory
  3270 0000636E 7268                <1> 	jc	loc_rmdir_cmd_failed
  3271                              <1> 
  3272                              <1> loc_rmdir_find_last_dir_entry:
  3273 00006370 56                  <1> 	push	esi
  3274 00006371 BE[D6DC0000]        <1> 	mov	esi, Dir_File_Name
  3275 00006376 C6062A              <1> 	mov	byte [esi], '*'
  3276 00006379 C646082A            <1> 	mov	byte [esi+8], '*'
  3277 0000637D 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3278                              <1> loc_rmdir_find_last_dir_entry_next:
  3279 0000637F 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3280 00006383 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3281 00006386 E816180000          <1> 	call	find_directory_entry
  3282 0000638B 7271                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3283 0000638D 83FB01              <1> 	cmp	ebx, 1
  3284 00006390 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3285                              <1> loc_rmdir_dot_entry_check:
  3286 00006392 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3287 00006395 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3288 00006397 08DB                <1> 	or	bl, bl
  3289 00006399 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3290 0000639B 807F0120            <1> 	cmp	byte [edi+1], 20h
  3291 0000639F EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3292                              <1> 
  3293                              <1> loc_rmdir_dotdot_entry_check:
  3294 000063A1 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3295                              <1> pass_rmdir_dot_entry_check:	
  3296 000063A7 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3297 000063A9 FEC3                <1> 	inc	bl
  3298 000063AB EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3299                              <1> 
  3300                              <1> 
  3301                              <1> loc_rmdir_directory_not_empty_1:
  3302 000063AD 58                  <1> 	pop	eax ; pushed esi 
  3303                              <1> 
  3304                              <1> loc_rmdir_directory_not_empty_2:
  3305 000063AE BE[A2C60000]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3306 000063B3 E8FCDBFFFF          <1> 	call	print_msg
  3307                              <1> 	; 01/03/2016
  3308 000063B8 A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3309 000063BD 09C0                <1> 	or	eax, eax ; 0 ?
  3310 000063BF 0F84B8FCFFFF        <1> 	jz	loc_file_rw_restore_retn
  3311                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3312                              <1> 
  3313 000063C5 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3314                              <1> 	           ; BL = 1 -> add free clusters
  3315 000063C9 E804380000          <1> 	call	calculate_fat_freespace
  3316 000063CE 09C9                <1> 	or	ecx, ecx
  3317 000063D0 0F84A7FCFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3318                              <1> 	; ecx > 0 -> Error (Recalculation is neeeded)
  3319 000063D6 EB0E                <1> 	jmp	short loc_rmdir_cmd_return
  3320                              <1> 
  3321                              <1> 
  3322                              <1> loc_rmdir_cmd_failed:
  3323 000063D8 833D[6EDB0000]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3324 000063DF 0F8298FCFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3325 000063E5 F9                  <1> 	stc
  3326                              <1> loc_rmdir_cmd_return:
  3327                              <1> 	; 01/03/2016
  3328 000063E6 9C                  <1> 	pushf
  3329                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3330 000063E7 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3331                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3332 000063EB 50                  <1> 	push	eax
  3333 000063EC E8E1370000          <1> 	call	calculate_fat_freespace	
  3334 000063F1 58                  <1> 	pop	eax
  3335 000063F2 9D                  <1> 	popf
  3336 000063F3 0F8284FCFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3337 000063F9 E97FFCFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3338                              <1> 
  3339                              <1> 
  3340                              <1> loc_rmdir_empty_dir_cluster:
  3341 000063FE 5E                  <1> 	pop	esi
  3342                              <1> 
  3343                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3344 000063FF 803D[DFDD0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3345 00006406 761D                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3346                              <1> 
  3347 00006408 A1[ECDD0000]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3348                              <1> 	;xor	ecx, ecx
  3349 0000640D 49                  <1> 	dec	ecx ; FFFFFFFFh
  3350 0000640E E86D340000          <1> 	call	update_cluster
  3351 00006413 7310                <1> 	jnc	short loc_rmdir_unlink_dir_last_cluster
  3352                              <1> 
  3353                              <1> loc_rmdir_unlink_stc_retn:
  3354                              <1> 	; 01/03/2016
  3355 00006415 83F801              <1> 	cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3356 00006418 F5                  <1> 	cmc 
  3357 00006419 72BD                <1> 	jc	short loc_rmdir_cmd_failed
  3358 0000641B EB1D                <1> 	jmp	short loc_rmdir_save_fat_buffer 
  3359                              <1> 	
  3360                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3361 0000641D B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  3362 00006422 F9                  <1> 	stc
  3363 00006423 EBB3                <1> 	jmp	short loc_rmdir_cmd_failed
  3364                              <1>  
  3365                              <1> loc_rmdir_unlink_dir_last_cluster:
  3366 00006425 A1[E8DD0000]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3367 0000642A 31C9                <1> 	xor	ecx, ecx ; 0
  3368 0000642C E84F340000          <1> 	call	update_cluster
  3369 00006431 73EA                <1> 	jnc	short loc_rmdir_unlink_stc_retn_0Bh
  3370                              <1> 	; Because of it is the last cluster
  3371                              <1> 	; 'update_cluster' must return with eocc error 
  3372 00006433 09C0                <1> 	or	eax, eax
  3373 00006435 7403                <1> 	jz	short loc_rmdir_save_fat_buffer ; eocc	
  3374 00006437 F9                  <1> 	stc
  3375 00006438 EB9E                <1>         jmp     short loc_rmdir_cmd_failed
  3376                              <1> 	 
  3377                              <1> loc_rmdir_save_fat_buffer:
  3378 0000643A 803D[66DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3379 00006441 7525                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3380 00006443 E8F5360000          <1> 	call	save_fat_buffer
  3381 00006448 728E                <1> 	jc	short loc_rmdir_cmd_failed
  3382                              <1> 
  3383                              <1> 	; 01/03/2016
  3384 0000644A 803D[DFDD0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3385 00006451 7615                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3386                              <1> 
  3387 00006453 A1[B4DD0000]        <1> 	mov	eax, [DelFile_FCluster]
  3388 00006458 E9B8FEFFFF          <1>         jmp     loc_rmdir_get_last_cluster
  3389                              <1> 
  3390                              <1> loc_rmdir_delete_short_name_invalid_data:
  3391 0000645D B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  3392 00006462 F9                  <1> 	stc
  3393 00006463 E970FFFFFF          <1>         jmp     loc_rmdir_cmd_failed
  3394                              <1> 
  3395                              <1> loc_rmdir_calculate_FAT_freespace:
  3396 00006468 A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3397 0000646D 66BB01FF            <1> 	mov	bx, 0FF01h
  3398                              <1> 	; BL = 1 -> Add EAX to free space count
  3399                              <1> 	; BH = FFh ->
  3400                              <1> 	; ESI = Logical DOS Drive Description Table address
  3401 00006471 E85C370000          <1> 	call	calculate_fat_freespace
  3402                              <1> 
  3403 00006476 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3404 00006478 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3405                              <1> 
  3406                              <1> loc_rmdir_recalculate_FAT_freespace:
  3407 0000647A 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3408 0000647E E84F370000          <1> 	call	calculate_fat_freespace
  3409                              <1> 	          
  3410                              <1> loc_rmdir_delete_short_name_continue:
  3411 00006483 A1[E4DD0000]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3412 00006488 83F802              <1> 	cmp	eax, 2
  3413 0000648B 730D                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3414 0000648D E81F320000          <1> 	call	load_FAT_root_directory
  3415 00006492 0F82E5FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3416 00006498 EB0B                <1> 	jmp	short loc_rmdir_del_short_name_ld_chk_fclust
  3417                              <1> 
  3418                              <1> loc_rmdir_del_short_name_load_sub_dir:	
  3419 0000649A E89D320000          <1> 	call	load_FAT_sub_directory
  3420 0000649F 0F82D8FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3421                              <1> 
  3422                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3423 000064A5 0FB73D[E0DD0000]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3424 000064AC 81C700000800        <1> 	add	edi, Directory_Buffer
  3425                              <1> 
  3426 000064B2 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3427 000064B6 C1E010              <1> 	shl	eax, 16
  3428 000064B9 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3429                              <1>         ; Not necessary... 
  3430 000064BD 3B05[B4DD0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3431 000064C3 7598                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3432                              <1> 	;
  3433 000064C5 C607E5              <1> 	mov	byte [edi], 0E5h ; 'Deleted' sign
  3434                              <1> 	; 27/02/2016
  3435                              <1> 	; TRDOS v1 has a bug here! it does not set
  3436                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3437                              <1> 	; 'save_directory_buffer' would not save the change ! 
  3438 000064C8 C605[78DB0000]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3439                              <1> 	;
  3440 000064CF E8EF1D0000          <1> 	call	save_directory_buffer
  3441 000064D4 0F82A3FBFFFF        <1> 	jc	loc_file_rw_cmd_failed 
  3442                              <1> 
  3443                              <1> loc_rmdir_del_long_name:
  3444 000064DA 0FB615[BADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3445 000064E1 08D2                <1> 	or	dl, dl
  3446 000064E3 7414                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3447                              <1>              
  3448 000064E5 0FB705[B8DD0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3449 000064EC 29D0                <1> 	sub	eax, edx
  3450 000064EE 0F8289FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3451                              <1>  
  3452                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3453 000064F4 E82A1F0000          <1> 	call	delete_longname
  3454                              <1> 	;jc	short loc_file_rw_cmd_failed
  3455                              <1> 
  3456                              <1> loc_rmdir_update_parent_dir_lmdt:
  3457 000064F9 E8601E0000          <1> 	call	update_parent_dir_lmdt
  3458                              <1> 	;jc	short loc_file_rw_cmd_failed
  3459                              <1> 
  3460                              <1> loc_rmdir_ok:
  3461 000064FE BE[7BC60000]        <1> 	mov	esi, Msg_OK
  3462 00006503 E8ACDAFFFF          <1> 	call	print_msg
  3463 00006508 E970FBFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3464                              <1> 
  3465                              <1> 
  3466                              <1> delete_file:
  3467                              <1> 	; 29/02/2016
  3468                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3469                              <1> 	; 09/08/2010 (CMD_INTR.ASM, 'cmp_cmd_del')
  3470                              <1> 	; 28/02/2010
  3471                              <1> 
  3472                              <1> get_delfile_fchar:
  3473                              <1> 	; esi = file name
  3474 0000650D 803E20              <1> 	cmp	byte [esi], 20h
  3475 00006510 7701                <1>         ja	short loc_delfile_parse_path_name
  3476                              <1> 
  3477                              <1> loc_delfile_nofilename_retn:
  3478 00006512 C3                  <1> 	retn
  3479                              <1> 
  3480                              <1> loc_delfile_parse_path_name:
  3481 00006513 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  3482 00006518 E842190000          <1> 	call	parse_path_name
  3483 0000651D 0F8230F2FFFF        <1> 	jc	loc_cmd_failed
  3484                              <1> 
  3485                              <1> loc_delfile_check_filename_exists:
  3486 00006523 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3487 00006528 803E20              <1> 	cmp	byte [esi], 20h
  3488 0000652B 0F8622F2FFFF        <1> 	jna	loc_cmd_failed
  3489 00006531 8935[B0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3490                              <1> 
  3491                              <1> loc_delfile_drv:
  3492 00006537 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  3493 0000653D 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  3494 00006543 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3495 00006549 38F2                <1> 	cmp	dl, dh
  3496 0000654B 740B                <1> 	je	short loc_delfile_change_directory
  3497                              <1> 
  3498 0000654D E867E3FFFF          <1> 	call	change_current_drive
  3499 00006552 0F8225FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3500                              <1> 
  3501                              <1> loc_delfile_change_directory:
  3502 00006558 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3503 0000655F 7618                <1> 	jna	short loc_delfile_find
  3504                              <1> 
  3505 00006561 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3506 00006567 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  3507 0000656C 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3508 0000656E E8D8120000          <1> 	call	change_current_directory
  3509 00006573 0F8204FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3510                              <1> 
  3511                              <1> ;loc_delfile_change_prompt_dir_string:
  3512                              <1> 	;call	change_prompt_dir_string
  3513                              <1> 
  3514                              <1> loc_delfile_find:
  3515                              <1> 	;mov	esi, FindFile_Name
  3516 00006579 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3517 0000657F 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3518 00006583 E8CDF6FFFF          <1> 	call	find_first_file
  3519 00006588 0F82EFFAFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3520                              <1> 
  3521                              <1> loc_delfile_ambgfn_check:
  3522 0000658E 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3523 00006591 740B                <1> 	jz	short loc_delfile_found
  3524                              <1> 
  3525                              <1> loc_file_not_found:
  3526 00006593 B802000000          <1> 	mov	eax, 2 ; File not found sign
  3527 00006598 F9                  <1> 	stc
  3528 00006599 E9DFFAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3529                              <1> 
  3530                              <1> loc_delfile_found:
  3531 0000659E 80E307              <1> 	and	bl, 07h ; Attributes
  3532 000065A1 0F85E0FAFFFF        <1>         jnz     loc_permission_denied
  3533                              <1> 
  3534                              <1> ;loc_delfile_found_save_lnel:
  3535                              <1> ;	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3536                              <1> 
  3537                              <1> loc_delfile_ask_for_delete:
  3538 000065A7 57                  <1> 	push	edi ; * (29/02/2016)
  3539                              <1> 
  3540 000065A8 BE[B9C60000]        <1> 	mov	esi, Msg_DoYouWantDelete
  3541 000065AD E802DAFFFF          <1> 	call	print_msg
  3542 000065B2 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3543 000065B8 E8F7D9FFFF          <1> 	call	print_msg
  3544 000065BD BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  3545 000065C2 E8EDD9FFFF          <1> 	call	print_msg
  3546                              <1> 
  3547                              <1> loc_delfile_ask_again:
  3548 000065C7 30E4                <1> 	xor	ah, ah
  3549 000065C9 E8CEA4FFFF          <1> 	call	int16h
  3550 000065CE 3C1B                <1> 	cmp	al, 1Bh
  3551                              <1> 	;je	short loc_do_not_delete_file
  3552 000065D0 7457                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3553 000065D2 24DF                <1> 	and	al, 0DFh
  3554 000065D4 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  3555 000065D9 3C59                <1> 	cmp	al, 'Y'
  3556 000065DB 7404                <1> 	je	short loc_yes_delete_file
  3557 000065DD 3C4E                <1> 	cmp	al, 'N'
  3558 000065DF 75E6                <1> 	jne	short loc_delfile_ask_again
  3559                              <1> 
  3560                              <1> loc_do_not_delete_file:
  3561                              <1> loc_yes_delete_file:
  3562 000065E1 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  3563 000065E6 6650                <1> 	push	ax
  3564 000065E8 BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  3565 000065ED E8C2D9FFFF          <1> 	call	print_msg
  3566 000065F2 6658                <1> 	pop	ax
  3567 000065F4 5F                  <1> 	pop	edi ; * (29/02/2016)
  3568                              <1> 	;cmp	al, 'Y' ; 'yes'
  3569                              <1> 	;cmc
  3570                              <1>         ;jnc	loc_file_rw_restore_retn
  3571 000065F5 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3572 000065F7 0F8480FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3573                              <1> 
  3574                              <1> loc_delete_file:
  3575 000065FD 8A3D[F2DC0000]      <1> 	mov	bh, [FindFile_Drv]
  3576                              <1> 	;mov	bl, [DelFile_LNEL]
  3577 00006603 8A1D[41DD0000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3578                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3579 00006609 668B0D[6CDD0000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3580                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3581 00006610 E8F81F0000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3582 00006615 0F8358FAFFFF        <1> 	jnc	loc_print_deleted_message
  3583                              <1> 
  3584 0000661B 3C05                <1> 	cmp	al, 05h
  3585 0000661D 0F8464FAFFFF        <1> 	je	loc_permission_denied
  3586 00006623 F9                  <1> 	stc
  3587 00006624 E954FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3588                              <1> 
  3589                              <1> loc_delfile_y_n_escape:
  3590 00006629 B04E                <1> 	mov	al, 'N' ; 'no'
  3591 0000662B EBB4                <1> 	jmp	short loc_do_not_delete_file
  3592                              <1> 
  3593                              <1> set_file_attributes:
  3594                              <1> 	; 06/03/2016
  3595                              <1> 	; 04/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3596                              <1> 	; 10/07/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_attrib')
  3597                              <1> 	; 23/05/2010 
  3598                              <1> 	; 17/12/2000 (P2000.ASM)
  3599                              <1> 
  3600                              <1> 	; esi = file or directory name
  3601 0000662D 6631C0              <1> 	xor	ax, ax
  3602 00006630 66A3[0AC70000]      <1> 	mov	[Attr_Chars], ax
  3603 00006636 A2[08DE0000]        <1> 	mov	[Attributes], al
  3604                              <1> 
  3605                              <1> get_attrib_fchar:
  3606                              <1> 	; esi = file name
  3607 0000663B 8A06                <1> 	mov	al, [esi]
  3608 0000663D 3C20                <1> 	cmp	al, 20h
  3609 0000663F 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3610                              <1> 
  3611                              <1> loc_scan_attrib_params:
  3612 00006641 3C2D                <1> 	cmp	al, '-'
  3613 00006643 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3614 00006649 7408                <1> 	je	short loc_attr_space
  3615                              <1> 
  3616 0000664B 3C2B                <1> 	cmp	al, '+'
  3617 0000664D 0F8500F1FFFF        <1> 	jne	loc_cmd_failed
  3618                              <1> 
  3619                              <1> loc_attr_space:
  3620 00006653 8A6601              <1> 	mov	ah, [esi+1]
  3621 00006656 80FC20              <1>  	cmp	ah, 20h
  3622 00006659 770A                <1> 	ja	short pass_attr_space
  3623 0000665B 0F82F2F0FFFF        <1> 	jb	loc_cmd_failed
  3624 00006661 46                  <1> 	inc	esi
  3625 00006662 EBEF                <1> 	jmp	short loc_attr_space
  3626                              <1> 
  3627                              <1> loc_attr_file_nofilename_retn:
  3628 00006664 C3                  <1> 	retn
  3629                              <1> 
  3630                              <1> pass_attr_space:
  3631 00006665 80E4DF              <1> 	and	ah, 0DFh
  3632 00006668 80FC53              <1> 	cmp	ah, 'S'
  3633 0000666B 0F87E2F0FFFF        <1> 	ja	loc_cmd_failed
  3634 00006671 7204                <1> 	jb	short pass_attr_system
  3635 00006673 B404                <1> 	mov	ah, 04h   ; System
  3636 00006675 EB21                <1> 	jmp	short pass_attr_archive
  3637                              <1> 
  3638                              <1> pass_attr_system:
  3639 00006677 80FC48              <1> 	cmp	ah, 'H'
  3640 0000667A 7706                <1> 	ja	short pass_attr_hidden
  3641 0000667C 7213                <1> 	jb	short pass_attr_read_only
  3642 0000667E B402                <1> 	mov	ah, 02h    ; Hidden
  3643 00006680 EB16                <1> 	jmp	short pass_attr_archive
  3644                              <1> 
  3645                              <1> pass_attr_hidden:
  3646 00006682 80FC52              <1> 	cmp	ah, 'R'
  3647 00006685 0F87C8F0FFFF        <1> 	ja	loc_cmd_failed
  3648 0000668B 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3649 0000668D B401                <1> 	mov	ah, 01h
  3650 0000668F EB07                <1> 	jmp	short pass_attr_archive
  3651                              <1> 
  3652                              <1> pass_attr_read_only:
  3653 00006691 80FC41              <1> 	cmp	ah, 'A'
  3654 00006694 753B                <1> 	jne	short loc_chk_attr_enter
  3655 00006696 B420                <1> 	mov	ah, 20h    ; Archive
  3656                              <1> 
  3657                              <1> pass_attr_archive:
  3658 00006698 3C2D                <1> 	cmp	al, '-'
  3659 0000669A 7508                <1> 	jne	short pass_reducing_attributes
  3660 0000669C 0825[0AC70000]      <1> 	or	[Attr_Chars], ah
  3661 000066A2 EB06                <1> 	jmp	short loc_change_attributes_inc
  3662                              <1> 
  3663                              <1> pass_reducing_attributes:
  3664 000066A4 0825[0BC70000]      <1> 	or	[Attr_Chars+1], ah
  3665                              <1> 
  3666                              <1> loc_change_attributes_inc:
  3667 000066AA 46                  <1> 	inc	esi
  3668 000066AB 8A6601              <1> 	mov	ah, [esi+1]
  3669 000066AE 80FC20              <1> 	cmp	ah, 20h
  3670 000066B1 7227                <1> 	jb	short pass_change_attr
  3671 000066B3 74F5                <1> 	je	short loc_change_attributes_inc
  3672 000066B5 80FC2D              <1> 	cmp	ah, '-'
  3673 000066B8 770D                <1> 	ja	short loc_chk_next_attr_char1
  3674 000066BA 7405                <1> 	je	short loc_chk_next_attr_char0
  3675 000066BC 80FC2B              <1> 	cmp	ah, '+'
  3676 000066BF 7506                <1> 	jne	short loc_chk_next_attr_char1
  3677                              <1> 
  3678                              <1> loc_chk_next_attr_char0:
  3679 000066C1 46                  <1> 	inc	esi
  3680 000066C2 668B06              <1> 	mov	ax, [esi]
  3681 000066C5 EB9E                <1> 	jmp	short pass_attr_space
  3682                              <1> 
  3683                              <1> loc_chk_next_attr_char1:
  3684 000066C7 803E2D              <1> 	cmp	byte [esi], '-'
  3685 000066CA 7799                <1> 	ja	short pass_attr_space
  3686 000066CC E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3687                              <1> 
  3688                              <1> loc_chk_attr_enter:
  3689 000066D1 80FC0D              <1> 	cmp	ah, 0Dh
  3690 000066D4 0F8579F0FFFF        <1> 	jne	loc_cmd_failed
  3691                              <1> 
  3692                              <1> pass_change_attr:
  3693 000066DA A0[0AC70000]        <1> 	mov	al, [Attr_Chars]
  3694 000066DF F6D0                <1> 	not	al
  3695 000066E1 2005[08DE0000]      <1> 	and	[Attributes], al
  3696 000066E7 A0[0BC70000]        <1> 	mov	al, [Attr_Chars+1]
  3697 000066EC 0805[08DE0000]      <1> 	or	[Attributes], al
  3698                              <1> 
  3699                              <1> loc_show_attributes:
  3700 000066F2 BE[20CF0000]        <1> 	mov	esi, nextline
  3701 000066F7 E8B8D8FFFF          <1> 	call	print_msg
  3702                              <1> 
  3703                              <1> loc_show_attributes_no_nextline:
  3704 000066FC C705[0AC70000]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3704 00006704 524D                <1>
  3705 00006706 66C705[0EC70000]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3705 0000670E 4C                  <1>
  3706 0000670F BE[0AC70000]        <1> 	mov	esi, Attr_Chars
  3707 00006714 A0[08DE0000]        <1> 	mov	al, [Attributes]
  3708 00006719 A804                <1> 	test	al, 04h
  3709 0000671B 7406                <1> 	jz	short pass_put_attr_s
  3710 0000671D 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3711 00006722 46                  <1> 	inc	esi
  3712                              <1> 
  3713                              <1> pass_put_attr_s:
  3714 00006723 A802                <1> 	test	al, 02h
  3715 00006725 7406                <1> 	jz	short pass_put_attr_h
  3716 00006727 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3717 0000672C 46                  <1> 	inc	esi
  3718                              <1> 
  3719                              <1> pass_put_attr_h:
  3720 0000672D A801                <1> 	test	al, 01h
  3721 0000672F 7406                <1> 	jz	short pass_put_attr_r
  3722 00006731 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3723 00006736 46                  <1> 	inc	esi
  3724                              <1> 
  3725                              <1> pass_put_attr_r:
  3726 00006737 3C20                <1> 	cmp	al, 20h
  3727 00006739 7205                <1> 	jb	short pass_put_attr_a
  3728 0000673B 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3729                              <1> 
  3730                              <1> pass_put_attr_a:
  3731 00006740 BE[FDC60000]        <1> 	mov	esi, Str_Attributes
  3732 00006745 E86AD8FFFF          <1> 	call	print_msg
  3733 0000674A BE[20CF0000]        <1> 	mov	esi, nextline
  3734 0000674F E860D8FFFF          <1> 	call	print_msg
  3735 00006754 E924F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3736                              <1> 
  3737                              <1> loc_attr_file_check_fname_fchar:
  3738 00006759 46                  <1> 	inc	esi
  3739 0000675A 803E20              <1> 	cmp	byte [esi], 20h
  3740 0000675D 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3741 0000675F 0F8275FFFFFF        <1>         jb      pass_change_attr
  3742                              <1> 		   
  3743                              <1> loc_attr_file_parse_path_name:
  3744 00006765 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  3745 0000676A E8F0160000          <1> 	call	parse_path_name
  3746 0000676F 0F82DEEFFFFF        <1> 	jc	loc_cmd_failed
  3747                              <1> 
  3748                              <1> loc_attr_file_check_filename_exists:
  3749 00006775 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3750 0000677A 803E20              <1> 	cmp	byte [esi], 20h
  3751 0000677D 0F86D0EFFFFF        <1> 	jna	loc_cmd_failed
  3752 00006783 8935[B0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3753                              <1> 
  3754                              <1> loc_attr_file_drv:
  3755 00006789 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  3756 0000678F 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3757                              <1> 
  3758 00006795 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  3759 0000679B 38F2                <1> 	cmp	dl, dh
  3760 0000679D 740B                <1> 	je	short loc_attr_file_change_directory
  3761                              <1> 
  3762 0000679F E815E1FFFF          <1> 	call	change_current_drive
  3763 000067A4 0F82D3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3764                              <1> 
  3765                              <1> loc_attr_file_change_directory:
  3766 000067AA 803D[F3DC0000]20    <1>         cmp     byte [FindFile_Directory], 20h
  3767 000067B1 7618                <1> 	jna	short loc_attr_file_find
  3768                              <1> 
  3769 000067B3 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3770                              <1> 	
  3771 000067B9 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  3772 000067BE 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3773 000067C0 E886100000          <1> 	call	change_current_directory
  3774 000067C5 0F82B2F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3775                              <1> 
  3776                              <1> ;loc_attr_file_change_prompt_dir_string:
  3777                              <1> 	;call	change_prompt_dir_string
  3778                              <1> 
  3779                              <1> loc_attr_file_find:
  3780                              <1> 	;mov	esi, FindFile_Name
  3781 000067CB 8B35[B0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3782 000067D1 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3783 000067D5 E87BF4FFFF          <1> 	call	find_first_file
  3784 000067DA 0F829DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3785                              <1> 
  3786                              <1> loc_attr_file_ambgfn_check:
  3787 000067E0 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3788                              <1> 	;	(Note: It was BX in TRDOS v1)
  3789                              <1> 	;jz	short loc_attr_file_found
  3790 000067E3 0F85AAFDFFFF        <1>         jnz     loc_file_not_found ; 06/03/2016 
  3791                              <1> 
  3792                              <1> 	;mov	eax, 2 ; File not found sign
  3793                              <1> 	;stc
  3794                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3795                              <1> 
  3796                              <1> loc_attr_file_found:
  3797                              <1> 	; EDI = Directory buffer entry offset/address
  3798                              <1> 	; BL = File (or Directory) Attributes 
  3799                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3800                              <1> 	; mov	bl, [EDI+0Bh]
  3801                              <1> 	
  3802 000067E9 66833D[0AC70000]00  <1> 	cmp	word [Attr_Chars], 0
  3803 000067F1 770B                <1> 	ja	short loc_attr_file_change_attributes
  3804 000067F3 881D[08DE0000]      <1> 	mov	[Attributes], bl
  3805 000067F9 E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3806                              <1> 
  3807                              <1> loc_attr_file_change_attributes:
  3808 000067FE A0[0AC70000]        <1> 	mov	al, [Attr_Chars]
  3809 00006803 F6D0                <1> 	not	al
  3810 00006805 20C3                <1> 	and	bl, al
  3811 00006807 A0[0BC70000]        <1> 	mov	al, [Attr_Chars+1]
  3812 0000680C 08C3                <1> 	or	bl, al
  3813                              <1> 
  3814 0000680E 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3815 00006814 741D                <1> 	je	short loc_attr_file_fs_check
  3816                              <1> 
  3817 00006816 881D[08DE0000]      <1> 	mov	[Attributes], bl
  3818 0000681C 885F0B              <1> 	mov	[edi+0Bh], bl    ; Attributes (New!)
  3819                              <1> 
  3820                              <1> 	; 04/03/2016
  3821                              <1> 	; TRDOS v1 has a bug here! it does not set
  3822                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3823                              <1> 	; 'save_directory_buffer' would not save the new attributes ! 
  3824                              <1> 	
  3825 0000681F C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3826                              <1> 
  3827 00006826 E8981A0000          <1> 	call 	save_directory_buffer
  3828 0000682B 0F824CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3829                              <1> 
  3830 00006831 EB33                <1> 	jmp	short loc_print_attr_changed_message
  3831                              <1> 
  3832                              <1> loc_attr_file_fs_check:
  3833 00006833 29C0                <1> 	sub	eax, eax
  3834 00006835 8A25[76DB0000]      <1>         mov     ah, [DirBuff_DRV]
  3835 0000683B BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3836 00006840 01C6                <1>         add     esi, eax
  3837 00006842 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3838 00006846 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3839 00006848 66B80D00            <1> 	mov	ax, 0Dh ; Invalid Data
  3840 0000684C E92CF8FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3841                              <1> 
  3842                              <1> loc_attr_file_change_fs_file_attributes:
  3843                              <1> 	; BL = New MS-DOS File Attributes
  3844 00006851 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3845 00006853 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3846 00006855 E89C050000          <1> 	call	change_fs_file_attributes
  3847 0000685A 0F821DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3848                              <1> 
  3849 00006860 881D[08DE0000]      <1> 	mov	[Attributes], bl 
  3850                              <1> 
  3851                              <1> loc_print_attr_changed_message:
  3852 00006866 BE[F8C60000]        <1> 	mov	esi, Msg_New
  3853 0000686B E844D7FFFF          <1> 	call	print_msg
  3854 00006870 E987FEFFFF          <1> 	jmp	loc_show_attributes_no_nextline
  3855                              <1> 
  3856                              <1> rename_file:
  3857                              <1> 	; 08/03/2016
  3858                              <1> 	; 06/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3859                              <1> 	; 20/11/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_rename')
  3860                              <1> 	; 16/11/2010 
  3861                              <1> 
  3862                              <1> get_rename_source_fchar:
  3863                              <1> 	; esi = file name
  3864 00006875 803E20              <1> 	cmp	byte [esi], 20h
  3865 00006878 7614                <1>         jna	short loc_rename_nofilename_retn
  3866                              <1> 
  3867 0000687A 8935[2CDE0000]      <1> 	mov	[SourceFilePath], esi
  3868                              <1> 
  3869                              <1> rename_scan_source_file:
  3870 00006880 46                  <1> 	inc	esi
  3871 00006881 803E20              <1> 	cmp	byte [esi], 20h
  3872 00006884 7409                <1> 	je	short rename_scan_destination_file_1
  3873                              <1> 	;jb	short loc_rename_nofilename_retn
  3874 00006886 0F82C7EEFFFF        <1> 	jb	loc_cmd_failed
  3875 0000688C EBF2                <1> 	jmp	short rename_scan_source_file
  3876                              <1> 
  3877                              <1> loc_rename_nofilename_retn: ; 08/03/2016
  3878 0000688E C3                  <1> 	retn
  3879                              <1> 
  3880                              <1> rename_scan_destination_file_1:
  3881 0000688F C60600              <1> 	mov	byte [esi], 0
  3882                              <1> 
  3883                              <1> rename_scan_destination_file_2:
  3884 00006892 46                  <1> 	inc	esi  
  3885 00006893 803E20              <1> 	cmp	byte [esi], 20h
  3886 00006896 74FA                <1> 	je	short rename_scan_destination_file_2
  3887                              <1> 	;jb	short loc_rename_nofilename_retn
  3888 00006898 0F82B5EEFFFF        <1> 	jb	loc_cmd_failed
  3889                              <1> 
  3890 0000689E 8935[30DE0000]      <1> 	mov	[DestinationFilePath], esi
  3891                              <1> 
  3892                              <1> rename_scan_destination_file_3:
  3893 000068A4 46                  <1> 	inc	esi  
  3894 000068A5 803E20              <1> 	cmp	byte [esi], 20h
  3895 000068A8 77FA                <1> 	ja	short rename_scan_destination_file_3
  3896                              <1> 
  3897 000068AA C60600              <1> 	mov	byte [esi], 0
  3898                              <1> 
  3899                              <1> loc_rename_save_current_drive:
  3900 000068AD 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  3901 000068B3 8835[AEDB0000]      <1> 	mov	byte [RUN_CDRV], dh
  3902                              <1> 
  3903                              <1> loc_rename_sf_parse_path_name:
  3904 000068B9 8B35[2CDE0000]      <1> 	mov	esi, [SourceFilePath] 
  3905 000068BF BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  3906 000068C4 E896150000          <1> 	call	parse_path_name
  3907 000068C9 0F8284EEFFFF        <1> 	jc	loc_cmd_failed
  3908                              <1> 
  3909                              <1> loc_rename_sf_check_filename_exists:
  3910 000068CF BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3911 000068D4 803E20              <1> 	cmp	byte [esi], 20h
  3912 000068D7 0F8676EEFFFF        <1> 	jna	loc_cmd_failed
  3913                              <1> 
  3914                              <1> 	;mov	[DelFile_FNPointer], esi 
  3915                              <1> 
  3916                              <1> loc_rename_sf_drv:
  3917                              <1> 	;mov	dh, [Current_Drv]
  3918                              <1> 	;mov	[RUN_CDRV], dh
  3919                              <1> 
  3920 000068DD 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  3921 000068E3 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  3922 000068E5 740B                <1> 	je	short rename_sf_change_directory
  3923                              <1> 
  3924 000068E7 E8CDDFFFFF          <1> 	call	change_current_drive
  3925 000068EC 0F828BF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3926                              <1> 
  3927                              <1> rename_sf_change_directory:
  3928 000068F2 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3929 000068F9 7618                <1> 	jna	short rename_sf_find
  3930                              <1> 
  3931 000068FB FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3932 00006901 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  3933 00006906 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3934 00006908 E83E0F0000          <1> 	call	change_current_directory
  3935 0000690D 0F826AF7FFFF        <1>  	jc	loc_file_rw_cmd_failed
  3936                              <1> 
  3937                              <1> ;rename_sf_change_prompt_dir_string:
  3938                              <1> 	;call	change_prompt_dir_string
  3939                              <1> 
  3940                              <1> rename_sf_find:
  3941                              <1> 	;mov	esi, [DelFile_FNPointer]
  3942 00006913 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3943                              <1> 
  3944 00006918 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3945 0000691C E834F3FFFF          <1> 	call	find_first_file
  3946 00006921 0F8256F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3947                              <1> 
  3948                              <1> loc_rename_sf_ambgfn_check:
  3949 00006927 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3950                              <1> 	;	(Note: It was BX in TRDOS v1)
  3951                              <1> 	;jz	short loc_rename_sf_found
  3952 0000692A 0F8563FCFFFF        <1> 	jnz	loc_file_not_found
  3953                              <1> 
  3954                              <1> 	;mov	eax, 2 ; File not found sign
  3955                              <1> 	;stc
  3956                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3957                              <1> 
  3958                              <1> loc_rename_sf_found:
  3959                              <1> 	; EDI = Directory buffer entry offset/address
  3960                              <1> 	; BL = File (or Directory) Attributes 
  3961                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3962                              <1> 	; mov	bl, [EDI+0Bh]
  3963                              <1> 
  3964 00006930 F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  3965 00006933 0F854EF7FFFF        <1> 	jnz	loc_permission_denied
  3966                              <1> 	
  3967 00006939 BE[F2DC0000]        <1>         mov     esi, FindFile_Drv
  3968 0000693E BF[34DE0000]        <1>         mov     edi, SourceFile_Drv
  3969 00006943 B920000000          <1> 	mov	ecx, 32
  3970 00006948 F3A5                <1> 	rep	movsd
  3971                              <1> 
  3972                              <1> loc_rename_df_parse_path_name:
  3973 0000694A 8B35[30DE0000]      <1> 	mov	esi, [DestinationFilePath]
  3974 00006950 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  3975 00006955 E805150000          <1> 	call	parse_path_name
  3976 0000695A 7219                <1> 	jc	short loc_rename_df_cmd_failed
  3977                              <1> 
  3978                              <1> 	;mov	dh, [RUN_CDRV]
  3979 0000695C 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  3980                              <1> 
  3981                              <1> 	; 'rename' command is valid only for same dos drive and same dir!
  3982                              <1> 	; ('move' command must be used if source file and destination file
  3983                              <1> 	; directories are not same!) 
  3984 00006962 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  3985 00006968 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  3986 0000696A 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  3987                              <1> 
  3988                              <1> rename_df_check_dirname_exists:
  3989 0000696C 803D[F3DC0000]00    <1> 	cmp	byte [FindFile_Directory], 0
  3990 00006973 760B                <1> 	jna	short rename_df_check_filename_exists
  3991                              <1> 
  3992                              <1> 	; different source file and destination file directories !
  3993                              <1> loc_rename_df_cmd_failed:
  3994                              <1> loc_rename_df_found:
  3995 00006975 B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  3996 0000697A F9                  <1> 	stc
  3997 0000697B E9FDF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3998                              <1> 	  
  3999                              <1> rename_df_check_filename_exists:
  4000 00006980 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  4001 00006985 E883F6FFFF          <1> 	call	check_filename
  4002 0000698A 0F829FF7FFFF        <1> 	jc	loc_mkdir_invalid_dir_name_chars
  4003                              <1> 
  4004                              <1> 	;mov	[DelFile_FNPointer], esi 
  4005                              <1> 	;cmp	byte [esi], 20h
  4006                              <1> 	;ja	short loc_rename_df_find
  4007                              <1> 
  4008                              <1> 	;mov	dh, [Current_Drv] ; dh has not been changed
  4009                              <1> 
  4010                              <1> rename_df_drv_check_writable:
  4011 00006990 0FB6F6              <1> 	movzx	esi, dh
  4012                              <1> 	;movzx	esi, byte [Current_Drv]
  4013 00006993 81C600010900        <1> 	add	esi, Logical_DOSDisks
  4014                              <1> 
  4015 00006999 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  4016 0000699B 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  4017                              <1> 
  4018 0000699E 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  4019 000069A1 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  4020                              <1> 
  4021 000069A3 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected
  4022 000069A8 8B1D[30DE0000]      <1> 	mov	ebx, [DestinationFilePath] 
  4023 000069AE E9CAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4024                              <1> 
  4025                              <1> rename_df_compare_sf_df_name:
  4026 000069B3 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  4027 000069B8 BF[76DE0000]        <1> 	mov	edi, SourceFile_Name
  4028 000069BD B90C000000          <1> 	mov	ecx, 12
  4029                              <1> rename_df_compare_sf_df_name_next: 
  4030 000069C2 AC                  <1> 	lodsb
  4031 000069C3 AE                  <1> 	scasb
  4032 000069C4 7506                <1> 	jne	short loc_rename_df_find
  4033 000069C6 08C0                <1> 	or	al, al
  4034 000069C8 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  4035 000069CA E2F6                <1> 	loop	rename_df_compare_sf_df_name_next 
  4036                              <1> 
  4037                              <1> loc_rename_df_find:
  4038                              <1> 	;mov	esi, [DelFile_FNPointer]
  4039 000069CC BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  4040                              <1> 
  4041 000069D1 6631C0              <1> 	xor	ax, ax ; Any
  4042 000069D4 E87CF2FFFF          <1> 	call	find_first_file
  4043 000069D9 739A                <1> 	jnc	short loc_rename_df_found
  4044                              <1> 
  4045                              <1> loc_rename_df_check_error_code:
  4046                              <1> 	;cmp	eax, 2
  4047 000069DB 3C02                <1> 	cmp	al, 2 ; Not found error
  4048 000069DD 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  4049 000069DF F9                  <1> 	stc
  4050 000069E0 E998F6FFFF          <1> 	jmp loc_file_rw_cmd_failed
  4051                              <1> 
  4052                              <1> ;loc_rename_df_found:
  4053                              <1> ;	mov	eax, 1 ;Bad command or file name error
  4054                              <1> ;	stc
  4055                              <1> ;	jmp	loc_file_rw_cmd_failed
  4056                              <1> 
  4057                              <1> rename_df_move_find_struct_to_dest:
  4058 000069E5 BE[F2DC0000]        <1>         mov     esi, FindFile_Drv
  4059 000069EA BF[B4DE0000]        <1>         mov     edi, DestinationFile_Drv
  4060 000069EF B920000000          <1> 	mov	ecx, 32
  4061 000069F4 F3A5                <1> 	rep	movsd
  4062                              <1> 
  4063                              <1> loc_rename_df_process_q_sf:
  4064                              <1> 	;mov	ecx, 12
  4065 000069F6 B10C                <1> 	mov	cl, 12
  4066 000069F8 BE[76DE0000]        <1>  	mov	esi, SourceFile_Name
  4067 000069FD BF[39C70000]        <1> 	mov	edi, Rename_OldName
  4068                              <1> rename_df_process_q_nml_1_sf:
  4069 00006A02 AC                  <1> 	lodsb
  4070 00006A03 3C20                <1>         cmp	al, 20h
  4071 00006A05 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4072 00006A07 AA                  <1> 	stosb
  4073 00006A08 E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4074                              <1> 
  4075                              <1> rename_df_process_q_nml_2_sf:
  4076 00006A0A C60700              <1> 	mov	byte [edi], 0
  4077                              <1> 
  4078                              <1> loc_rename_df_process_q_df:
  4079                              <1> 	;mov	ecx, 12
  4080 00006A0D B10C                <1> 	mov	cl, 12
  4081 00006A0F BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  4082 00006A14 BF[4AC70000]        <1> 	mov	edi, Rename_NewName
  4083                              <1> rename_df_process_q_nml_1_df:
  4084 00006A19 AC                  <1> 	lodsb
  4085 00006A1A 3C20                <1> 	cmp	al, 20h
  4086 00006A1C 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4087 00006A1E AA                  <1> 	stosb
  4088 00006A1F E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4089                              <1> 
  4090                              <1> loc_rename_df_process_q_nml_2_df:
  4091 00006A21 C60700              <1> 	mov	byte [edi], 0
  4092                              <1> 
  4093                              <1> loc_rename_confirmation_question:
  4094 00006A24 BE[11C70000]        <1> 	mov	esi, Msg_DoYouWantRename
  4095 00006A29 E886D5FFFF          <1> 	call	print_msg
  4096                              <1> 
  4097 00006A2E A0[91DE0000]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4098 00006A33 2410                <1> 	and	al, 10h
  4099 00006A35 750C                <1> 	jnz	short rename_confirmation_question_dir
  4100                              <1> 
  4101                              <1> rename_confirmation_question_file:
  4102 00006A37 BE[28C70000]        <1> 	mov	esi, Rename_File
  4103 00006A3C E873D5FFFF          <1> 	call	print_msg 
  4104 00006A41 EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4105                              <1> 
  4106                              <1> rename_confirmation_question_dir:
  4107 00006A43 BE[2EC70000]        <1> 	mov	esi, Rename_Directory
  4108 00006A48 E867D5FFFF          <1> 	call	print_msg
  4109                              <1> 
  4110                              <1> rename_confirmation_question_as:
  4111 00006A4D BE[39C70000]        <1> 	mov	esi, Rename_OldName
  4112 00006A52 E85DD5FFFF          <1> 	call	print_msg
  4113 00006A57 BE[46C70000]        <1> 	mov	esi, Msg_File_rename_as
  4114 00006A5C E853D5FFFF          <1> 	call	print_msg
  4115 00006A61 BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  4116 00006A66 E849D5FFFF          <1> 	call	print_msg
  4117                              <1> 
  4118                              <1> loc_rename_ask_again:
  4119 00006A6B 30E4                <1> 	xor	ah, ah
  4120 00006A6D E82AA0FFFF          <1> 	call	int16h
  4121 00006A72 3C1B                <1> 	cmp	al, 1Bh
  4122 00006A74 740F                <1> 	je	short loc_do_not_rename_file
  4123 00006A76 24DF                <1> 	and	al, 0DFh
  4124 00006A78 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  4125 00006A7D 3C59                <1> 	cmp	al, 'Y'
  4126 00006A7F 7404                <1> 	je	short loc_yes_rename_file
  4127 00006A81 3C4E                <1> 	cmp	al, 'N'
  4128 00006A83 75E6                <1> 	jne	short loc_rename_ask_again
  4129                              <1> 
  4130                              <1> loc_do_not_rename_file:
  4131                              <1> loc_yes_rename_file:
  4132 00006A85 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  4133 00006A8A 6650                <1> 	push	ax
  4134 00006A8C BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  4135 00006A91 E81ED5FFFF          <1> 	call	print_msg
  4136 00006A96 6658                <1> 	pop	ax
  4137                              <1> 	;cmp	al, 'Y' ; 'yes'
  4138                              <1> 	;cmc
  4139                              <1>         ;jnc	loc_file_rw_restore_retn
  4140 00006A98 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4141 00006A9A 0F84DDF5FFFF        <1>         je	loc_file_rw_restore_retn  
  4142                              <1> 
  4143 00006AA0 BE[4AC70000]        <1> 	mov	esi, Rename_NewName
  4144 00006AA5 668B0D[AEDE0000]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4145 00006AAC 66A1[9ADE0000]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4146 00006AB2 66C1E010            <1> 	shl	ax, 16
  4147 00006AB6 66A1[A0DE0000]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4148                              <1> 
  4149 00006ABC 0FB61D[83DE0000]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4150 00006AC3 E8E11B0000          <1>    	call	rename_directory_entry
  4151 00006AC8 E9DEF6FFFF          <1> 	jmp	loc_rename_file_ok	
  4152                              <1> ;loc_rename_file_ok:
  4153                              <1> ;	jc	loc_run_cmd_failed
  4154                              <1> ;	mov	esi, Msg_OK
  4155                              <1> ;	call	proc_printmsg
  4156                              <1> ;	jmp	loc_file_rw_restore_retn
  4157                              <1> 
  4158                              <1> move_file:
  4159                              <1> 	; 11/03/2016
  4160                              <1> 	; 09/03/2016
  4161                              <1> 	; 08/03/2016 (TRDOS 386 =  TRDOS v2.0)
  4162                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_move')
  4163                              <1> 	; 23/04/2011
  4164                              <1> 
  4165                              <1> get_move_source_fchar:
  4166                              <1> 	; esi = file name
  4167 00006ACD 803E20              <1> 	cmp	byte [esi], 20h
  4168 00006AD0 7614                <1>         jna	short loc_move_nofilename_retn
  4169                              <1> 
  4170 00006AD2 8935[2CDE0000]      <1> 	mov	[SourceFilePath], esi
  4171                              <1> 
  4172                              <1> move_scan_source_file:
  4173 00006AD8 46                  <1> 	inc	esi
  4174 00006AD9 803E20              <1> 	cmp	byte [esi], 20h
  4175 00006ADC 7409                <1>         je      short move_scan_destination_1
  4176                              <1> 	;jb	short loc_move_nofilename_retn
  4177 00006ADE 0F826FECFFFF        <1> 	jb	loc_cmd_failed
  4178 00006AE4 EBF2                <1> 	jmp	short move_scan_source_file
  4179                              <1> 
  4180                              <1> loc_move_nofilename_retn:
  4181 00006AE6 C3                  <1> 	retn
  4182                              <1> 
  4183                              <1> move_scan_destination_1:
  4184 00006AE7 C60600              <1> 	mov	byte [esi], 0
  4185                              <1> 
  4186                              <1> move_scan_destination_2:
  4187 00006AEA 46                  <1> 	inc	esi  
  4188 00006AEB 803E20              <1> 	cmp	byte [esi], 20h
  4189 00006AEE 74FA                <1> 	je	short move_scan_destination_2
  4190                              <1> 	;jb	short loc_move_nofilename_retn
  4191 00006AF0 0F825DECFFFF        <1> 	jb	loc_cmd_failed
  4192                              <1> 
  4193 00006AF6 8935[30DE0000]      <1> 	mov	[DestinationFilePath], esi
  4194                              <1> 
  4195                              <1> move_scan_destination_3:
  4196 00006AFC 46                  <1> 	inc	esi  
  4197 00006AFD 803E20              <1> 	cmp	byte [esi], 20h
  4198 00006B00 77FA                <1> 	ja	short move_scan_destination_3
  4199 00006B02 C60600              <1> 	mov	byte [esi], 0
  4200                              <1> 
  4201                              <1> loc_move_scan_destination_OK:
  4202 00006B05 8B35[2CDE0000]      <1> 	mov	esi, [SourceFilePath]
  4203 00006B0B 8B3D[30DE0000]      <1> 	mov	edi, [DestinationFilePath]
  4204                              <1> 
  4205 00006B11 B001                <1> 	mov	al, 1  ; move procedure Phase 1
  4206 00006B13 E80E1C0000          <1> 	call	move_source_file_to_destination_file
  4207 00006B18 7328                <1> 	jnc	short move_source_file_to_destination_question
  4208                              <1> 
  4209                              <1> loc_move_cmd_failed_1:
  4210 00006B1A 08C0                <1> 	or	al, al
  4211 00006B1C 0F8431ECFFFF        <1> 	jz	loc_cmd_failed 
  4212 00006B22 3C11                <1> 	cmp	al, 11h
  4213 00006B24 740D                <1> 	je	short loc_msg_not_same_device   
  4214 00006B26 3C05                <1> 	cmp	al, 05h
  4215 00006B28 0F8550ECFFFF        <1> 	jne	loc_run_cmd_failed
  4216                              <1> 
  4217 00006B2E E954F5FFFF          <1> 	jmp	loc_permission_denied
  4218                              <1> 
  4219                              <1> 	;mov	esi, Msg_Permission_denied
  4220                              <1> 	;call	print_msg
  4221                              <1> 	;jmp	loc_file_rw_restore_retn
  4222                              <1> 
  4223                              <1> loc_msg_not_same_device:
  4224 00006B33 BE[57C70000]        <1> 	mov	esi, msg_not_same_drv 
  4225 00006B38 E877D4FFFF          <1> 	call	print_msg
  4226 00006B3D E93BF5FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4227                              <1> 
  4228                              <1> move_source_file_to_destination_question:
  4229 00006B42 A0[34DE0000]        <1>         mov     al, [SourceFile_Drv]
  4230 00006B47 0441                <1> 	add	al, 'A'
  4231 00006B49 A2[B9C70000]        <1> 	mov	[msg_source_file_drv], al
  4232 00006B4E A0[B4DE0000]        <1>         mov     al, [DestinationFile_Drv]
  4233 00006B53 0441                <1> 	add	al, 'A'
  4234 00006B55 A2[D8C70000]        <1> 	mov	[msg_destination_file_drv], al
  4235                              <1> 
  4236 00006B5A 57                  <1> 	push	edi ; *
  4237                              <1> 
  4238 00006B5B BE[9DC70000]        <1> 	mov	esi, msg_source_file
  4239 00006B60 E84FD4FFFF          <1> 	call	print_msg
  4240 00006B65 BE[35DE0000]        <1> 	mov	esi, SourceFile_Directory
  4241 00006B6A 803E20              <1> 	cmp	byte [esi], 20h
  4242 00006B6D 7605                <1> 	jna	short msftdfq_sfn
  4243 00006B6F E840D4FFFF          <1> 	call	print_msg
  4244                              <1> msftdfq_sfn:
  4245 00006B74 BE[76DE0000]        <1> 	mov	esi, SourceFile_Name
  4246 00006B79 E836D4FFFF          <1> 	call	print_msg
  4247 00006B7E BE[BCC70000]        <1> 	mov	esi, msg_destination_file
  4248 00006B83 E82CD4FFFF          <1> 	call	print_msg
  4249 00006B88 BE[B5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  4250 00006B8D 803E20              <1> 	cmp	byte [esi], 20h
  4251 00006B90 7605                <1> 	jna	short msftdfq_dfn
  4252 00006B92 E81DD4FFFF          <1> 	call	print_msg
  4253                              <1> msftdfq_dfn:
  4254 00006B97 BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  4255 00006B9C E813D4FFFF          <1> 	call	print_msg
  4256 00006BA1 BE[DBC70000]        <1> 	mov	esi, msg_copy_nextline
  4257 00006BA6 E809D4FFFF          <1> 	call	print_msg
  4258 00006BAB BE[DBC70000]        <1> 	mov	esi, msg_copy_nextline
  4259 00006BB0 E8FFD3FFFF          <1> 	call	print_msg
  4260                              <1> 
  4261                              <1> loc_move_ask_for_new_file_yes_no:
  4262 00006BB5 BE[69C70000]        <1> 	mov	esi, Msg_DoYouWantMoveFile
  4263 00006BBA E8F5D3FFFF          <1> 	call	print_msg
  4264 00006BBF BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  4265 00006BC4 E8EBD3FFFF          <1> 	call	print_msg
  4266                              <1> loc_move_ask_for_new_file_again:
  4267 00006BC9 30E4                <1> 	xor	ah, ah
  4268 00006BCB E8CC9EFFFF          <1> 	call	int16h
  4269 00006BD0 3C1B                <1> 	cmp	al, 1Bh
  4270                              <1> 	;je	short loc_do_not_move_file
  4271 00006BD2 744F                <1> 	je	short loc_move_y_n_escape
  4272 00006BD4 24DF                <1> 	and	al, 0DFh
  4273 00006BD6 A2[77C60000]        <1>         mov     [Y_N_nextline], al
  4274 00006BDB 3C59                <1> 	cmp	al, 'Y'
  4275 00006BDD 7404                <1> 	je	short loc_yes_move_file
  4276 00006BDF 3C4E                <1> 	cmp	al, 'N'
  4277 00006BE1 75E6                <1> 	jne	short loc_move_ask_for_new_file_again
  4278                              <1> 
  4279                              <1> loc_do_not_move_file:
  4280                              <1> loc_yes_move_file:
  4281 00006BE3 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  4282 00006BE8 6650                <1> 	push	ax
  4283 00006BEA BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  4284 00006BEF E8C0D3FFFF          <1> 	call	print_msg
  4285 00006BF4 6658                <1> 	pop	ax
  4286 00006BF6 5F                  <1> 	pop	edi ; *
  4287                              <1> 	;cmp	al, 'Y' ; 'yes'
  4288                              <1> 	;cmc
  4289                              <1>         ;jnc	loc_file_rw_restore_retn
  4290 00006BF7 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4291 00006BF9 0F847EF4FFFF        <1>         je	loc_file_rw_restore_retn
  4292                              <1> 
  4293                              <1> loc_move_yes_move_file:
  4294 00006BFF B002                <1> 	mov	al, 2 ; move procedure Phase 2
  4295 00006C01 E8201B0000          <1> 	call	move_source_file_to_destination_file
  4296                              <1> 	;jc	short loc_move_cmd_failed_2
  4297 00006C06 0F83A5F5FFFF        <1>         jnc     move_source_file_to_destination_OK
  4298                              <1> 
  4299                              <1> ;move_source_file_to_destination_OK:
  4300                              <1> ;	mov	esi, Msg_OK
  4301                              <1> ;	call	print_msg
  4302                              <1> ;	jmp	loc_file_rw_restore_retn
  4303                              <1> 
  4304                              <1> loc_move_cmd_failed_2:
  4305 00006C0C 3C27                <1> 	cmp	al, 27h
  4306 00006C0E 0F856AEBFFFF        <1> 	jne	loc_run_cmd_failed
  4307                              <1> 
  4308 00006C14 BE[82C70000]        <1> 	mov	esi, msg_insufficient_disk_space
  4309 00006C19 E896D3FFFF          <1> 	call	print_msg
  4310                              <1> 
  4311 00006C1E E95AF4FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4312                              <1> 
  4313                              <1> loc_move_y_n_escape:
  4314 00006C23 B04E                <1> 	mov	al, 'N' ; 'no'
  4315 00006C25 EBBC                <1> 	jmp	short loc_do_not_move_file
  4316                              <1> 
  4317                              <1> copy_file:
  4318                              <1> 	; 24/03/2016
  4319                              <1> 	; 21/03/2016
  4320                              <1> 	; 15/03/2016 (TRDOS 386 =  TRDOS v2.0)
  4321                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_copy')
  4322                              <1> 	; 01/08/2010
  4323                              <1> 
  4324                              <1> get_copy_source_fchar:
  4325                              <1> 	; esi = file name
  4326 00006C27 803E20              <1> 	cmp	byte [esi], 20h
  4327 00006C2A 7614                <1>         jna     short loc_copy_nofilename_retn
  4328                              <1> 
  4329 00006C2C 8935[2CDE0000]      <1> 	mov	[SourceFilePath], esi
  4330                              <1> 
  4331                              <1> copy_scan_source_file:
  4332 00006C32 46                  <1> 	inc	esi  
  4333 00006C33 803E20              <1> 	cmp	byte [esi], 20h
  4334 00006C36 7409                <1> 	je	short copy_scan_destination_1
  4335                              <1> 	;jb	short loc_copy_nofilename_retn
  4336 00006C38 0F8215EBFFFF        <1> 	jb	loc_cmd_failed
  4337 00006C3E EBF2                <1> 	jmp	short copy_scan_source_file
  4338                              <1> 
  4339                              <1> loc_copy_nofilename_retn:
  4340 00006C40 C3                  <1> 	retn
  4341                              <1> 
  4342                              <1> copy_scan_destination_1:
  4343 00006C41 C60600              <1> 	mov	byte [esi], 0
  4344                              <1> 
  4345                              <1> copy_scan_destination_2:
  4346 00006C44 46                  <1> 	inc	esi  
  4347 00006C45 803E20              <1> 	cmp	byte [esi], 20h
  4348 00006C48 74FA                <1> 	je	short copy_scan_destination_2
  4349                              <1> 	;jb	short loc_copy_nofilename_retn
  4350 00006C4A 0F8203EBFFFF        <1> 	jb	loc_cmd_failed
  4351                              <1> 
  4352 00006C50 8935[30DE0000]      <1> 	mov	[DestinationFilePath], esi
  4353                              <1> 
  4354                              <1> copy_scan_destination_3:
  4355 00006C56 46                  <1> 	inc	esi  
  4356 00006C57 803E20              <1> 	cmp	byte [esi], 20h
  4357 00006C5A 77FA                <1> 	ja	short copy_scan_destination_3
  4358 00006C5C C60600              <1> 	mov	byte [esi], 0
  4359                              <1> 
  4360                              <1> loc_copy_save_current_drive:
  4361 00006C5F 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  4362 00006C65 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  4363                              <1> 
  4364                              <1> copy_source_file_to_destination_phase_1:
  4365 00006C6B 8B35[2CDE0000]      <1> 	mov	esi, [SourceFilePath]
  4366 00006C71 8B3D[30DE0000]      <1> 	mov	edi, [DestinationFilePath]
  4367                              <1> 
  4368 00006C77 B001                <1> 	mov	al, 1  ; copy procedure Phase 1
  4369 00006C79 E8331D0000          <1> 	call	copy_source_file_to_destination_file
  4370 00006C7E 732B                <1> 	jnc	short copy_source_file_to_destination_question
  4371                              <1> 
  4372                              <1> loc_copy_cmd_failed_1:
  4373                              <1> 	; 18/03/2016 (restore current drive and directory)
  4374 00006C80 08C0                <1> 	or	al, al
  4375 00006C82 7507                <1> 	jnz	short loc_copy_cmd_failed_2
  4376                              <1> 
  4377 00006C84 FEC0                <1>         inc     al ; mov al, 1 ; Bad command or file name !
  4378 00006C86 E9F3EAFFFF          <1> 	jmp	loc_run_cmd_failed
  4379                              <1> 
  4380                              <1> loc_copy_cmd_failed_2:
  4381 00006C8B 3C27                <1> 	cmp	al, 27h ; Insufficient disk space 
  4382 00006C8D 740D                <1> 	je	short loc_file_write_insuff_disk_space_msg
  4383                              <1>  
  4384 00006C8F 3C05                <1> 	cmp	al, 05h
  4385 00006C91 0F85E7EAFFFF        <1> 	jne	loc_run_cmd_failed
  4386                              <1> 	
  4387 00006C97 E9EBF3FFFF          <1> 	jmp	loc_permission_denied
  4388                              <1> 
  4389                              <1> loc_file_write_insuff_disk_space_msg:
  4390 00006C9C BE[82C70000]        <1> 	mov	esi, msg_insufficient_disk_space
  4391 00006CA1 E80ED3FFFF          <1> 	call	print_msg
  4392 00006CA6 E9D2F3FFFF          <1>         jmp     loc_file_rw_restore_retn 
  4393                              <1> 
  4394                              <1> copy_source_file_to_destination_question:
  4395 00006CAB 57                  <1> 	push	edi ; *
  4396                              <1> 
  4397                              <1> 	; dh = source file attributes
  4398                              <1> 	; dl > 0 -> destination file found
  4399 00006CAC 20D2                <1> 	and	dl, dl            
  4400 00006CAE 7449                <1> 	jz	short copy_source_file_to_destination_pass_owrq
  4401                              <1> 
  4402                              <1> loc_copy_ask_for_owr_yes_no:
  4403 00006CB0 BE[DEC70000]        <1> 	mov	esi, Msg_DoYouWantOverWriteFile
  4404 00006CB5 E8FAD2FFFF          <1> 	call	print_msg
  4405 00006CBA BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  4406 00006CBF E8F0D2FFFF          <1> 	call	print_msg
  4407 00006CC4 BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  4408 00006CC9 E8E6D2FFFF          <1> 	call	print_msg
  4409                              <1> 
  4410                              <1> loc_copy_ask_for_owr_again:
  4411 00006CCE 30E4                <1> 	xor	ah, ah
  4412 00006CD0 E8C79DFFFF          <1> 	call	int16h
  4413 00006CD5 3C1B                <1> 	cmp	al, 1Bh
  4414                              <1>         ;je     loc_do_not_copy_file
  4415 00006CD7 7419                <1>         je      short loc_copy_y_n_escape
  4416 00006CD9 24DF                <1> 	and	al, 0DFh
  4417 00006CDB A2[77C60000]        <1>         mov     [Y_N_nextline], al
  4418 00006CE0 3C59                <1> 	cmp	al, 'Y'
  4419 00006CE2 0F84B1000000        <1>         je      loc_yes_copy_file
  4420 00006CE8 3C4E                <1> 	cmp	al, 'N'
  4421 00006CEA 0F84A9000000        <1>         je      loc_do_not_copy_file
  4422 00006CF0 EBDC                <1> 	jmp	short loc_copy_ask_for_owr_again
  4423                              <1> 
  4424                              <1> loc_copy_y_n_escape:
  4425 00006CF2 B04E                <1> 	mov	al, 'N' ; 'no'
  4426 00006CF4 E9A0000000          <1>         jmp     loc_do_not_copy_file
  4427                              <1> 
  4428                              <1> copy_source_file_to_destination_pass_owrq:
  4429 00006CF9 A0[34DE0000]        <1> 	mov     al, [SourceFile_Drv]
  4430 00006CFE 0441                <1> 	add	al, 'A'
  4431 00006D00 A2[B9C70000]        <1> 	mov	[msg_source_file_drv], al
  4432 00006D05 A0[B4DE0000]        <1>         mov     al, [DestinationFile_Drv]
  4433 00006D0A 0441                <1> 	add	al, 'A'
  4434 00006D0C A2[D8C70000]        <1> 	mov	[msg_destination_file_drv], al
  4435                              <1> 
  4436 00006D11 BE[9DC70000]        <1> 	mov	esi, msg_source_file
  4437 00006D16 E899D2FFFF          <1> 	call	print_msg
  4438 00006D1B BE[35DE0000]        <1> 	mov	esi, SourceFile_Directory
  4439 00006D20 803E20              <1> 	cmp	byte [esi], 20h
  4440 00006D23 7605                <1> 	jna	short csftdfq_sfn
  4441 00006D25 E88AD2FFFF          <1> 	call	print_msg
  4442                              <1> csftdfq_sfn:
  4443 00006D2A BE[76DE0000]        <1> 	mov	esi, SourceFile_Name
  4444 00006D2F E880D2FFFF          <1> 	call	print_msg
  4445 00006D34 BE[BCC70000]        <1> 	mov	esi, msg_destination_file
  4446 00006D39 E876D2FFFF          <1> 	call	print_msg
  4447 00006D3E BE[B5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  4448 00006D43 803E20              <1> 	cmp	byte [esi], 20h
  4449 00006D46 7605                <1> 	jna	short csftdfq_dfn
  4450 00006D48 E867D2FFFF          <1> 	call	print_msg
  4451                              <1> csftdfq_dfn:
  4452 00006D4D BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  4453 00006D52 E85DD2FFFF          <1> 	call	print_msg
  4454 00006D57 BE[DBC70000]        <1> 	mov	esi, msg_copy_nextline
  4455 00006D5C E853D2FFFF          <1> 	call	print_msg
  4456 00006D61 BE[DBC70000]        <1> 	mov	esi, msg_copy_nextline
  4457 00006D66 E849D2FFFF          <1> 	call	print_msg
  4458                              <1> 
  4459                              <1> loc_copy_ask_for_new_file_yes_no:
  4460 00006D6B BE[FDC70000]        <1> 	mov	esi, Msg_DoYouWantCopyFile
  4461 00006D70 E83FD2FFFF          <1> 	call	print_msg
  4462 00006D75 BE[6DC60000]        <1> 	mov	esi, Msg_YesNo
  4463 00006D7A E835D2FFFF          <1> 	call	print_msg
  4464                              <1> 
  4465                              <1> loc_copy_ask_for_new_file_again:
  4466 00006D7F 30E4                <1> 	xor	ah, ah
  4467 00006D81 E8169DFFFF          <1> 	call	int16h
  4468 00006D86 3C1B                <1> 	cmp	al, 1Bh
  4469 00006D88 740F                <1> 	je	short loc_do_not_copy_file
  4470 00006D8A 24DF                <1> 	and	al, 0DFh
  4471 00006D8C A2[77C60000]        <1>         mov     [Y_N_nextline], al
  4472 00006D91 3C59                <1> 	cmp	al, 'Y'
  4473 00006D93 7404                <1> 	je	short loc_yes_copy_file
  4474 00006D95 3C4E                <1> 	cmp	al, 'N'
  4475 00006D97 75E6                <1> 	jne	short loc_copy_ask_for_new_file_again
  4476                              <1> 
  4477                              <1> loc_do_not_copy_file:
  4478                              <1> loc_yes_copy_file:
  4479 00006D99 A2[77C60000]        <1> 	mov	[Y_N_nextline], al
  4480 00006D9E 6650                <1> 	push	ax
  4481 00006DA0 BE[77C60000]        <1> 	mov	esi, Y_N_nextline
  4482 00006DA5 E80AD2FFFF          <1> 	call	print_msg
  4483 00006DAA 6658                <1> 	pop	ax
  4484 00006DAC 5F                  <1> 	pop	edi ; *
  4485                              <1> 	;cmp	al, 'Y' ; 'yes'
  4486                              <1> 	;cmc
  4487                              <1>         ;jnc	loc_file_rw_restore_retn
  4488 00006DAD 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4489 00006DAF 0F84C8F2FFFF        <1>         je	loc_file_rw_restore_retn
  4490                              <1> 
  4491                              <1> copy_source_file_to_destination_pass_q:
  4492 00006DB5 B002                <1> 	mov	al, 2  ; copy procedure Phase 2
  4493 00006DB7 E8F51B0000          <1> 	call	copy_source_file_to_destination_file
  4494                              <1> 	;jc	short loc_file_write_check_disk_space_err
  4495                              <1> 
  4496                              <1> 	; 24/03/2016
  4497 00006DBC 6651                <1> 	push	cx
  4498 00006DBE BE[DBC70000]        <1> 	mov	esi, msg_copy_nextline
  4499 00006DC3 E8ECD1FFFF          <1> 	call	print_msg
  4500                              <1> 	;pop	cx
  4501 00006DC8 6658                <1> 	pop	ax
  4502                              <1> 
  4503                              <1> 	;or	cl, cl
  4504 00006DCA 08C0                <1> 	or	al, al
  4505 00006DCC 7419                <1> 	jz	short copy_source_file_to_destination_OK
  4506                              <1> 	
  4507                              <1> 	; 18/03/2016
  4508                              <1> 	;cmp	cl, 1Dh ; write error
  4509 00006DCE 3C1D                <1> 	cmp	al, 1Dh
  4510 00006DD0 7506                <1> 	jne	short copy_source_file_to_destination_not_OK
  4511                              <1> 	;
  4512                              <1> 	;mov	al, cl ; error number (write fault!)
  4513 00006DD2 F9                  <1> 	stc
  4514 00006DD3 E9A5F2FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4515                              <1> 
  4516                              <1> copy_source_file_to_destination_not_OK:
  4517 00006DD8 BE[16C80000]        <1> 	mov	esi, Msg_read_file_error_before_EOF
  4518 00006DDD E8D2D1FFFF          <1> 	call	print_msg
  4519 00006DE2 E996F2FFFF          <1> 	jmp	loc_file_rw_restore_retn	      
  4520                              <1>  
  4521                              <1> copy_source_file_to_destination_OK:
  4522 00006DE7 BE[7BC60000]        <1> 	mov	esi, Msg_OK
  4523 00006DEC E8C3D1FFFF          <1> 	call	print_msg
  4524                              <1> 
  4525 00006DF1 E987F2FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4526                              <1> 
  4527                              <1> ;loc_file_write_check_disk_space_err:
  4528                              <1> 	;cmp	al, 27h ; Insufficient disk space 
  4529                              <1> 	;je	loc_file_write_insuff_disk_space_msg
  4530                              <1>         ;jb	loc_file_rw_cmd_failed
  4531                              <1> 
  4532                              <1> 	;call	print_misc_error_msg ; 15/03/2016
  4533                              <1>         ;jmp	loc_file_rw_restore_retn 
  4534                              <1> 
  4535                              <1> change_fs_file_attributes:
  4536                              <1> 	; 04/03/2016 ; Temporary
  4537                              <1> 	; AL = File or directory attributes
  4538                              <1> 	; AH = 0 -> Attributes are in MS-DOS format
  4539                              <1> 	; AH > 0 -> Attributes are in SINGLIX format
  4540                              <1> 	;push	ebx
  4541                              <1> 	; ... do somethings here ...
  4542                              <1> 	;pop	ebx
  4543                              <1> 	; BL = File or directory attributes
  4544 00006DF6 C3                  <1> 	retn
  4545                              <1> 
  4546                              <1> set_get_env:
  4547                              <1> 	; 11/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4548                              <1> 	; 02/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_set')
  4549                              <1> 	; 2005 - 28/08/2011 
  4550                              <1> get_setenv_fchar:
  4551                              <1> 	; esi = environment variable/string
  4552 00006DF7 8A06                <1> 	mov	al, [esi]
  4553 00006DF9 3C20                <1> 	cmp	al, 20h
  4554 00006DFB 771E                <1> 	ja	short loc_find_env
  4555                              <1> 
  4556 00006DFD BE00300900          <1> 	mov	esi, Env_Page
  4557                              <1> loc_print_setline:
  4558 00006E02 803E00              <1> 	cmp	byte [esi], 0
  4559 00006E05 7613                <1> 	jna	short loc_setenv_retn
  4560 00006E07 E8A8D1FFFF          <1> 	call	print_msg
  4561 00006E0C 56                  <1> 	push	esi
  4562 00006E0D BE[20CF0000]        <1> 	mov	esi, nextline
  4563 00006E12 E89DD1FFFF          <1> 	call	print_msg 
  4564 00006E17 5E                  <1> 	pop	esi
  4565 00006E18 EBE8                <1> 	jmp	short loc_print_setline   
  4566                              <1> 
  4567                              <1> loc_setenv_retn: 
  4568 00006E1A C3                  <1> 	retn
  4569                              <1> 
  4570                              <1> loc_find_env:
  4571 00006E1B 3C3D                <1> 	cmp	al, '='
  4572 00006E1D 0F8430E9FFFF        <1> 	je	loc_cmd_failed
  4573                              <1> 
  4574 00006E23 56                  <1> 	push	esi
  4575                              <1> loc_repeat_env_equal_check:
  4576 00006E24 46                  <1> 	inc	esi
  4577 00006E25 803E3D              <1> 	cmp	byte [esi], '='
  4578 00006E28 7431                <1> 	je	short pass_env_equal_check
  4579 00006E2A 803E20              <1> 	cmp	byte [esi], 20h
  4580 00006E2D 73F5                <1> 	jnb	short loc_repeat_env_equal_check
  4581 00006E2F C60600              <1> 	mov	byte [esi], 0 
  4582 00006E32 5E                  <1> 	pop	esi
  4583 00006E33 BF[4ED40000]        <1> 	mov	edi, TextBuffer ; out buffer
  4584 00006E38 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4585 00006E3D 30C0                <1> 	xor	al, al ; 0 -> use [ESI]
  4586 00006E3F E89E000000          <1> 	call	get_environment_string
  4587 00006E44 72D4                <1> 	jc	short loc_setenv_retn
  4588                              <1> 
  4589 00006E46 BE[4ED40000]        <1> 	mov	esi, TextBuffer
  4590 00006E4B E864D1FFFF          <1> 	call	print_msg
  4591 00006E50 BE[20CF0000]        <1> 	mov	esi, nextline
  4592 00006E55 E85AD1FFFF          <1> 	call	print_msg
  4593                              <1> 
  4594 00006E5A C3                  <1> 	retn 
  4595                              <1>               
  4596                              <1> pass_env_equal_check:
  4597 00006E5B 46                  <1> 	inc	esi
  4598 00006E5C 803E20              <1> 	cmp	byte [esi], 20h
  4599 00006E5F 73FA                <1> 	jnb	short pass_env_equal_check
  4600 00006E61 C60600              <1> 	mov	byte [esi], 0	
  4601                              <1> 
  4602                              <1> loc_call_set_env_string:
  4603 00006E64 5E                  <1> 	pop	esi
  4604 00006E65 E83B010000          <1> 	call	set_environment_string
  4605 00006E6A 73AE                <1> 	jnc	short loc_setenv_retn
  4606                              <1> 
  4607                              <1> loc_set_cmd_failed:
  4608 00006E6C 3C08                <1> 	cmp	al, 08h
  4609 00006E6E 0F85DFE8FFFF        <1> 	jne	loc_cmd_failed
  4610                              <1> 
  4611 00006E74 BE[56C80000]        <1> 	mov	esi, Msg_No_Set_Space
  4612 00006E79 E836D1FFFF          <1> 	call	print_msg
  4613                              <1> 
  4614 00006E7E C3                  <1> 	retn
  4615                              <1> 
  4616                              <1> set_get_path:
  4617                              <1> 	; 11/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4618                              <1> 	; 03/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_path')
  4619                              <1> 	; 2005
  4620                              <1> get_path_fchar:
  4621                              <1>  	; esi = path
  4622 00006E7F 803E20              <1> 	cmp	byte [esi], 20h
  4623 00006E82 7737                <1> 	ja	short loc_set_path
  4624                              <1> 
  4625 00006E84 BE00300900          <1> 	mov	esi, Env_Page
  4626                              <1> loc_print_path:
  4627 00006E89 803E00              <1> 	cmp	byte [esi], 0
  4628 00006E8C 762C                <1> 	jna	short loc_path_retn
  4629                              <1> 
  4630 00006E8E BE[AFC20000]        <1> 	mov	esi, Cmd_Path ; 'PATH' address
  4631 00006E93 BF[4ED40000]        <1> 	mov	edi, TextBuffer ; oout buffer
  4632 00006E98 30C0                <1> 	xor	al, al  ; use [ESI]
  4633 00006E9A B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4634 00006E9F E83E000000          <1> 	call	get_environment_string
  4635 00006EA4 7214                <1> 	jc	short loc_path_retn
  4636                              <1> 
  4637 00006EA6 BE[4ED40000]        <1> 	mov	esi, TextBuffer
  4638 00006EAB E804D1FFFF          <1> 	call	print_msg
  4639 00006EB0 BE[20CF0000]        <1> 	mov	esi, nextline
  4640 00006EB5 E8FAD0FFFF          <1> 	call	print_msg   
  4641                              <1> 
  4642                              <1> loc_path_retn: 
  4643 00006EBA C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> loc_set_path:
  4646 00006EBB 56                  <1> 	push	esi 
  4647                              <1> loc_set_path_find_end:
  4648 00006EBC 46                  <1> 	inc	esi
  4649 00006EBD 803E20              <1> 	cmp	byte [esi], 20h
  4650 00006EC0 73FA                <1> 	jnb	short loc_set_path_find_end
  4651 00006EC2 C60600              <1> 	mov	byte [esi], 0 
  4652                              <1> loc_set_path_header: 
  4653 00006EC5 5E                  <1> 	pop	esi	  
  4654 00006EC6 4E                  <1> 	dec	esi
  4655 00006EC7 C6063D              <1> 	mov	byte [esi], '='
  4656 00006ECA 4E                  <1> 	dec	esi
  4657 00006ECB C60648              <1> 	mov	byte [esi], 'H'
  4658 00006ECE 4E                  <1> 	dec	esi
  4659 00006ECF C60654              <1> 	mov	byte [esi], 'T'
  4660 00006ED2 4E                  <1> 	dec	esi
  4661 00006ED3 C60641              <1> 	mov	byte [esi], 'A'
  4662 00006ED6 4E                  <1> 	dec	esi
  4663 00006ED7 C60650              <1> 	mov	byte [esi], 'P'   
  4664                              <1> 
  4665                              <1> loc_path_call_set_env_string:
  4666 00006EDA E8C6000000          <1> 	call	set_environment_string
  4667 00006EDF 728B                <1>         jc	short loc_set_cmd_failed
  4668                              <1> 
  4669 00006EE1 C3                  <1> 	retn              
  4670                              <1> 
  4671                              <1> get_environment_string:
  4672                              <1> 	; 12/04/2016
  4673                              <1> 	; 11/04/2016
  4674                              <1> 	; 05/04/2016 (TRDOS 386 =  TRDOS v2.0)
  4675                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4676                              <1> 	; 28/08/2011
  4677                              <1> 	; INPUT->
  4678                              <1> 	;	EDI = Output buffer
  4679                              <1> 	;	CX = Buffer length (<= ENV_PAGE_SIZE)
  4680                              <1> 	;
  4681                              <1> 	;	AL > 0 = AL = String sequence number
  4682                              <1> 	;	AL = 0 -> ESI = ASCIIZ Set word 
  4683                              <1> 	;		(environment variable)
  4684                              <1> 	; OUTPUT ->
  4685                              <1> 	;	ESI is not changed
  4686                              <1> 	;	EDI is not changed
  4687                              <1> 	;	EAX = String length (with zero tail)
  4688                              <1> 	;	EDX = Environment variables page address
  4689                              <1> 	;	CF = 1 -> Not found (EAX not valid)
  4690                              <1> 	;
  4691                              <1> 	; (Modified registers: EAX, EDX) 
  4692                              <1> 
  4693 00006EE2 BA00300900          <1> 	mov	edx, Env_Page
  4694 00006EE7 803A00              <1> 	cmp	byte [edx], 0
  4695 00006EEA 7474                <1> 	jz	short get_env_string_with_word_stc_retn
  4696                              <1> 
  4697 00006EEC 66890D[B8DF0000]    <1> 	mov	[env_var_length], cx
  4698                              <1> 
  4699 00006EF3 51                  <1> 	push	ecx ; *
  4700 00006EF4 56                  <1> 	push	esi ; **
  4701                              <1> 
  4702 00006EF5 08C0                <1> 	or	al, al
  4703 00006EF7 7449                <1> 	jz	short get_env_string_with_word
  4704                              <1> 
  4705                              <1> get_env_string_with_seq_number:
  4706 00006EF9 B101                <1> 	mov	cl, 1
  4707 00006EFB 88C5                <1> 	mov	ch, al
  4708 00006EFD 31C0                <1> 	xor	eax, eax
  4709 00006EFF 89D6                <1> 	mov	esi, edx ; Env_Page
  4710                              <1> 
  4711                              <1> get_env_string_seq_number_check:
  4712 00006F01 38CD                <1> 	cmp	ch, cl
  4713 00006F03 7726                <1> 	ja	short get_env_string_seq_number_next
  4714                              <1> 
  4715                              <1> get_env_string_move_to_buff:
  4716 00006F05 57                  <1> 	push	edi ; ***
  4717                              <1> 
  4718 00006F06 29D2                <1> 	sub	edx, edx
  4719                              <1> 
  4720                              <1> get_env_string_seq_number_repeat1:
  4721 00006F08 42                  <1> 	inc	edx
  4722 00006F09 AC                  <1> 	lodsb
  4723 00006F0A AA                  <1> 	stosb
  4724                              <1> 
  4725 00006F0B 66FF0D[B8DF0000]    <1> 	dec	word [env_var_length]
  4726 00006F12 7508                <1> 	jnz	short get_env_string_seq_number_repeat3
  4727                              <1> 
  4728                              <1> get_env_string_seq_number_repeat2:
  4729 00006F14 20C0                <1> 	and	al, al
  4730 00006F16 7408                <1> 	jz	short get_env_string_seq_number_ok
  4731 00006F18 42                  <1> 	inc	edx
  4732 00006F19 AC                  <1> 	lodsb
  4733 00006F1A EBF8                <1> 	jmp	short get_env_string_seq_number_repeat2
  4734                              <1> 
  4735                              <1> get_env_string_seq_number_repeat3:
  4736 00006F1C 08C0                <1> 	or	al, al
  4737 00006F1E 75E8                <1> 	jnz	short get_env_string_seq_number_repeat1
  4738                              <1> 
  4739                              <1> get_env_string_seq_number_ok:
  4740 00006F20 5F                  <1> 	pop	edi ; ***
  4741 00006F21 89D0                <1> 	mov	eax, edx ; Length of the environment string
  4742                              <1> 			 ; (ASCIIZ, includes ZERO tail)
  4743 00006F23 BA00300900          <1> 	mov	edx, Env_Page
  4744                              <1> 
  4745                              <1> get_env_string_stc_retn:
  4746 00006F28 5E                  <1> 	pop	esi ; **
  4747 00006F29 59                  <1> 	pop	ecx ; *
  4748 00006F2A C3                  <1> 	retn   
  4749                              <1> 	
  4750                              <1> get_env_string_seq_number_next:
  4751 00006F2B AC                  <1> 	lodsb
  4752 00006F2C 08C0                <1> 	or	al, al
  4753 00006F2E 75FB                <1> 	jnz	short get_env_string_seq_number_next
  4754                              <1> 
  4755 00006F30 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; +512 (+4096)
  4756 00006F36 F5                  <1> 	cmc
  4757 00006F37 72EF                <1> 	jc	short get_env_string_stc_retn
  4758                              <1> 
  4759 00006F39 AC                  <1> 	lodsb
  4760 00006F3A 3C01                <1> 	cmp	al, 1
  4761 00006F3C 72EA                <1> 	jb	short get_env_string_stc_retn
  4762 00006F3E FEC1                <1> 	inc	cl
  4763 00006F40 EBBF                <1> 	jmp	short get_env_string_seq_number_check
  4764                              <1> 
  4765                              <1> get_env_string_with_word:
  4766 00006F42 31C9                <1> 	xor	ecx, ecx
  4767                              <1> 
  4768                              <1> get_env_string_calc_word_length:
  4769 00006F44 AC                  <1> 	lodsb 
  4770 00006F45 3C20                <1> 	cmp	al, 20h
  4771 00006F47 7211                <1> 	jb	short get_env_string_calc_word_length_ok
  4772                              <1> 	;inc	cx
  4773 00006F49 FEC1                <1> 	inc	cl
  4774                              <1> 
  4775 00006F4B 3C61                <1> 	cmp	al, 'a'
  4776 00006F4D 72F5                <1> 	jb	short get_env_string_calc_word_length
  4777 00006F4F 3C7A                <1> 	cmp	al, 'z'
  4778 00006F51 77F1                <1> 	ja	short get_env_string_calc_word_length
  4779 00006F53 24DF                <1> 	and	al, 0DFh
  4780 00006F55 8846FF              <1> 	mov	[esi-1], al
  4781 00006F58 EBEA                <1> 	jmp	short get_env_string_calc_word_length
  4782                              <1> 	
  4783                              <1> get_env_string_calc_word_length_ok:
  4784 00006F5A 08C9                <1> 	or	cl, cl
  4785 00006F5C 7506                <1> 	jnz	short get_env_string_calc_word_length_save
  4786                              <1>      
  4787 00006F5E 5E                  <1> 	pop	esi ; **
  4788                              <1> 
  4789                              <1> get_env_string_stc_retn1:
  4790 00006F5F 59                  <1> 	pop	ecx ; *
  4791                              <1>         
  4792                              <1> get_env_string_with_word_stc_retn:
  4793 00006F60 31C0                <1> 	xor	eax, eax  
  4794 00006F62 F9                  <1> 	stc
  4795 00006F63 C3                  <1> 	retn
  4796                              <1>   
  4797                              <1> get_env_string_calc_word_length_save:
  4798 00006F64 871C24              <1> 	xchg	ebx, [esp] ; **
  4799 00006F67 89DE                <1> 	mov	esi, ebx 
  4800                              <1> 		; Start of the env string (to be searched)
  4801                              <1> 
  4802 00006F69 57                  <1> 	push	edi ; ***
  4803 00006F6A 89D7                <1> 	mov	edi, edx ; Env_Page
  4804                              <1> 
  4805                              <1> get_env_string_compare:
  4806 00006F6C 57                  <1> 	push	edi ; ****
  4807 00006F6D 51                  <1> 	push	ecx ; ***** ; Variable name length
  4808                              <1> 
  4809                              <1> get_env_string_compare_rep:
  4810 00006F6E AC                  <1> 	lodsb
  4811 00006F6F AE                  <1> 	scasb
  4812 00006F70 7511                <1> 	jne	short get_env_string_compare_next1
  4813 00006F72 E2FA                <1> 	loop	get_env_string_compare_rep
  4814                              <1> 	
  4815 00006F74 803F3D              <1> 	cmp	byte [edi], '='
  4816 00006F77 750A                <1> 	jne	short get_env_string_compare_next1
  4817                              <1>  
  4818 00006F79 59                  <1> 	pop	ecx ; *****
  4819 00006F7A 5F                  <1> 	pop	edi ; ****
  4820 00006F7B 89FE                <1> 	mov	esi, edi
  4821 00006F7D 5F                  <1> 	pop	edi ; ***
  4822 00006F7E 871C24              <1> 	xchg	ebx, [esp] ; **
  4823 00006F81 EB82                <1> 	jmp	short get_env_string_move_to_buff
  4824                              <1> 
  4825                              <1> get_env_string_compare_next1:
  4826 00006F83 89FE                <1> 	mov	esi, edi
  4827 00006F85 59                  <1> 	pop	ecx ; *****
  4828 00006F86 5F                  <1> 	pop	edi ; ****
  4829                              <1> get_env_string_compare_next2:
  4830 00006F87 81FEFF310900        <1> 	cmp	esi, Env_Page + Env_Page_Size - 1 ; +511 (+4095)
  4831 00006F8D 7310                <1> 	jnb	short get_env_string_compare_not_ok
  4832 00006F8F 20C0                <1> 	and	al, al
  4833 00006F91 AC                  <1> 	lodsb
  4834 00006F92 75F3                <1> 	jnz	short get_env_string_compare_next2
  4835 00006F94 08C0                <1> 	or	al, al
  4836 00006F96 7407                <1> 	jz	short get_env_string_compare_not_ok
  4837 00006F98 4E                  <1> 	dec	esi ; 12/04/2016
  4838 00006F99 89F7                <1> 	mov	edi, esi
  4839 00006F9B 89DE                <1> 	mov	esi, ebx
  4840 00006F9D EBCD                <1> 	jmp	short get_env_string_compare
  4841                              <1> 
  4842                              <1> get_env_string_compare_not_ok:
  4843 00006F9F 5F                  <1> 	pop	edi ; ***
  4844 00006FA0 89DE                <1> 	mov	esi, ebx
  4845 00006FA2 5B                  <1> 	pop	ebx ; **
  4846 00006FA3 EBBA                <1> 	jmp	short get_env_string_stc_retn1
  4847                              <1> 
  4848                              <1> set_environment_string:
  4849                              <1> 	; 13/04/2016
  4850                              <1> 	; 12/04/2016
  4851                              <1> 	; 11/04/2016
  4852                              <1> 	; 06/04/2016
  4853                              <1> 	; 05/04/2016 (TRDOS 386 = TRDOS v2.0)
  4854                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4855                              <1> 	; 29/08/2011
  4856                              <1> 	; 29/08/2011
  4857                              <1> 	; INPUT->
  4858                              <1> 	;	ESI = ASCIIZ environment string
  4859                              <1> 	; OUTPUT ->
  4860                              <1> 	;	ESI is not changed
  4861                              <1> 	;	CF = 1 -> Could not set, 
  4862                              <1> 	;	     insufficient environment space
  4863                              <1> 	;
  4864                              <1> 	; (EAX, EDX will be changed) 
  4865                              <1> 	;
  4866                              <1> 	;    (EAX = Start address of the env string if > 0)	
  4867                              <1> 	;    (EDX = Environment string length)	
  4868                              <1> 
  4869 00006FA5 56                  <1> 	push 	esi ; *
  4870                              <1> 
  4871 00006FA6 31C0                <1> 	xor	eax, eax
  4872                              <1> 
  4873                              <1> set_env_chk_validation1:
  4874 00006FA8 FEC4                <1> 	inc	ah ; variable (string) length
  4875 00006FAA AC                  <1> 	lodsb
  4876 00006FAB 3C3D                <1> 	cmp	al, '='
  4877 00006FAD 7415                <1> 	je	short set_env_chk_validation2
  4878 00006FAF 3C20                <1> 	cmp	al, 20h
  4879 00006FB1 720F                <1> 	jb	short set_env_string_stc
  4880                              <1> 
  4881                              <1> 	; 06/04/2016
  4882 00006FB3 3C61                <1> 	cmp	al, 'a'
  4883 00006FB5 72F1                <1> 	jb	short set_env_chk_validation1
  4884 00006FB7 3C7A                <1> 	cmp	al, 'z'
  4885 00006FB9 77ED                <1> 	ja	short set_env_chk_validation1
  4886 00006FBB 2C20                <1> 	sub	al, 'a'-'A'
  4887 00006FBD 8846FF              <1> 	mov	[esi-1], al
  4888 00006FC0 EBE6                <1> 	jmp	short set_env_chk_validation1
  4889                              <1> 
  4890                              <1> set_env_string_stc:
  4891 00006FC2 5E                  <1> 	pop	esi ; *
  4892                              <1> 	;stc
  4893 00006FC3 C3                  <1> 	retn 
  4894                              <1> 	   
  4895                              <1> set_env_chk_validation2:
  4896 00006FC4 51                  <1> 	push	ecx ; **
  4897 00006FC5 53                  <1> 	push	ebx ; *** 
  4898 00006FC6 57                  <1> 	push	edi ; ****
  4899                              <1> 
  4900                              <1> 	; 12/04/2016
  4901 00006FC7 8B5C240C            <1> 	mov	ebx, [esp+12]
  4902                              <1> 
  4903                              <1> set_env_chk_validation2w:
  4904 00006FCB 89F7                <1> 	mov	edi, esi
  4905 00006FCD 4F                  <1> 	dec	edi
  4906                              <1> 
  4907 00006FCE 807FFF20            <1> 	cmp	byte [edi-1], 20h
  4908 00006FD2 771A                <1> 	ja	short set_env_chk_validation2z
  4909                              <1> 	
  4910 00006FD4 56                  <1> 	push	esi
  4911 00006FD5 89FE                <1> 	mov	esi, edi
  4912 00006FD7 4E                  <1> 	dec	esi
  4913                              <1> 
  4914                              <1> set_env_chk_validation2x:
  4915 00006FD8 4E                  <1> 	dec	esi
  4916                              <1> 
  4917 00006FD9 39DE                <1> 	cmp	esi, ebx
  4918 00006FDB 7207                <1> 	jb	short set_env_chk_validation2y
  4919                              <1> 
  4920 00006FDD 4F                  <1> 	dec	edi
  4921                              <1> 
  4922 00006FDE 8A06                <1> 	mov	al, [esi]
  4923 00006FE0 8807                <1> 	mov	[edi], al
  4924                              <1> 
  4925 00006FE2 EBF4                <1> 	jmp	short set_env_chk_validation2x
  4926                              <1> 
  4927                              <1> set_env_chk_validation2y:
  4928 00006FE4 5E                  <1> 	pop	esi
  4929                              <1> 
  4930                              <1> 	;mov	byte [ebx], 20h
  4931                              <1> 	
  4932 00006FE5 43                  <1> 	inc 	ebx
  4933 00006FE6 895C240C            <1> 	mov	[esp+12], ebx
  4934                              <1> 
  4935 00006FEA FECC                <1> 	dec 	ah ; 13/04/2016
  4936                              <1> 
  4937 00006FEC EBDD                <1> 	jmp	short set_env_chk_validation2w
  4938                              <1> 	
  4939                              <1> set_env_chk_validation2z:	
  4940 00006FEE BA00300900          <1> 	mov	edx, Env_Page
  4941 00006FF3 89D7                <1> 	mov	edi, edx
  4942                              <1> 
  4943                              <1> set_env_chk_validation3:
  4944 00006FF5 AC                  <1> 	lodsb
  4945 00006FF6 3C20                <1> 	cmp	al, 20h
  4946 00006FF8 74FB                <1> 	je	short set_env_chk_validation3
  4947                              <1> 
  4948 00006FFA 9C                  <1> 	pushf
  4949                              <1> 
  4950                              <1> 	; 12/04/2016
  4951                              <1> set_env_chk_validation3n:
  4952 00006FFB 3C61                <1> 	cmp	al, 'a'
  4953 00006FFD 720C                <1> 	jb	short set_env_chk_validation3c
  4954 00006FFF 3C7A                <1> 	cmp	al, 'z'
  4955 00007001 7705                <1> 	ja	short set_env_chk_validation3x
  4956 00007003 2C20                <1> 	sub	al, 'a'-'A'
  4957 00007005 8846FF              <1> 	mov	[esi-1], al
  4958                              <1> 
  4959                              <1> set_env_chk_validation3x:
  4960 00007008 AC                  <1> 	lodsb
  4961 00007009 EBF0                <1> 	jmp	short set_env_chk_validation3n
  4962                              <1> 
  4963                              <1> set_env_chk_validation3c:
  4964 0000700B 3C20                <1> 	cmp	al, 20h
  4965 0000700D 73F9                <1> 	jnb	short set_env_chk_validation3x
  4966                              <1> 		
  4967 0000700F 803F00              <1> 	cmp	byte [edi], 0
  4968 00007012 7731                <1> 	ja	short set_env_chk_validation4
  4969                              <1> 
  4970 00007014 9D                  <1> 	popf
  4971 00007015 7228                <1> 	jb	short set_env_string_nothing
  4972                              <1> 
  4973 00007017 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)
  4974                              <1> 
  4975 0000701C 89DE                <1> 	mov	esi, ebx ; 12/04/2016
  4976                              <1> 
  4977                              <1> set_env_string_copy_to_envb:
  4978 0000701E AC                  <1> 	lodsb
  4979 0000701F 3C20                <1> 	cmp	al, 20h
  4980 00007021 720A                <1> 	jb	short set_env_string_copy_to_envb_z
  4981 00007023 AA                  <1> 	stosb
  4982 00007024 E2F8                <1> 	loop	set_env_string_copy_to_envb
  4983                              <1> 
  4984                              <1> 	; 11/04/2016
  4985 00007026 89D7                <1> 	mov	edi, edx ; Env_Page
  4986 00007028 B900020000          <1> 	mov	ecx, Env_Page_Size 
  4987                              <1> 
  4988                              <1> set_env_string_copy_to_envb_z:
  4989 0000702D 52                  <1> 	push	edx  ; Start address of the variable
  4990 0000702E BA00020000          <1> 	mov	edx, Env_Page_Size
  4991 00007033 29CA                <1> 	sub	edx, ecx ; variable (string) length
  4992                              <1> 
  4993 00007035 28C0                <1> 	sub	al, al ; 0
  4994 00007037 F3AA                <1>  	rep	stosb ; clear remain bytes of the env page
  4995                              <1> 
  4996 00007039 58                  <1> 	pop	eax  ; Start address of the variable
  4997                              <1> 
  4998                              <1> set_env_string_allocate_envb_retn:  ; stc or clc return
  4999 0000703A 5F                  <1> 	pop	edi ; ****
  5000 0000703B 5B                  <1> 	pop	ebx ; ***
  5001 0000703C 59                  <1> 	pop	ecx ; **
  5002 0000703D 5E                  <1> 	pop	esi ; *	
  5003 0000703E C3                  <1> 	retn
  5004                              <1> 
  5005                              <1> set_env_string_nothing:
  5006 0000703F 31C0                <1> 	xor	eax, eax
  5007 00007041 31D2                <1> 	xor	edx, edx ; 11/04/2016
  5008 00007043 EBF5                <1> 	jmp	short set_env_string_allocate_envb_retn
  5009                              <1> 
  5010                              <1> set_env_chk_validation4:
  5011                              <1> 	; 11/04/2016
  5012 00007045 9D                  <1> 	popf
  5013                              <1> 
  5014 00007046 89D6                <1> 	mov	esi, edx  ; Env_Page
  5015                              <1> 
  5016                              <1> set_env_chk_validation5:	
  5017 00007048 89DF                <1> 	mov	edi, ebx  ; ASCIIZ environment string address	
  5018 0000704A 0FB6CC              <1> 	movzx	ecx, ah ; Variable (string) length (with '=')
  5019                              <1> 
  5020                              <1> set_env_chk_validation5_loop:
  5021 0000704D AC                  <1> 	lodsb
  5022 0000704E AE                  <1> 	scasb
  5023 0000704F 750A                <1> 	jne	short set_env_chk_validation6
  5024 00007051 E2FA                <1> 	loop	set_env_chk_validation5_loop
  5025                              <1> 
  5026 00007053 3C3D                <1> 	cmp	al, '='
  5027 00007055 0F8483000000        <1>         je      set_env_change_variable
  5028                              <1> 
  5029                              <1> set_env_chk_validation6:
  5030 0000705B 08C0                <1> 	or	al, al ; 0
  5031 0000705D 7403                <1> 	jz	short set_env_chk_validation7
  5032                              <1> 
  5033 0000705F AC                  <1> 	lodsb
  5034 00007060 EBF9                <1> 	jmp	short set_env_chk_validation6
  5035                              <1> 
  5036                              <1> set_env_chk_validation7:
  5037 00007062 88E1                <1> 	mov	cl, ah
  5038 00007064 01F1                <1> 	add	ecx, esi
  5039 00007066 81F9FF310900        <1> 	cmp	ecx, Env_Page + Env_Page_Size - 1 
  5040                              <1> 		; 511 (4095) 
  5041                              <1> 		; strlen + '=' + 0
  5042 0000706C 72DA                <1> 	jb	short set_env_chk_validation5
  5043                              <1> 
  5044                              <1> set_env_chk_validation8: ; variable not found
  5045 0000706E 0FB6F4              <1> 	movzx	esi, ah  ; variable name length (with '=') 
  5046 00007071 01DE                <1> 	add	esi, ebx ; position just after of the '='
  5047                              <1> 
  5048                              <1> set_env_chk_validation8_loop:
  5049 00007073 AC                  <1> 	lodsb
  5050 00007074 3C20                <1> 	cmp	al, 20h
  5051 00007076 74FB                <1> 	je	short set_env_chk_validation8_loop	
  5052 00007078 72C5                <1> 	jb	short set_env_string_nothing
  5053                              <1> 
  5054                              <1> set_env_chk_validation9:
  5055 0000707A AC                  <1> 	lodsb
  5056 0000707B 3C20                <1> 	cmp	al, 20h
  5057 0000707D 73FB                <1> 	jnb	short set_env_chk_validation9
  5058                              <1> 
  5059                              <1> 	; End of ASCIIZ environment string
  5060                              <1> 
  5061                              <1> set_env_add_variable:
  5062 0000707F 29DE                <1> 	sub	esi, ebx ; variable+definition length
  5063                              <1> 	
  5064 00007081 56                  <1> 	push	esi ; *****
  5065                              <1> 
  5066 00007082 89D6                <1> 	mov	esi, edx ; Environment page address
  5067                              <1> 
  5068 00007084 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)	
  5069                              <1> 
  5070                              <1> set_env_add_variable_loop:
  5071 00007089 AC                  <1> 	lodsb
  5072 0000708A 20C0                <1> 	and	al, al		
  5073 0000708C 7406                <1> 	jz	short set_env_add_variable_chk1 ; 0
  5074 0000708E E2F9                <1> 	loop	set_env_add_variable_loop
  5075                              <1> 
  5076                              <1> 	; 11/04/2016
  5077 00007090 884EFF              <1> 	mov	[esi-1], cl ; 0
  5078 00007093 41                  <1> 	inc	ecx
  5079                              <1> 	
  5080                              <1> set_env_add_variable_chk1: 
  5081 00007094 49                  <1> 	dec	ecx
  5082 00007095 7408                <1> 	jz	short set_env_add_variable_nspc
  5083 00007097 AC                  <1> 	lodsb
  5084 00007098 08C0                <1> 	or 	al, al
  5085 0000709A 740C                <1> 	jz	short set_env_add_variable_chk2 ; 00
  5086 0000709C 49                  <1> 	dec	ecx
  5087 0000709D 75EA                <1> 	jnz	short set_env_add_variable_loop
  5088                              <1> 
  5089                              <1> set_env_add_variable_nspc: ; no space on environment page
  5090 0000709F 58                  <1> 	pop	eax ; *****
  5091 000070A0 B808000000          <1> 	mov	eax, 08h ; No space for new environment string
  5092 000070A5 F9                  <1> 	stc
  5093 000070A6 EB92                <1>         jmp     short set_env_string_allocate_envb_retn
  5094                              <1> 
  5095                              <1> set_env_add_variable_chk2:
  5096 000070A8 8B0C24              <1> 	mov	ecx, [esp] ; *****
  5097 000070AB 4E                  <1> 	dec	esi ; beginning address of the new variable
  5098 000070AC 89F0                <1> 	mov	eax, esi
  5099 000070AE 01C8                <1> 	add	eax, ecx ; string length (with CR)
  5100 000070B0 81C200020000        <1> 	add	edx, Env_Page_Size ; 512 (4096)
  5101 000070B6 39D0                <1> 	cmp	eax, edx 
  5102 000070B8 77E5                <1> 	ja	short set_env_add_variable_nspc
  5103 000070BA 49                  <1> 	dec	ecx ; except CR at the end
  5104 000070BB 89CA                <1> 	mov	edx, ecx ; 12/04/2016
  5105 000070BD 89F7                <1> 	mov	edi, esi
  5106 000070BF 893C24              <1> 	mov	[esp], edi ; ***** ; Start address of new variable
  5107 000070C2 89DE                <1> 	mov	esi, ebx ; ASCIIZ environment string address
  5108 000070C4 F3A4                <1> 	rep	movsb
  5109 000070C6 28C0                <1> 	sub	al, al
  5110 000070C8 AA                  <1> 	stosb
  5111 000070C9 58                  <1> 	pop	eax ; ***** ; Beginning address of new variable			
  5112 000070CA 81FF00320900        <1>         cmp     edi, Env_Page + Env_Page_Size ; 12/04/2016
  5113 000070D0 0F8364FFFFFF        <1>         jnb     set_env_string_allocate_envb_retn ; OK !
  5114 000070D6 880F                <1> 	mov	[edi], cl ; 0
  5115 000070D8 F8                  <1> 	clc	; 13/04/2016
  5116 000070D9 E95CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5117                              <1> 
  5118                              <1> set_env_change_variable:
  5119                              <1> 	; 06/04/2016
  5120                              <1> 	; esi = Variable's address in environment page (after '=')
  5121                              <1> 	; edi = ASCIIZ environment string address (after '=')
  5122                              <1> 
  5123                              <1> 	; ah = variable length from start to the '='
  5124 000070DE 8825[B8DF0000]      <1> 	mov	[env_var_length], ah
  5125                              <1> 
  5126 000070E4 28C9                <1> 	sub	cl, cl ; ecx = 0
  5127                              <1> 
  5128 000070E6 57                  <1> 	push	edi ; *****
  5129                              <1> 
  5130 000070E7 89F7                <1> 	mov	edi, esi ; 11/04/2016
  5131                              <1> 
  5132                              <1> set_env_change_variable_calc1:
  5133 000070E9 AC                  <1> 	lodsb
  5134 000070EA 08C0                <1> 	or	al, al
  5135 000070EC 7403                <1> 	jz	short set_env_change_variable_calc2
  5136                              <1> 
  5137 000070EE 41                  <1> 	inc	ecx ; length of environment string (after the '=')
  5138                              <1> 
  5139 000070EF EBF8                <1> 	jmp	short set_env_change_variable_calc1	
  5140                              <1> 
  5141                              <1> set_env_change_variable_calc2:
  5142 000070F1 8B3424              <1> 	mov	esi, [esp] ; ASCIIZ environment string address
  5143                              <1> 	
  5144 000070F4 29D2                <1> 	sub	edx, edx
  5145                              <1> 
  5146                              <1> set_env_change_variable_calc3:
  5147 000070F6 AC                  <1> 	lodsb
  5148 000070F7 3C20                <1> 	cmp	al, 20h
  5149 000070F9 7203                <1> 	jb	short set_env_change_variable_calc4
  5150                              <1> 
  5151 000070FB 42                  <1> 	inc	edx ; length of ASCIIZ string (after the '=')
  5152                              <1> 	
  5153 000070FC EBF8                <1> 	jmp	short set_env_change_variable_calc3
  5154                              <1> 	
  5155                              <1> set_env_change_variable_calc4:
  5156 000070FE C646FF00            <1> 	mov	byte [esi-1], 0  ; put ZERO instead of CR
  5157                              <1> 	
  5158 00007102 5E                  <1> 	pop	esi ; ***** ; ASCIIZ string address (after '=')
  5159                              <1> 
  5160                              <1> 	; EDI = Old variable's address (after '=')
  5161                              <1> 	
  5162                              <1> 	; compare the new string with the old string
  5163 00007103 39CA                <1> 	cmp	edx, ecx
  5164 00007105 7717                <1> 	ja	short set_env_change_variable_calc5 ; longer
  5165 00007107 0F828F000000        <1>         jb      set_env_change_variable_calc9 ; shorter
  5166                              <1> 	
  5167                              <1> 	;same length (simple copy)
  5168 0000710D 0FB6C4              <1> 	movzx	eax, ah
  5169 00007110 01C2                <1> 	add	edx, eax
  5170 00007112 F7D8                <1> 	neg	eax
  5171 00007114 01F8                <1> 	add	eax, edi
  5172                              <1> 	; EAX = Start address of the variable
  5173                              <1> 	; EDX = Variable length (without ZERO at the end of variable)
  5174                              <1> 
  5175 00007116 F3A4                <1> 	rep	movsb
  5176 00007118 F8                  <1> 	clc	; 13/04/2016
  5177 00007119 E91CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5178                              <1> 
  5179                              <1> set_env_change_variable_calc5:
  5180                              <1> 	; 11/04/2016
  5181 0000711E 52                  <1> 	push	edx ; *****
  5182 0000711F 29CA                <1> 	sub	edx, ecx ; difference ; (the new string is longer)
  5183 00007121 89F3                <1> 	mov 	ebx, esi
  5184 00007123 89FE                <1> 	mov	esi, edi
  5185                              <1> 
  5186                              <1> set_env_change_variable_calc6:
  5187 00007125 AC                  <1> 	lodsb 
  5188 00007126 20C0                <1> 	and	al, al
  5189 00007128 75FB                <1> 	jnz	short set_env_change_variable_calc6
  5190                              <1> 
  5191 0000712A 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5192 00007130 0F8369FFFFFF        <1>         jnb     set_env_add_variable_nspc
  5193                              <1> 
  5194 00007136 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5195 00007138 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5196                              <1> 
  5197 0000713A AC                  <1> 	lodsb
  5198 0000713B 08C0                <1> 	or	al, al
  5199 0000713D 7416                <1> 	jz	short set_env_change_variable_calc8 ; 00
  5200                              <1> 
  5201                              <1> set_env_change_variable_calc7:
  5202 0000713F AC                  <1> 	lodsb
  5203 00007140 20C0                <1> 	and	al, al
  5204 00007142 75FB                <1> 	jnz	short set_env_change_variable_calc7
  5205                              <1> 
  5206 00007144 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5207 0000714A 0F834FFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5208                              <1> 
  5209 00007150 AC                  <1> 	lodsb
  5210 00007151 08C0                <1> 	or	al, al
  5211 00007153 75EA                <1> 	jnz	short set_env_change_variable_calc7
  5212                              <1> 
  5213                              <1> set_env_change_variable_calc8:
  5214 00007155 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5215                              <1> 
  5216 00007156 01F2                <1> 	add	edx, esi ; final position of the last 0
  5217                              <1> 
  5218 00007158 81FA00320900        <1> 	cmp	edx, Env_Page + Env_Page_Size ; 512 (4096)
  5219 0000715E 0F833BFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5220                              <1> 
  5221 00007164 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5222                              <1> 
  5223 00007166 89F1                <1> 	mov	ecx, esi 
  5224 00007168 29F9                <1> 	sub	ecx, edi ; count of bytes to move forward
  5225                              <1> 
  5226                              <1> 	; 13/04/2016
  5227 0000716A C60200              <1> 	mov	byte [edx], 0
  5228 0000716D 89D7                <1> 	mov	edi, edx
  5229 0000716F 29F2                <1> 	sub	edx, esi ; difference (additional byte count)
  5230 00007171 4F                  <1> 	dec	edi ; the last zero address (first byte of the 00)
  5231 00007172 89FE                <1> 	mov	esi, edi
  5232 00007174 29D6                <1> 	sub	esi, edx ; - displacement
  5233                              <1> 	
  5234 00007176 FA                  <1> 	cli	; disable interrupts
  5235 00007177 FD                  <1> 	std	; backward
  5236                              <1> 
  5237 00007178 F3A4                <1> 	rep	movsb ; move ECX bytes from DS:ESI to ES:EDI
  5238                              <1> 
  5239 0000717A FC                  <1> 	cld	; forward (default)
  5240 0000717B FB                  <1> 	sti	; enable interrupts
  5241                              <1> 	
  5242 0000717C 89C7                <1> 	mov	edi, eax
  5243 0000717E 59                  <1> 	pop	ecx ; ***** ; byte count (after '=')
  5244 0000717F 89CA                <1> 	mov	edx, ecx
  5245 00007181 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5246 00007183 89FB                <1> 	mov	ebx, edi
  5247                              <1> 
  5248 00007185 F3A4                <1> 	rep	movsb
  5249                              <1> 
  5250 00007187 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5251                              <1> 
  5252 00007189 0FB605[B8DF0000]    <1> 	movzx	eax, byte [env_var_length]
  5253 00007190 01C2                <1> 	add	edx, eax ; variable length (total)
  5254 00007192 F7D8                <1> 	neg	eax
  5255 00007194 01D8                <1> 	add	eax, ebx ; start address of the variable
  5256 00007196 F8                  <1> 	clc	; 13/04/2016
  5257 00007197 E99EFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5258                              <1> 
  5259                              <1> set_env_change_variable_calc9:
  5260                              <1> 	; 11/04/2016
  5261 0000719C 21D2                <1> 	and	edx, edx ; is empty ?
  5262 0000719E 753B                <1> 	jnz	short set_env_change_variable_calc15
  5263                              <1> 	
  5264 000071A0 0FB6DC              <1> 	movzx	ebx, ah
  5265 000071A3 F7DB                <1> 	neg	ebx
  5266 000071A5 01FB                <1> 	add	ebx, edi
  5267                              <1> 
  5268                              <1> 	; EBX = Start address of the variable (in env page)
  5269                              <1> 	; EDX = Variable length = 0
  5270                              <1> 	
  5271 000071A7 89FE                <1> 	mov	esi, edi
  5272                              <1> 
  5273                              <1> set_env_change_variable_calc10:
  5274 000071A9 AC                  <1> 	lodsb
  5275 000071AA 08C0                <1> 	or	al, al
  5276 000071AC 75FB                <1> 	jnz	short set_env_change_variable_calc10
  5277                              <1> 
  5278 000071AE B9FF310900          <1> 	mov	ecx, Env_Page + Env_Page_Size - 1
  5279                              <1> 
  5280 000071B3 39CE                <1> 	cmp	esi, ecx ; +511 (+4095)
  5281 000071B5 7604                <1> 	jna	short set_env_change_variable_calc11
  5282                              <1> 
  5283 000071B7 89CE                <1> 	mov	esi, ecx
  5284 000071B9 8806                <1> 	mov	[esi], al ; 0
  5285                              <1> 
  5286                              <1> set_env_change_variable_calc11:
  5287 000071BB 89DF                <1> 	mov	edi, ebx ; old variable's start address
  5288                              <1> 
  5289                              <1> set_env_change_variable_calc12:
  5290 000071BD AC                  <1> 	lodsb
  5291 000071BE AA                  <1> 	stosb
  5292 000071BF 20C0                <1> 	and	al, al
  5293 000071C1 75FA                <1> 	jnz	short set_env_change_variable_calc12
  5294 000071C3 39CE                <1> 	cmp	esi, ecx
  5295 000071C5 7706                <1> 	ja	short set_env_change_variable_calc13
  5296 000071C7 AC                  <1> 	lodsb
  5297 000071C8 AA                  <1> 	stosb
  5298 000071C9 20C0                <1> 	and	al, al
  5299 000071CB 75F0                <1> 	jnz	short set_env_change_variable_calc12	
  5300                              <1> 
  5301                              <1> set_env_change_variable_calc13:
  5302 000071CD 29F9                <1> 	sub	ecx, edi
  5303 000071CF 7203                <1> 	jb	short set_env_change_variable_calc14
  5304 000071D1 41                  <1> 	inc	ecx ; 1-512 (1-4096)
  5305 000071D2 F3AA                <1> 	rep	stosb ; al = 0	
  5306                              <1> 
  5307                              <1> set_env_change_variable_calc14:
  5308 000071D4 29C0                <1> 	sub	eax, eax ; Start address of the variable
  5309                              <1> 	; EAX = 0 -> Variable is removed
  5310                              <1> 	; EDX = Variable length = 0	
  5311                              <1> 
  5312 000071D6 E95FFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5313                              <1> 	    
  5314                              <1> set_env_change_variable_calc15:	
  5315 000071DB 52                  <1> 	push	edx ; *****
  5316 000071DC F7DA                <1> 	neg	edx
  5317 000071DE 01CA                <1> 	add	edx, ecx ; difference (the old string is longer)
  5318 000071E0 89F3                <1> 	mov 	ebx, esi
  5319 000071E2 89FE                <1> 	mov	esi, edi
  5320                              <1> 
  5321                              <1> set_env_change_variable_calc16:
  5322 000071E4 AC                  <1> 	lodsb 
  5323 000071E5 20C0                <1> 	and	al, al
  5324 000071E7 75FB                <1> 	jnz	short set_env_change_variable_calc16
  5325                              <1> 
  5326 000071E9 B900320900          <1> 	mov	ecx, Env_Page + Env_Page_Size
  5327                              <1> 
  5328 000071EE 39CE                <1> 	cmp	esi, ecx ; +512 (+4096)
  5329 000071F0 7605                <1> 	jna	short set_env_change_variable_calc17
  5330                              <1> 
  5331 000071F2 89CE                <1> 	mov	esi, ecx
  5332 000071F4 8846FF              <1> 	mov	[esi-1], al ; 0
  5333                              <1> 
  5334                              <1> set_env_change_variable_calc17:
  5335 000071F7 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5336 000071F9 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5337                              <1> 
  5338 000071FB AC                  <1> 	lodsb
  5339 000071FC 08C0                <1> 	or	al, al
  5340 000071FE 741D                <1> 	jz	short set_env_change_variable_calc20
  5341                              <1> 
  5342                              <1> set_env_change_variable_calc18:
  5343 00007200 AC                  <1> 	lodsb
  5344 00007201 20C0                <1> 	and	al, al
  5345 00007203 75FB                <1> 	jnz	short set_env_change_variable_calc18
  5346                              <1> 
  5347 00007205 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size
  5348 0000720B 720B                <1> 	jb	short set_env_change_variable_calc19
  5349 0000720D 740E                <1> 	je	short set_env_change_variable_calc20
  5350                              <1> 
  5351 0000720F BEFF310900          <1> 	mov	esi, Env_Page + Env_Page_Size - 1
  5352 00007214 8806                <1> 	mov	[esi], al ; 0
  5353 00007216 EB06                <1> 	jmp	short set_env_change_variable_calc21
  5354                              <1> 
  5355                              <1> set_env_change_variable_calc19:
  5356 00007218 AC                  <1> 	lodsb
  5357 00007219 08C0                <1> 	or	al, al
  5358 0000721B 75E3                <1> 	jnz	short set_env_change_variable_calc18
  5359                              <1> 
  5360                              <1> set_env_change_variable_calc20:
  5361 0000721D 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5362                              <1> 
  5363                              <1> set_env_change_variable_calc21:
  5364                              <1> 	; edx = difference (byte count)
  5365                              <1> 	
  5366 0000721E 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5367                              <1> 
  5368 00007220 89F1                <1> 	mov	ecx, esi 
  5369 00007222 29F9                <1> 	sub	ecx, edi ; count of bytes to move backward
  5370                              <1> 
  5371 00007224 89FE                <1> 	mov	esi, edi ; next variable's address
  5372 00007226 29D7                <1> 	sub	edi, edx ; (displacement)
  5373                              <1> 	
  5374 00007228 F3A4                <1> 	rep	movsb
  5375                              <1> 
  5376 0000722A 880F                <1> 	mov	[edi], cl ; 0 ; 00 ; end of environment variables
  5377                              <1> 
  5378 0000722C 89C7                <1> 	mov	edi, eax
  5379 0000722E 5A                  <1> 	pop	edx ; ***** ; byte count (after '=')
  5380 0000722F 89D1                <1> 	mov	ecx, edx
  5381 00007231 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5382 00007233 89FB                <1> 	mov	ebx, edi
  5383                              <1> 	
  5384 00007235 F3A4                <1> 	rep	movsb
  5385                              <1> 
  5386 00007237 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5387                              <1> 
  5388 00007239 0FB605[B8DF0000]    <1> 	movzx	eax, byte [env_var_length]
  5389 00007240 01C2                <1> 	add	edx, eax ; variable length (total)
  5390 00007242 F7D8                <1> 	neg	eax
  5391 00007244 01D8                <1> 	add	eax, ebx ; start address of the variable
  5392 00007246 F8                  <1> 	clc	; 13/04/2016
  5393 00007247 E9EEFDFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5394                              <1> 
  5395                              <1> mainprog_startup_configuration:
  5396                              <1> 	; 06/05/2016
  5397                              <1> 	; 14/04/2016 (TRDOS 386 = TRDOS v2.0)
  5398                              <1> 	; 17/09/2011 (TRDOS v1, MAINPROG.ASM)
  5399                              <1> 	;
  5400                              <1> loc_load_mainprog_cfg_file:
  5401 0000724C BE[29C20000]        <1> 	mov	esi, MainProgCfgFile
  5402 00007251 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5403 00007255 E8FBE9FFFF          <1> 	call	find_first_file
  5404 0000725A 7256                <1> 	jc	short loc_load_mainprog_cfg_exit
  5405                              <1> 
  5406                              <1> 	;or	eax, eax
  5407                              <1> 	;jz	short loc_load_mainprog_cfg_exit
  5408                              <1> 
  5409                              <1> loc_start_mainprog_configuration:
  5410                              <1> 	; ESI = FindFile_DirEntry Location
  5411                              <1> 	; EAX = File Size
  5412                              <1> 
  5413 0000725C A3[3CD30000]        <1> 	mov	[MainProgCfg_FileSize], eax
  5414                              <1> 
  5415 00007261 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  5416 00007265 C1E210              <1> 	shl	edx, 16
  5417 00007268 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  5418 0000726C 8915[6CDF0000]      <1> 	mov	[csftdf_sf_cluster], edx
  5419                              <1> 
  5420 00007272 89C1                <1> 	mov	ecx, eax
  5421 00007274 29C0                <1> 	sub	eax, eax
  5422                              <1> 
  5423                              <1> 	; TRDOS 386 (TRDOS v2.0)
  5424                              <1> 	; Allocate contiguous memory block for loading the file
  5425                              <1> 	
  5426                              <1> 	; eax = 0 (Allocate memory from the beginning)
  5427                              <1> 	; ecx = File (Allocation) size in bytes
  5428                              <1> 	
  5429 00007276 E80AC7FFFF          <1> 	call	allocate_memory_block
  5430 0000727B 7235                <1> 	jc	short loc_load_mainprog_cfg_exit
  5431                              <1> 
  5432 0000727D A3[64DF0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  5433 00007282 890D[68DF0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  5434                              <1> 
  5435 00007288 31DB                <1> 	xor	ebx, ebx
  5436                              <1> 	;mov	[csftdf_sf_rbytes], ebx ; 0, reset
  5437                              <1> 
  5438 0000728A 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv] ; [FindFile_Drv]
  5439 00007290 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5440 00007295 01DE                <1> 	add	esi, ebx
  5441                              <1> 
  5442 00007297 8B1D[64DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  5443                              <1> 
  5444 0000729D 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5445 000072A1 7710                <1>         ja	short loc_mcfg_load_fat_file
  5446                              <1> 
  5447 000072A3 C705[74DF0000]0000- <1> 	mov	dword [csftdf_r_size], 65536
  5447 000072AB 0100                <1>
  5448 000072AD E992010000          <1>         jmp     loc_mcfg_load_fs_file
  5449                              <1> 
  5450                              <1> loc_load_mainprog_cfg_exit:
  5451 000072B2 C3                  <1> 	retn 
  5452                              <1> 
  5453                              <1> loc_mcfg_load_fat_file:
  5454 000072B3 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  5455 000072B7 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  5456 000072BB F7E1                <1> 	mul	ecx
  5457 000072BD A3[74DF0000]        <1> 	mov	[csftdf_r_size], eax
  5458                              <1> 
  5459                              <1> loc_mcfg_load_fat_file_next:
  5460 000072C2 E813010000          <1> 	call	mcfg_read_fat_file_sectors
  5461 000072C7 0F82F7000000        <1>         jc      mcfg_deallocate_mem
  5462                              <1> 
  5463 000072CD 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  5464 000072CF 74F1                <1> 	jz	short loc_mcfg_load_fat_file_next
  5465                              <1> 
  5466                              <1> loc_mcfg_load_fat_file_ok:
  5467                              <1> 	; 06/05/2016
  5468 000072D1 C705[FCDF0000]-     <1> 	mov	dword [mainprog_return_addr], loc_mcfg_ci_return_addr 
  5468 000072D7 [85730000]          <1>
  5469                              <1> 	;
  5470 000072DB 8B35[64DF0000]      <1> 	mov	esi, [csftdf_sf_mem_addr]
  5471 000072E1 8935[40D30000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5472                              <1> 	
  5473 000072E7 A1[3CD30000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5474 000072EC 89C2                <1> 	mov	edx, eax
  5475 000072EE 01F2                <1> 	add	edx, esi
  5476                              <1> 
  5477                              <1> loc_mcfg_process_next_line_check:
  5478 000072F0 89C1                <1> 	mov	ecx, eax
  5479                              <1> 
  5480 000072F2 803E2A              <1> 	cmp	byte [esi], "*" ; Remark sign
  5481 000072F5 7503                <1> 	jne	short loc_mcfg_process_next_line
  5482 000072F7 46                  <1> 	inc	esi
  5483 000072F8 EB17                <1> 	jmp	short loc_move_mainprog_cfg_nl1
  5484                              <1> 
  5485                              <1> loc_mcfg_process_next_line:
  5486 000072FA 83F94F              <1> 	cmp	ecx, 79
  5487 000072FD 7605                <1> 	jna	short loc_start_mainprog_cfg_process
  5488                              <1> 	
  5489 000072FF B94F000000          <1> 	mov	ecx, 79 
  5490                              <1> 
  5491                              <1> loc_start_mainprog_cfg_process:
  5492 00007304 BF[FED30000]        <1> 	mov	edi, CommandBuffer
  5493                              <1> 
  5494                              <1> loc_move_mainprog_cfg_line:
  5495 00007309 AC                  <1> 	lodsb
  5496 0000730A 3C20                <1> 	cmp	al, 20h
  5497 0000730C 720C                <1> 	jb	short loc_move_mainprog_cfg_nl2
  5498 0000730E AA                  <1> 	stosb
  5499 0000730F E2F8                <1> 	loop	loc_move_mainprog_cfg_line
  5500                              <1> 
  5501                              <1> loc_move_mainprog_cfg_nl1:
  5502 00007311 39D6                <1> 	cmp	esi, edx ; + configuration file size
  5503 00007313 7312                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5504 00007315 AC                  <1> 	lodsb
  5505 00007316 3C20                <1> 	cmp	al, 20h
  5506 00007318 73F7                <1> 	jnb	short loc_move_mainprog_cfg_nl1
  5507                              <1> 
  5508                              <1> loc_move_mainprog_cfg_nl2:
  5509 0000731A 39D6                <1> 	cmp	esi, edx
  5510 0000731C 7309                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5511 0000731E 8A06                <1> 	mov	al, [esi]
  5512 00007320 3C20                <1> 	cmp	al, 20h
  5513 00007322 7703                <1>  	ja	short loc_end_of_mainprog_cfg_line
  5514 00007324 46                  <1> 	inc	esi
  5515 00007325 EBF3                <1> 	jmp	short loc_move_mainprog_cfg_nl2	               
  5516                              <1> 
  5517                              <1> loc_end_of_mainprog_cfg_line:
  5518 00007327 C60700              <1> 	mov	byte [edi], 0
  5519                              <1> 
  5520 0000732A 8935[40D30000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5521                              <1> 	
  5522                              <1> loc_move_mainprog_cfg_command:
  5523 00007330 BE[FED30000]        <1> 	mov	esi, CommandBuffer
  5524 00007335 89F7                <1> 	mov	edi, esi
  5525 00007337 31DB                <1> 	xor	ebx, ebx
  5526                              <1> 	;xor	ecx, ecx
  5527 00007339 30C9                <1> 	xor	cl, cl
  5528                              <1> 
  5529                              <1> loc_move_mcfg_first_cmd_char:
  5530 0000733B 8A041E              <1> 	mov	al, [esi+ebx]
  5531 0000733E FEC3                <1> 	inc	bl 
  5532 00007340 3C20                <1> 	cmp	al, 20h
  5533 00007342 7712                <1> 	ja	short loc_move_mcfg_cmd_capitalizing
  5534 00007344 7237                <1> 	jb	short loc_move_mcfg_cmd_arguments_ok
  5535 00007346 80FB4F              <1> 	cmp	bl, 79
  5536 00007349 72F0                <1> 	jb	short loc_move_mcfg_first_cmd_char
  5537 0000734B EB30                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5538                              <1> 
  5539                              <1> loc_move_mcfg_next_cmd_char:
  5540 0000734D 8A041E              <1> 	mov	al, [esi+ebx]
  5541 00007350 FEC3                <1> 	inc	bl
  5542 00007352 3C20                <1> 	cmp	al, 20h
  5543 00007354 7614                <1> 	jna	short loc_move_mcfg_cmd_ok
  5544                              <1> 
  5545                              <1> loc_move_mcfg_cmd_capitalizing:
  5546 00007356 3C61                <1> 	cmp	al, 61h ; 'a'
  5547 00007358 7206                <1> 	jb	short loc_move_mcfg_cmd_caps_ok
  5548 0000735A 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  5549 0000735C 7702                <1> 	ja	short loc_move_mcfg_cmd_caps_ok
  5550 0000735E 24DF                <1> 	and	al, 0DFh ; sub	al, 'a'-'A'
  5551                              <1> 
  5552                              <1> loc_move_mcfg_cmd_caps_ok:
  5553 00007360 AA                  <1> 	stosb 
  5554 00007361 FEC1                <1> 	inc	cl
  5555 00007363 80FB4F              <1> 	cmp	bl, 79
  5556 00007366 72E5                <1> 	jb	short loc_move_mcfg_next_cmd_char
  5557 00007368 EB13                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5558                              <1> 
  5559                              <1> loc_move_mcfg_cmd_ok:
  5560 0000736A 30C0                <1> 	xor	al, al ; 0
  5561                              <1> 
  5562                              <1> loc_move_mcfg_cmd_arguments:
  5563 0000736C 8807                <1> 	mov	[edi], al
  5564 0000736E 47                  <1> 	inc	edi
  5565 0000736F 80FB4F              <1> 	cmp	bl, 79
  5566 00007372 7309                <1> 	jnb	short loc_move_mcfg_cmd_arguments_ok
  5567 00007374 8A041E              <1> 	mov	al, [esi+ebx]
  5568 00007377 FEC3                <1> 	inc	bl
  5569 00007379 3C20                <1> 	cmp	al, 20h
  5570 0000737B 73EF                <1> 	jnb	short loc_move_mcfg_cmd_arguments
  5571                              <1> 	
  5572                              <1> loc_move_mcfg_cmd_arguments_ok:
  5573 0000737D C60700              <1> 	mov	byte [edi], 0
  5574                              <1>        
  5575                              <1> loc_mcfg_process_cmd_interpreter:
  5576 00007380 E8F8DFFFFF          <1> 	call    command_interpreter
  5577                              <1> 
  5578                              <1> loc_mcfg_ci_return_addr: 
  5579 00007385 A1[3CD30000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5580 0000738A 89C2                <1> 	mov	edx, eax
  5581 0000738C 8B35[40D30000]      <1> 	mov	esi, [MainProgCfg_LineOffset]
  5582 00007392 01F2                <1> 	add	edx, esi
  5583 00007394 0305[64DF0000]      <1> 	add	eax, [csftdf_sf_mem_addr]
  5584 0000739A 29F0                <1> 	sub	eax, esi
  5585 0000739C 0F874EFFFFFF        <1>         ja      loc_mcfg_process_next_line_check
  5586                              <1> 
  5587 000073A2 E81D000000          <1> 	call	mcfg_deallocate_mem
  5588                              <1>  
  5589 000073A7 B94F000000          <1>  	mov	ecx, 79 ; 80 ?
  5590 000073AC BF[FED30000]        <1> 	mov	edi, CommandBuffer
  5591 000073B1 30C0                <1> 	xor	al, al
  5592 000073B3 F3AA                <1> 	rep	stosb
  5593                              <1> 
  5594                              <1> 	; 06/05/2016
  5595 000073B5 BE[20CF0000]        <1> 	mov	esi, nextline
  5596 000073BA E8F5CBFFFF          <1> 	call	print_msg
  5597 000073BF E931D6FFFF          <1> 	jmp	dos_prompt
  5598                              <1> 
  5599                              <1> mcfg_deallocate_mem:
  5600 000073C4 A1[64DF0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  5601 000073C9 8B0D[68DF0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  5602                              <1> 	;call	deallocate_memory_block
  5603                              <1> 	;retn
  5604 000073CF E9B2C7FFFF          <1> 	jmp	deallocate_memory_block
  5605                              <1> 
  5606                              <1> mcfg_read_file_sectors:
  5607                              <1> 	; 14/04/2016
  5608 000073D4 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5609 000073D8 7669                <1>         jna	short mcfg_read_fs_file_sectors
  5610                              <1> 
  5611                              <1> mcfg_read_fat_file_sectors:
  5612                              <1> 	; return:
  5613                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  5614                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  5615                              <1> 	;   CF = 1 -> read error (error code in AL)	
  5616                              <1> 
  5617                              <1> mcfg_read_fat_file_secs_0:
  5618 000073DA 8B15[3CD30000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5619 000073E0 2B15[7CDF0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  5620 000073E6 3B15[74DF0000]      <1> 	cmp	edx, [csftdf_r_size]	
  5621 000073EC 7306                <1> 	jnb	short mcfg_read_fat_file_secs_1
  5622 000073EE 8915[74DF0000]      <1> 	mov	[csftdf_r_size], edx
  5623                              <1> 		
  5624                              <1> mcfg_read_fat_file_secs_1:
  5625 000073F4 A1[74DF0000]        <1> 	mov	eax, [csftdf_r_size]
  5626 000073F9 29D2                <1> 	sub	edx, edx
  5627 000073FB 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  5628 000073FF 01C8                <1> 	add	eax, ecx
  5629 00007401 48                  <1> 	dec	eax
  5630 00007402 F7F1                <1> 	div	ecx
  5631 00007404 89C1                <1> 	mov	ecx, eax ; sector count
  5632 00007406 A1[6CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5633                              <1> 
  5634                              <1> 	; EBX = memory block address (current)
  5635                              <1> 	
  5636 0000740B E874230000          <1> 	call	read_fat_file_sectors
  5637 00007410 7230                <1> 	jc	short mcfg_read_fat_file_secs_3
  5638                              <1> 
  5639                              <1> 	; EBX = next memory address
  5640                              <1> 
  5641 00007412 A1[7CDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  5642 00007417 0305[74DF0000]      <1> 	add	eax, [csftdf_r_size]
  5643 0000741D 8B15[3CD30000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5644 00007423 39D0                <1> 	cmp	eax, edx
  5645 00007425 731B                <1> 	jnb	short mcfg_read_fat_file_secs_3 ; edx > 0
  5646 00007427 A3[7CDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  5647                              <1> 
  5648 0000742C 53                  <1> 	push	ebx ; *
  5649                              <1> 	; get next cluster (csftdf_r_size! bytes)
  5650 0000742D A1[6CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5651 00007432 E81F210000          <1> 	call	get_next_cluster
  5652 00007437 5B                  <1> 	pop	ebx ; *
  5653 00007438 7301                <1> 	jnc	short mcfg_read_fat_file_secs_2
  5654                              <1> 
  5655                              <1> 	;mov	eax, 15h ; Read error !
  5656 0000743A C3                  <1> 	retn
  5657                              <1> 
  5658                              <1> mcfg_read_fat_file_secs_2:
  5659 0000743B 29D2                <1> 	sub	edx, edx ; 0
  5660 0000743D A3[6CDF0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  5661                              <1> 
  5662                              <1> mcfg_read_fat_file_secs_3:
  5663 00007442 C3                  <1> 	retn
  5664                              <1> 
  5665                              <1> mcfg_read_fs_file_sectors:
  5666 00007443 C3                  <1> 	retn
  5667                              <1> 
  5668                              <1> loc_mcfg_load_fs_file:
  5669 00007444 C3                  <1> 	retn
  5670                              <1> 
  5671                              <1> load_and_execute_file:
  5672                              <1> 	; 11/05/2016
  5673                              <1> 	; 07/05/2016
  5674                              <1> 	; 06/05/2016
  5675                              <1> 	; 24/04/2016
  5676                              <1> 	; 23/04/2016
  5677                              <1> 	; 22/04/2016 (TRDOS 386 = TRDOS v2.0)
  5678                              <1> 	; 05/11/2011 
  5679                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'cmp_cmd_run', 'cmp_cmd_external')
  5680                              <1> 	; ('loc_run_check_filename')
  5681                              <1> 	; 29/08/2011
  5682                              <1> 	; 10/09/2011
  5683                              <1> 	; INPUT->
  5684                              <1> 	;	ESI = Path Name address (CommandBuffer address)
  5685                              <1> 	; OUTPUT ->
  5686                              <1> 	;	none (error message will be shown if an error will occur)
  5687                              <1> 	;
  5688                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI, EBP will be changed) 
  5689                              <1> 	;
  5690                              <1> loc_run_check_filename:
  5691 00007445 803E20              <1> 	cmp	byte [esi], 20h
  5692 00007448 0F8205E3FFFF        <1> 	jb	loc_cmd_failed
  5693 0000744E 7703                <1> 	ja	short loc_run_check_filename_ok
  5694 00007450 46                  <1> 	inc	esi
  5695 00007451 EBF2                <1> 	jmp	short loc_run_check_filename
  5696                              <1> 
  5697                              <1> loc_run_check_filename_ok:
  5698 00007453 C605[AFD30000]00    <1> 	mov	byte [CmdArgStart], 0 ; reset
  5699 0000745A 56                  <1> 	push	esi ; *
  5700                              <1> loc_run_get_first_arg_pos:
  5701 0000745B 46                  <1> 	inc	esi
  5702 0000745C 8A06                <1> 	mov	al, [esi]
  5703 0000745E 3C20                <1> 	cmp	al, 20h
  5704 00007460 77F9                <1> 	ja	short loc_run_get_first_arg_pos
  5705 00007462 C60600              <1> 	mov	byte [esi], 0
  5706                              <1> loc_run_get_external_arg_pos:
  5707                              <1> 	; 11/05/2016
  5708 00007465 46                  <1> 	inc	esi
  5709 00007466 8A06                <1> 	mov	al, [esi]
  5710 00007468 3C20                <1> 	cmp	al, 20h
  5711 0000746A 760C                <1> 	jna	short loc_run_parse_path_name
  5712 0000746C 89F0                <1> 	mov	eax, esi
  5713 0000746E 2D[FED30000]        <1> 	sub	eax, CommandBuffer
  5714 00007473 A2[AFD30000]        <1> 	mov	byte [CmdArgStart], al
  5715                              <1> loc_run_parse_path_name:
  5716 00007478 5E                  <1> 	pop	esi ; *
  5717 00007479 BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  5718 0000747E E8DC090000          <1> 	call	parse_path_name
  5719 00007483 0F82CAE2FFFF        <1> 	jc	loc_cmd_failed
  5720                              <1> 
  5721                              <1> loc_run_check_filename_exists:
  5722 00007489 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5723 0000748E 803E20              <1> 	cmp	byte [esi], 20h
  5724 00007491 0F86BCE2FFFF        <1> 	jna	loc_cmd_failed
  5725                              <1> 
  5726                              <1> loc_run_check_exe_filename_ext:
  5727 00007497 E897020000          <1> 	call	check_prg_filename_ext
  5728 0000749C 0F82B1E2FFFF        <1> 	jc	loc_cmd_failed
  5729                              <1> 	
  5730                              <1> loc_run_check_exe_filename_ext_ok:
  5731 000074A2 66A3[FADF0000]      <1> 	mov	word [EXE_ID], ax
  5732                              <1> 
  5733                              <1> loc_run_drv:
  5734 000074A8 C605[F9DF0000]00    <1> 	mov	byte [Run_Manual_Path], 0
  5735 000074AF A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5736 000074B4 A3[F4DF0000]        <1>         mov     [Run_CDirFC], eax
  5737                              <1> 	;
  5738 000074B9 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  5739 000074BF 8835[AEDB0000]      <1> 	mov	[RUN_CDRV], dh
  5740                              <1> 
  5741 000074C5 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  5742 000074CB 38F2                <1> 	cmp	dl, dh
  5743 000074CD 7412                <1> 	je	short loc_run_change_directory
  5744                              <1>                
  5745 000074CF 8005[F9DF0000]02    <1> 	add	byte [Run_Manual_Path], 2
  5746                              <1> 
  5747 000074D6 E8DED3FFFF          <1> 	call	change_current_drive
  5748 000074DB 0F829DE2FFFF        <1> 	jc	loc_run_cmd_failed
  5749                              <1> 
  5750                              <1> loc_run_change_directory:
  5751 000074E1 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5752 000074E8 7623                <1> 	jna	short loc_run_find_executable_file
  5753                              <1> 
  5754 000074EA FE05[F9DF0000]      <1> 	inc	byte [Run_Manual_Path]
  5755                              <1>      
  5756 000074F0 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  5757                              <1> 
  5758 000074F6 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  5759 000074FB 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5760 000074FD E849030000          <1> 	call	change_current_directory
  5761 00007502 0F8276E2FFFF        <1> 	jc	loc_run_cmd_failed
  5762                              <1> 
  5763                              <1> loc_run_change_prompt_dir_string:
  5764 00007508 E85E020000          <1> 	call	change_prompt_dir_string
  5765                              <1> 
  5766                              <1> loc_run_find_executable_file:
  5767 0000750D 66C705[F8DF0000]00- <1> 	mov	word [Run_Auto_Path], 0
  5767 00007515 00                  <1>
  5768                              <1> 
  5769                              <1> loc_run_find_executable_file_next:
  5770 00007516 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5771                              <1> loc_run_find_program_file_next:
  5772 0000751B 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5773 0000751F E831E7FFFF          <1> 	call	find_first_file
  5774                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  5775                              <1> 	; EDI = Directory Buffer Directory Entry Location
  5776                              <1> 	; EAX = File size
  5777 00007524 0F835C010000        <1> 	jnc	loc_load_and_run_file
  5778                              <1> 	 
  5779 0000752A 3C02                <1> 	cmp	al, 2 ; file not found
  5780 0000752C 0F854CE2FFFF        <1> 	jne	loc_run_cmd_failed
  5781                              <1> 
  5782 00007532 66A1[FADF0000]      <1> 	mov	ax, word [EXE_ID]
  5783 00007538 80FC2E              <1> 	cmp	ah, '.' ; File name has extension sign
  5784 0000753B 7424                <1> 	je	short loc_run_check_auto_path
  5785                              <1> 
  5786 0000753D 08C0                <1> 	or	al, al
  5787 0000753F 7520                <1> 	jnz	short loc_run_check_auto_path
  5788                              <1> 
  5789 00007541 80FC08              <1> 	cmp	ah, 8 ; count of file name chars
  5790 00007544 771B                <1> 	ja	short loc_run_check_auto_path
  5791                              <1> 
  5792                              <1> loc_run_change_file_ext_to_prg:
  5793 00007546 0FB6DC              <1> 	movzx	ebx, ah ; count of file name chars
  5794 00007549 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5795 0000754E 01F3                <1> 	add	ebx, esi	
  5796                              <1> 	; 07/05/2016
  5797 00007550 C7032E505247        <1> 	mov	dword [ebx],  '.PRG'
  5798 00007556 66C705[FADF0000]50- <1> 	mov	word [EXE_ID], 'P.'
  5798 0000755E 2E                  <1>
  5799 0000755F EBBA                <1> 	jmp	short loc_run_find_program_file_next	
  5800                              <1> 
  5801                              <1> loc_run_check_auto_path:
  5802                              <1> 	; NOTE: /// 07/05/2016 ///
  5803                              <1> 	; If the path is given, value of byte [Run_Manual_Path]
  5804                              <1> 	; will not be ZERO. If so, file searching by using
  5805                              <1> 	; Automatic Path (via 'PATH' environment variable)
  5806                              <1> 	; will not be applicable, because the program file 
  5807                              <1> 	; is already/absolutely not found.
  5808                              <1> 
  5809 00007561 A0[F9DF0000]        <1> 	mov	al, [Run_Manual_Path]
  5810 00007566 08C0                <1> 	or	al, al
  5811 00007568 0F85E5E1FFFF        <1> 	jnz	loc_cmd_failed
  5812                              <1> 
  5813                              <1> loc_run_check_auto_path_again:
  5814 0000756E 66833D[F8DF0000]FF  <1> 	cmp	word [Run_Auto_Path], 0FFFFh		 
  5815                              <1> 		; 0FFFFh = Not a valid run path (in ENV block) 
  5816 00007576 0F83D7E1FFFF        <1> 	jnb	loc_cmd_failed
  5817                              <1> 	; xor	al, al 
  5818 0000757C BE[AFC20000]        <1> 	mov	esi, Cmd_Path ; 'PATH'
  5819 00007581 BF[4ED40000]        <1> 	mov	edi, TextBuffer
  5820 00007586 E857F9FFFF          <1> 	call	get_environment_string
  5821 0000758B 730E                <1> 	jnc	short loc_run_chk_filename_ext_again
  5822 0000758D 66C705[F8DF0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; invalid
  5822 00007595 FF                  <1>
  5823 00007596 E9B8E1FFFF          <1> 	jmp	loc_cmd_failed
  5824                              <1> 
  5825                              <1> loc_run_chk_filename_ext_again:
  5826 0000759B 89C1                <1> 	mov	ecx, eax ; string length (with zero tail)
  5827 0000759D 49                  <1> 	dec	ecx ; without zero tail
  5828 0000759E 66A1[FADF0000]      <1> 	mov	ax, [EXE_ID]
  5829 000075A4 80FC2E              <1> 	cmp	ah, '.'
  5830 000075A7 740E                <1> 	je	short loc_run_chk_auto_path_pos
  5831                              <1> 	 
  5832                              <1> loc_run_change_file_ext_to_noext_again:
  5833 000075A9 0FB6DC              <1> 	movzx	ebx, ah
  5834 000075AC BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5835 000075B1 01F3                <1> 	add 	ebx, esi
  5836 000075B3 29C0                <1> 	sub	eax, eax
  5837 000075B5 8903                <1> 	mov	[ebx], eax ; 0 ; erase extension (.PRG)
  5838                              <1> 
  5839                              <1> loc_run_chk_auto_path_pos:
  5840                              <1> 	;movzx	eax,  word [Run_Auto_Path]
  5841 000075B7 66A1[F8DF0000]      <1> 	mov	ax, [Run_Auto_Path]
  5842 000075BD 39C8                <1> 	cmp	eax, ecx ; ecx = string length (except zero tail)
  5843 000075BF 0F838EE1FFFF        <1> 	jnb	loc_cmd_failed
  5844                              <1> 	;or	eax, eax
  5845 000075C5 6609C0              <1> 	or	ax, ax
  5846 000075C8 7502                <1> 	jnz	short loc_run_auto_path_pos_move
  5847 000075CA B005                <1> 	mov	al, 5
  5848                              <1> 
  5849                              <1> loc_run_auto_path_pos_move:
  5850 000075CC 89FE                <1> 	mov	esi, edi ; offset TextBuffer
  5851 000075CE 01C6                <1> 	add	esi, eax
  5852                              <1> 
  5853                              <1> loc_run_auto_path_pos_space_loop:
  5854 000075D0 AC                  <1> 	lodsb
  5855 000075D1 3C20                <1> 	cmp	al, 20h 
  5856 000075D3 74FB                <1> 	je	short loc_run_auto_path_pos_space_loop
  5857 000075D5 0F8278E1FFFF        <1> 	jb	loc_cmd_failed 
  5858 000075DB AA                  <1> 	stosb
  5859                              <1> loc_run_auto_path_pos_move_next: 
  5860 000075DC AC                  <1> 	lodsb
  5861 000075DD 3C3B                <1> 	cmp	al, ';'
  5862 000075DF 7414                <1> 	je	short loc_run_auto_path_pos_move_last_byte
  5863 000075E1 3C20                <1> 	cmp	al, 20h
  5864 000075E3 74F7                <1> 	je	short loc_run_auto_path_pos_move_next
  5865 000075E5 7203                <1> 	jb	short loc_byte_ptr_end_of_path
  5866 000075E7 AA                  <1> 	stosb
  5867 000075E8 EBF2                <1> 	jmp	short loc_run_auto_path_pos_move_next 
  5868                              <1> 
  5869                              <1> loc_byte_ptr_end_of_path: 
  5870 000075EA 66C705[F8DF0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; end of path
  5870 000075F2 FF                  <1>
  5871 000075F3 EB0D                <1> 	jmp	short loc_run_auto_path_move_ok 
  5872                              <1> 
  5873                              <1> loc_run_auto_path_pos_move_last_byte:
  5874 000075F5 89F0                <1> 	mov	eax, esi
  5875 000075F7 2D[4ED40000]        <1> 	sub	eax, TextBuffer 
  5876 000075FC 66A3[F8DF0000]      <1> 	mov	[Run_Auto_Path], ax ; next path position
  5877                              <1> 
  5878                              <1> loc_run_auto_path_move_ok:
  5879 00007602 4F                  <1> 	dec	edi
  5880 00007603 B02F                <1> 	mov	al, '/'
  5881 00007605 3807                <1> 	cmp	[edi], al
  5882 00007607 7403                <1> 	je	short loc_run_auto_path_move_file_name
  5883 00007609 47                  <1> 	inc	edi
  5884 0000760A 8807                <1> 	mov	[edi], al
  5885                              <1> 
  5886                              <1> loc_run_auto_path_move_file_name:
  5887 0000760C 47                  <1> 	inc	edi   
  5888 0000760D BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5889                              <1> 
  5890                              <1> loc_run_auto_path_move_fn_loop:
  5891 00007612 AC                  <1> 	lodsb
  5892 00007613 AA                  <1> 	stosb
  5893 00007614 08C0                <1> 	or	al, al
  5894 00007616 75FA                <1> 	jnz	short loc_run_auto_path_move_fn_loop
  5895                              <1> 
  5896 00007618 BE[4ED40000]        <1> 	mov	esi, TextBuffer
  5897 0000761D BF[F2DC0000]        <1> 	mov	edi, FindFile_Drv
  5898 00007622 E838080000          <1> 	call	parse_path_name
  5899 00007627 0F8226E1FFFF        <1> 	jc	loc_cmd_failed
  5900                              <1> 
  5901 0000762D 8A35[4ED30000]      <1> 	mov	dh, [Current_Drv]
  5902 00007633 8A15[F2DC0000]      <1> 	mov	dl, [FindFile_Drv]
  5903 00007639 38F2                <1> 	cmp	dl, dh
  5904 0000763B 740B                <1> 	je	short loc_run_change_directory_again
  5905                              <1>                
  5906 0000763D E877D2FFFF          <1> 	call	change_current_drive
  5907 00007642 0F8236E1FFFF        <1> 	jc	loc_run_cmd_failed
  5908                              <1> 
  5909                              <1> loc_run_change_directory_again:
  5910 00007648 803D[F3DC0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5911 0000764F 761D                <1> 	jna	short loc_load_executable_cdir_chk_again
  5912                              <1> 
  5913 00007651 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  5914 00007657 BE[F3DC0000]        <1> 	mov	esi, FindFile_Directory
  5915 0000765C 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5916 0000765E E8E8010000          <1> 	call	change_current_directory
  5917 00007663 0F8215E1FFFF        <1> 	jc	loc_run_cmd_failed
  5918                              <1> 
  5919                              <1> loc_run_chg_prompt_dir_str_again:
  5920 00007669 E8FD000000          <1> 	call	change_prompt_dir_string
  5921                              <1> 
  5922                              <1> loc_load_executable_cdir_chk_again:
  5923 0000766E A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5924 00007673 3B05[F4DF0000]      <1> 	cmp	eax, [Run_CDirFC]
  5925 00007679 0F8597FEFFFF        <1> 	jne	loc_run_find_executable_file_next
  5926 0000767F 30C0                <1> 	xor	al, al ; 0
  5927 00007681 E9E8FEFFFF          <1> 	jmp	loc_run_check_auto_path_again
  5928                              <1> 
  5929                              <1> loc_load_and_run_file:
  5930                              <1> 	; 23/04/2016
  5931 00007686 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  5932 0000768B BF[4ED40000]        <1> 	mov	edi, TextBuffer
  5933                              <1> 
  5934                              <1>  	; 24/04/2016
  5935 00007690 31D2                <1> 	xor	edx, edx
  5936 00007692 668915[C6E30000]    <1> 	mov	word [argc], dx ; 0
  5937 00007699 8915[70E30000]      <1> 	mov	dword [u.nread], edx ; 0
  5938                              <1> 
  5939                              <1> loc_load_and_run_file_1:
  5940 0000769F AC                  <1> 	lodsb	
  5941 000076A0 AA                  <1> 	stosb
  5942 000076A1 FF05[70E30000]      <1> 	inc	dword [u.nread]
  5943 000076A7 20C0                <1> 	and	al, al
  5944 000076A9 75F4                <1> 	jnz 	short loc_load_and_run_file_1
  5945                              <1> 	
  5946 000076AB A0[AFD30000]        <1> 	mov	al, [CmdArgStart]
  5947 000076B0 20C0                <1> 	and	al, al
  5948 000076B2 7445                <1> 	jz	short loc_load_and_run_file_7
  5949                              <1> 
  5950 000076B4 0FB6F0              <1> 	movzx	esi, al ; 11/05/2016
  5951 000076B7 B950000000          <1> 	mov	ecx, 80
  5952 000076BC 29F1                <1> 	sub	ecx, esi
  5953 000076BE 81C6[FED30000]      <1> 	add	esi, CommandBuffer
  5954                              <1> 
  5955 000076C4 66FF05[C6E30000]    <1> 	inc	word [argc] ; 11/05/2016
  5956                              <1> 
  5957                              <1> loc_load_and_run_file_2:
  5958 000076CB AC                  <1> 	lodsb
  5959 000076CC 3C20                <1> 	cmp	al, 20h
  5960 000076CE 7717                <1> 	ja	short loc_load_and_run_file_5	
  5961 000076D0 721E                <1> 	jb	short loc_load_and_run_file_6
  5962                              <1> 
  5963                              <1> loc_load_and_run_file_3:
  5964 000076D2 803E20              <1> 	cmp	byte [esi], 20h
  5965 000076D5 7707                <1> 	ja	short loc_load_and_run_file_4
  5966 000076D7 7217                <1> 	jb	short loc_load_and_run_file_6
  5967 000076D9 46                  <1> 	inc	esi
  5968 000076DA E2F6                <1> 	loop	loc_load_and_run_file_3
  5969 000076DC EB12                <1> 	jmp	short loc_load_and_run_file_6
  5970                              <1> 
  5971                              <1> loc_load_and_run_file_4:
  5972 000076DE 28C0                <1> 	sub	al, al ; 0
  5973 000076E0 66FF05[C6E30000]    <1> 	inc	word [argc]
  5974                              <1> loc_load_and_run_file_5:
  5975 000076E7 AA                  <1> 	stosb
  5976 000076E8 FF05[70E30000]      <1> 	inc	dword [u.nread]
  5977 000076EE E2DB                <1> 	loop	loc_load_and_run_file_2
  5978                              <1> 			
  5979                              <1> loc_load_and_run_file_6:
  5980 000076F0 30C0                <1> 	xor	al, al ; 0
  5981 000076F2 AA                  <1> 	stosb
  5982 000076F3 FF05[70E30000]      <1> 	inc	dword [u.nread]
  5983                              <1> loc_load_and_run_file_7:
  5984 000076F9 8807                <1> 	mov 	[edi], al ; 0
  5985 000076FB 66FF05[C6E30000]    <1> 	inc	word [argc] ; 24/04/2016
  5986 00007702 FF05[70E30000]      <1> 	inc	dword [u.nread] ; 24/04/2016
  5987 00007708 BE[4ED40000]        <1> 	mov	esi, TextBuffer
  5988 0000770D 8B15[60DD0000]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  5989 00007713 66A1[58DD0000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  5990 00007719 66C1E010            <1> 	shl	ax, 16
  5991 0000771D 66A1[5EDD0000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusLO]
  5992                              <1> 	; EAX = First Cluster number
  5993                              <1> 	; EDX = File Size
  5994                              <1> 	; ESI = Argument list address
  5995                              <1> 	; [argc] = argument count
  5996                              <1> 	; [u.nread] = argument list length
  5997 00007723 E84E3E0000          <1> 	call	load_and_run_file ; trdosk6.s
  5998 00007728 0F8250E0FFFF        <1>         jc      loc_run_cmd_failed
  5999                              <1> loc_load_and_run_file_8: ; 06/05/2016
  6000 0000772E E94AE9FFFF          <1> 	jmp	loc_file_rw_restore_retn
  6001                              <1> 
  6002                              <1> check_prg_filename_ext:
  6003                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  6004                              <1> 	; 10/09/2011 
  6005                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'proc_check_exe_filename_ext')
  6006                              <1> 	; 14/11/2009
  6007                              <1> 	; INPUT -> 
  6008                              <1> 	;	ESI = Dot File Name
  6009                              <1> 	; OUTPUT ->
  6010                              <1> 	;     cf = 0 -> EXE_ID in AL
  6011                              <1> 	;	ESI = Last char + 1 position
  6012                              <1> 	;     cf = 1 -> Invalid executable file name
  6013                              <1> 	;	or no file name extension if AH<=8
  6014                              <1> 	;	AL = Last file name char     
  6015                              <1> 	;     cf = 0 -> AL='P' (PRG), AL=0 (no extension)
  6016                              <1> 	;
  6017                              <1> 	; (Modified registers: EAX, ESI)
  6018                              <1>   
  6019 00007733 30E4                <1> 	xor	ah, ah
  6020                              <1> loc_run_check_filename_ext:	
  6021 00007735 AC                  <1> 	lodsb
  6022 00007736 3C21                <1> 	cmp	al, 21h
  6023 00007738 7229                <1> 	jb	short loc_check_exe_fn_retn 
  6024 0000773A FEC4                <1> 	inc	ah
  6025 0000773C 3C2E                <1> 	cmp	al, '.'
  6026 0000773E 75F5                <1> 	jne	short loc_run_check_filename_ext	
  6027                              <1> 		 
  6028                              <1> loc_run_check_filename_ext_dot:
  6029 00007740 80FC02              <1> 	cmp	ah, 2 ; .??? is not valid
  6030 00007743 88C4                <1> 	mov	ah, al ; '.' 
  6031 00007745 7219                <1> 	jb	short loc_check_prg_fn_retn
  6032                              <1> 
  6033                              <1> loc_run_check_filename_ext_dot_ok:
  6034 00007747 AC                  <1> 	lodsb
  6035 00007748 24DF                <1> 	and	al, 0DFh 
  6036                              <1> 
  6037                              <1> loc_run_check_filename_ext_prg:
  6038 0000774A 3C50                <1> 	cmp	al, 'P'
  6039 0000774C 7212                <1> 	jb	short loc_check_prg_fn_retn
  6040 0000774E 7711                <1> 	ja	short loc_check_prg_fn_stc
  6041 00007750 AC                  <1> 	lodsb
  6042 00007751 24DF                <1> 	and	al, 0DFh 
  6043 00007753 3C52                <1> 	cmp	al, 'R'
  6044 00007755 750A                <1> 	jne	short loc_check_prg_fn_stc
  6045 00007757 AC                  <1> 	lodsb
  6046 00007758 24DF                <1> 	and	al, 0DFh
  6047 0000775A 3C47                <1> 	cmp	al, 'G'
  6048 0000775C 7503                <1> 	jne	short loc_check_prg_fn_stc
  6049                              <1> 
  6050 0000775E B050                <1> 	mov	al, 'P'
  6051                              <1> loc_check_prg_fn_retn:
  6052 00007760 C3                  <1> 	retn
  6053                              <1> 
  6054                              <1> loc_check_prg_fn_stc:
  6055 00007761 F9                  <1> 	stc
  6056 00007762 C3                  <1> 	retn
  6057                              <1>  
  6058                              <1> loc_check_exe_fn_retn:
  6059 00007763 28C0                <1> 	sub	al, al ; 0
  6060 00007765 C3                  <1> 	retn
  6061                              <1>               
  6062                              <1> find_and_list_files:
  6063 00007766 C3                  <1> 	retn
  6064                              <1> set_exec_arguments:
  6065 00007767 C3                  <1> 	retn
  6066                              <1> delete_fs_directory:
  6067 00007768 31C0                <1> 	xor eax, eax
  6068 0000776A C3                  <1> 	retn
  1880                                  %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: 13/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 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 0000776B BF[52D30000]        <1> 	mov	edi, Current_Directory
    27 00007770 8A25[4CD30000]      <1> 	mov	ah, [Current_Dir_Level]
    28 00007776 BE[AFDB0000]        <1> 	mov	esi, PATH_Array
    29 0000777B E807000000          <1> 	call	set_current_directory_string
    30 00007780 880D[ADD30000]      <1> 	mov	[Current_Dir_StrLen], cl
    31                              <1> 
    32 00007786 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 00007787 57                  <1> 	push    edi
    47 00007788 80FC00              <1> 	cmp     ah, 0
    48 0000778B 7652                <1> 	jna	short pass_write_path
    49 0000778D 83C610              <1> 	add	esi, 16
    50 00007790 89F3                <1> 	mov	ebx, esi
    51                              <1> loc_write_path:
    52 00007792 B908000000          <1> 	mov	ecx, 8
    53                              <1> path_write_dirname1:
    54 00007797 AC                  <1> 	lodsb
    55 00007798 3C20                <1> 	cmp	al, 20h
    56 0000779A 7612                <1> 	jna	short pass_write_dirname1
    57 0000779C AA                  <1> 	stosb
    58 0000779D 81FF[ACD30000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    59 000077A3 733A                <1> 	jnb	short pass_write_path
    60 000077A5 E2F0                <1> 	loop	path_write_dirname1
    61 000077A7 803E20              <1> 	cmp	byte [esi], 20h
    62 000077AA 7624                <1> 	jna	short pass_write_dirname2
    63 000077AC EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    64                              <1> pass_write_dirname1:
    65 000077AE 89DE                <1> 	mov	esi, ebx
    66 000077B0 83C608              <1> 	add	esi, 8
    67 000077B3 803E20              <1> 	cmp	byte [esi], 20h
    68 000077B6 7618                <1> 	jna	short pass_write_dirname2
    69                              <1> loc_put_dot_cont_ext:
    70 000077B8 C6072E              <1> 	mov	byte [edi], "."
    71                              <1> 	;mov	ecx, 3
    72 000077BB B103                <1> 	mov	cl, 3
    73                              <1> loc_check_dir_name_ext:
    74 000077BD AC                  <1> 	lodsb
    75 000077BE 47                  <1> 	inc	edi
    76 000077BF 3C20                <1> 	cmp	al, 20h
    77 000077C1 760D                <1> 	jna	short pass_write_dirname2
    78 000077C3 8807                <1> 	mov	[edi], al
    79 000077C5 81FF[ACD30000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    80 000077CB 7312                <1> 	jnb	short pass_write_path
    81 000077CD E2EE                <1> 	loop    loc_check_dir_name_ext
    82 000077CF 47                  <1> 	inc	edi
    83                              <1> pass_write_dirname2:
    84 000077D0 FECC                <1> 	dec	ah
    85 000077D2 740B                <1> 	jz      short pass_write_path
    86 000077D4 83C310              <1> 	add	ebx, 16
    87 000077D7 89DE                <1> 	mov	esi, ebx
    88 000077D9 C6072F              <1> 	mov	byte [edi],"/"
    89 000077DC 47                  <1> 	inc	edi
    90 000077DD EBB3                <1> 	jmp	short loc_write_path
    91                              <1> pass_write_path:
    92 000077DF C60700              <1> 	mov	byte [edi], 0
    93 000077E2 47                  <1> 	inc	edi
    94 000077E3 89F9                <1> 	mov	ecx, edi
    95 000077E5 5F                  <1> 	pop	edi
    96 000077E6 29F9                <1> 	sub	ecx, edi
    97                              <1> 	; ECX = Current Directory String Length
    98 000077E8 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 000077E9 80FA00              <1> 	cmp	dl, 0
   122 000077EC 7708                <1> 	ja	short loc_get_current_drive_1
   123 000077EE 8A15[4ED30000]      <1> 	mov	dl, [Current_Drv]
   124 000077F4 EB17                <1> 	jmp	short loc_get_current_drive_2
   125                              <1> loc_get_current_drive_1:
   126 000077F6 FECA                <1> 	dec 	dl
   127 000077F8 3A15[E2C10000]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   128 000077FE 760D                <1> 	jna	short loc_get_current_drive_2
   129 00007800 B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
   130 00007805 F5                  <1> 	cmc 	; stc
   131 00007806 C3                  <1> 	retn
   132                              <1> 
   133                              <1> loc_get_current_drive_not_ready_retn:
   134 00007807 5E                  <1> 	pop	esi
   135                              <1> 	;mov	eax, 15h
   136 00007808 66B81500            <1> 	mov	ax, 15h ; Drive not ready
   137 0000780C C3                  <1> 	retn  
   138                              <1>  
   139                              <1> loc_get_current_drive_2:
   140 0000780D 31C0                <1> 	xor	eax, eax
   141 0000780F 88D4                <1> 	mov	ah, dl
   142 00007811 56                  <1> 	push	esi
   143 00007812 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   144 00007817 01C6                <1> 	add	esi, eax
   145 00007819 8A06                <1> 	mov	al, [esi+LD_Name] 
   146 0000781B 3C41                <1> 	cmp	al, 'A'
   147 0000781D 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   148                              <1> 
   149 0000781F 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   150 00007822 08E4                <1> 	or	ah, ah
   151 00007824 7506                <1> 	jnz	short loc_get_current_drive_3
   152                              <1> 
   153                              <1> 	;xor	ah, ah ; mov ah, 0
   154 00007826 8826                <1> 	mov	[esi], ah
   155 00007828 31C9                <1> 	xor	ecx, ecx
   156 0000782A EB1C                <1> 	jmp	short loc_get_current_drive_4
   157                              <1> 
   158                              <1> loc_get_current_drive_3:
   159 0000782C BF[AFDB0000]        <1>         mov     edi, PATH_Array
   160 00007831 57                  <1> 	push	edi
   161 00007832 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   162 00007838 B920000000          <1> 	mov	ecx, 32
   163 0000783D F3A5                <1> 	rep	movsd
   164 0000783F 5E                  <1> 	pop	esi ; Path Array Address
   165 00007840 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   166                              <1> 	;
   167 00007841 E841FFFFFF          <1> 	call	set_current_directory_string
   168 00007846 89FE                <1> 	mov	esi, edi
   169                              <1> 
   170                              <1> loc_get_current_drive_4:
   171 00007848 30C0                <1> 	xor	al, al
   172 0000784A 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 0000784B 8825[3DDC0000]      <1> 	mov	[CD_COMMAND], ah
   197 00007851 803E2F              <1> 	cmp	byte [esi], '/'
   198 00007854 7505                <1> 	jne	short loc_ccd_cdir_level
   199 00007856 46                  <1> 	inc	esi
   200 00007857 30C0                <1> 	xor	al, al
   201 00007859 EB05                <1> 	jmp	short loc_ccd_parse_path_name
   202                              <1> loc_ccd_cdir_level:
   203 0000785B A0[4CD30000]        <1> 	mov	al, [Current_Dir_Level]
   204                              <1> loc_ccd_parse_path_name:
   205 00007860 88C4                <1> 	mov	ah, al
   206 00007862 BF[AFDB0000]        <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 00007867 0FB6C8              <1> 	movzx	ecx, al
   218 0000786A FEC1                <1> 	inc	cl
   219 0000786C C0E104              <1> 	shl	cl, 4
   220 0000786F 01CF                <1> 	add	edi, ecx
   221 00007871 B107                <1> 	mov	cl, 7
   222 00007873 28C1                <1> 	sub	cl, al
   223 00007875 C0E102              <1> 	shl	cl, 2
   224 00007878 89C3                <1> 	mov	ebx, eax
   225 0000787A 31C0                <1> 	xor	eax, eax ; 0
   226 0000787C F3AB                <1> 	rep	stosd
   227 0000787E 89D8                <1> 	mov	eax, ebx
   228                              <1> 
   229 00007880 BF[AFDB0000]        <1> 	mov	edi, PATH_Array
   230                              <1> 
   231 00007885 803E20              <1> 	cmp	byte [esi], 20h
   232 00007888 F5                  <1> 	cmc
   233 00007889 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   234                              <1> 
   235                              <1> 		; ESI = Path name
   236                              <1> 		; AL = CCD_Level
   237 0000788B 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 00007890 9C                  <1> 	pushf
   244                              <1> 
   245                              <1> 	;mov	[CCD_Level], al
   246                              <1>         ;mov	[Last_Dir_Level], ah
   247 00007891 66A3[33DC0000]      <1> 	mov	[CCD_Level], ax
   248                              <1> 
   249 00007897 31DB                <1> 	xor	ebx, ebx
   250 00007899 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
   251 0000789F BE00010900          <1> 	mov	esi, Logical_DOSDisks
   252 000078A4 01DE                <1> 	add	esi, ebx
   253                              <1> 
   254 000078A6 9D                  <1> 	popf 
   255 000078A7 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   256                              <1> 
   257 000078A9 8935[2FDC0000]      <1> 	mov	[CCD_DriveDT], esi
   258                              <1> 
   259 000078AF 3C07                <1> 	cmp	al, 7
   260 000078B1 7209                <1> 	jb	short loc_ccd_load_child_dir
   261                              <1> 
   262                              <1> loc_ccd_bad_path_name_retn:
   263 000078B3 87F7                <1> 	xchg	esi, edi
   264                              <1> 	; DOS Error Code 
   265 000078B5 B818000000          <1> 	mov	eax, 18h ; Bad request structure length 
   266 000078BA F9                  <1> 	stc
   267                              <1> loc_ccd_retn_p:
   268 000078BB C3                  <1> 	retn
   269                              <1> 
   270                              <1> loc_ccd_load_child_dir:
   271                              <1> 	; AL = CCD_Level
   272 000078BC 08C0                <1> 	or	al, al
   273 000078BE 7468                <1> 	jz	short loc_ccd_load_root_dir
   274                              <1> 
   275 000078C0 6689C1              <1> 	mov	cx, ax
   276 000078C3 C0E004              <1> 	shl	al, 4
   277 000078C6 0FB6F0              <1> 	movzx	esi, al
   278 000078C9 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   279                              <1> 
   280 000078CB 8B460C              <1> 	mov	eax, [esi+12]
   281 000078CE 38E9                <1> 	cmp	cl, ch
   282 000078D0 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   283 000078D6 A3[48D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   284                              <1> 
   285                              <1> loc_ccd_load_child_dir_next:
   286 000078DB 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   287                              <1> 
   288                              <1>  	; Directory attribute : 10h
   289 000078DE B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   290                              <1> 	;mov	ah, 11001000b ; C8h
   291                              <1> 	; Volume name attribute: 8h
   292 000078E0 B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   293                              <1> 
   294 000078E2 6631C9              <1> 	xor	cx, cx  
   295 000078E5 E8B5010000          <1> 	call	locate_current_dir_file
   296 000078EA 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   297                              <1> 
   298                              <1> 	 ; 19/02/2016
   299                              <1> 	;mov	edi, [CCD_DriveDT]
   300 000078EC 8A25[33DC0000]      <1> 	mov	ah, [CCD_Level]
   301 000078F2 803D[3DDC0000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   302 000078F9 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 000078FB 88E1                <1> 	mov	cl, ah
   308 000078FD 50                  <1> 	push	eax
   309 000078FE E8E3000000          <1> 	call	loc_ccd_save_current_dir
   310 00007903 58                  <1> 	pop	eax
   311                              <1> loc_ccd_load_child_dir_err:            
   312 00007904 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   313 00007906 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   314 00007908 F9                  <1> 	stc
   315 00007909 C3                  <1> 	retn
   316                              <1> 
   317                              <1> loc_ccd_path_not_found_retn:
   318 0000790A B003                <1> 	mov	al, 3	; Path not found
   319 0000790C C3                  <1> 	retn
   320                              <1> 
   321                              <1> loc_ccd_load_FAT_root_dir:
   322 0000790D 803D[4DD30000]02    <1> 	cmp	byte [Current_FATType], 2
   323 00007914 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   324                              <1> 
   325                              <1> 	;mov	esi, [CCD_DriveDT]
   326                              <1> 	;push	esi
   327 00007916 E8961D0000          <1> 	call	load_FAT_root_directory
   328                              <1> 	;pop	edi ; Dos Drv Description Table
   329                              <1> 
   330 0000791B 89F7                <1> 	mov	edi, esi
   331 0000791D BE[AFDB0000]        <1> 	mov	esi, PATH_Array
   332 00007922 7297                <1> 	jc	short loc_ccd_retn_p
   333                              <1> 
   334 00007924 31C0                <1> 	xor	eax, eax
   335 00007926 EB78                <1>         jmp	short loc_ccd_set_cdfc
   336                              <1> 
   337                              <1> loc_ccd_load_root_dir:
   338 00007928 803D[4DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   339 0000792F 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   340                              <1> 
   341                              <1> loc_ccd_load_FS_root_dir:
   342 00007931 E8421E0000          <1> 	call	load_FS_root_directory
   343 00007936 EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   344                              <1> 
   345                              <1> loc_ccd_load_FS_sub_directory_next:
   346 00007938 E83C1E0000          <1> 	call	load_FS_sub_directory
   347 0000793D 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 0000793F 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   352 00007943 C1E010              <1> 	shl	eax, 16
   353 00007946 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   354                              <1> 
   355 0000794A 8B35[2FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   356 00007950 803D[4DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   357 00007957 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   358                              <1> 	;push	esi
   359 00007959 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 0000795E BE[AFDB0000]        <1> 	mov	esi, PATH_Array
   365 00007963 7264                <1> 	jc	short loc_ccd_retn_c
   366                              <1> 
   367 00007965 A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   368                              <1> 
   369 0000796A FE05[33DC0000]      <1> 	inc	byte [CCD_Level]
   370 00007970 0FB61D[33DC0000]    <1> 	movzx	ebx, byte [CCD_Level]
   371 00007977 C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   372 0000797A 01DE                <1> 	add	esi, ebx ; 19/02/2016
   373 0000797C 89460C              <1> 	mov	[esi+12], eax
   374 0000797F EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   375                              <1> 
   376                              <1> loc_ccd_load_FAT32_root_dir:
   377 00007981 BE[AFDB0000]        <1> 	mov	esi, PATH_Array
   378 00007986 8B460C              <1> 	mov	eax, [esi+12]
   379 00007989 8B35[2FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   380                              <1>  
   381                              <1> loc_ccd_load_FAT_sub_directory:
   382                              <1> 	;push	esi
   383 0000798F 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 00007994 BE[AFDB0000]        <1> 	mov	esi, PATH_Array
   389 00007999 722E                <1> 	jc	short loc_ccd_retn_c
   390                              <1> 
   391 0000799B A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   392                              <1> 
   393                              <1> loc_ccd_set_cdfc:
   394 000079A0 8A0D[33DC0000]      <1> 	mov	cl, [CCD_Level]
   395 000079A6 880D[4CD30000]      <1> 	mov	[Current_Dir_Level], cl
   396 000079AC A3[48D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   397                              <1> 
   398 000079B1 8A2D[34DC0000]      <1> 	mov	ch, [Last_Dir_Level]
   399 000079B7 38E9                <1> 	cmp	cl, ch 
   400 000079B9 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   401                              <1> 	
   402 000079BF 803D[3DDC0000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   403 000079C6 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 000079C8 F8                  <1> 	clc
   409                              <1> 
   410                              <1> loc_ccd_retn_c:
   411 000079C9 8B3D[2FDC0000]      <1> 	mov	edi, [CCD_DriveDT]
   412 000079CF C3                  <1> 	retn
   413                              <1> 
   414                              <1> loc_ccd_load_sub_directory:
   415 000079D0 8B35[2FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   416 000079D6 803D[4DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   417 000079DD 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   418 000079DF E8951D0000          <1> 	call	load_FS_sub_directory
   419 000079E4 EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   420                              <1> 
   421                              <1> loc_ccd_save_current_dir:
   422 000079E6 BE[AFDB0000]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   423 000079EB 8B3D[2FDC0000]      <1> 	mov	edi, [CCD_DriveDT]
   424 000079F1 57                  <1> 	push	edi
   425 000079F2 83C77F              <1>         add     edi, LD_CDirLevel
   426 000079F5 880F                <1> 	mov	[edi], cl
   427 000079F7 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   428 000079F8 56                  <1> 	push	esi
   429                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   430 000079F9 66B92000            <1> 	mov	cx, 32
   431 000079FD F3A5                <1> 	rep	movsd
   432                              <1> 	; Current directory has been saved to 
   433                              <1> 	; the DOS drive description table, cdir area !
   434 000079FF 5E                  <1> 	pop	esi  ; PATH_Array
   435 00007A00 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   436                              <1> 
   437 00007A01 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 00007A02 88C4                <1> 	mov	ah, al
   460 00007A04 66A3[D4DC0000]      <1> 	mov	[PATH_CDLevel], ax
   461                              <1> repeat_ppdn_check_slash:
   462 00007A0A AC                  <1> 	lodsb
   463 00007A0B 3C2F                <1> 	cmp	al, '/'
   464 00007A0D 74FB                <1> 	je	short repeat_ppdn_check_slash
   465 00007A0F 3C21                <1> 	cmp	al, 21h
   466 00007A11 7219                <1> 	jb	short loc_ppdn_retn
   467 00007A13 57                  <1> 	push	edi
   468                              <1> loc_ppdn_get_dir_name:
   469 00007A14 B90C000000          <1> 	mov	ecx, 12
   470 00007A19 BF[D6DC0000]        <1> 	mov	edi, Dir_File_Name
   471                              <1> repeat_ppdn_get_dir_name:
   472 00007A1E AA                  <1> 	stosb
   473 00007A1F AC                  <1> 	lodsb
   474 00007A20 3C2F                <1> 	cmp	al, '/'
   475 00007A22 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   476 00007A24 3C20                <1> 	cmp	al, 20h
   477 00007A26 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   478 00007A28 E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   479 00007A2A 5F                  <1> 	pop	edi
   480 00007A2B F9                  <1> 	stc
   481                              <1> loc_ppdn_retn:
   482 00007A2C C3                  <1> 	retn
   483                              <1> 
   484                              <1> loc_ppdn_end_of_path_scan:
   485 00007A2D 4E                  <1> 	dec	esi
   486                              <1> loc_check_level_dot_conv_dir_name:
   487 00007A2E 31C0                <1> 	xor	eax, eax
   488 00007A30 AA                  <1> 	stosb
   489 00007A31 89F3                <1> 	mov	ebx, esi
   490 00007A33 BE[D6DC0000]        <1> 	mov	esi, Dir_File_Name
   491 00007A38 AC                  <1> 	lodsb
   492                              <1> repeat_ppdn_name_check_dot:
   493 00007A39 3C2E                <1> 	cmp	al, '.'
   494 00007A3B 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   495                              <1> repeat_ppdn_name_dot_dot:
   496 00007A3D AC                  <1> 	lodsb
   497 00007A3E 3C2E                <1> 	cmp	al, '.'
   498 00007A40 743E                <1> 	je	short loc_ppdn_dot_dot
   499 00007A42 3C21                <1> 	cmp	al, 21h
   500 00007A44 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   501                              <1> loc_ppdn_convert_sub_dir_name:
   502 00007A46 8A25[D5DC0000]      <1> 	mov	ah, [PATH_Level]
   503 00007A4C 80FC07              <1> 	cmp	ah, 7
   504 00007A4F 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   505 00007A51 FEC4                <1> 	inc	ah  
   506 00007A53 8825[D5DC0000]      <1> 	mov	[PATH_Level], ah
   507 00007A59 BE[D6DC0000]        <1> 	mov	esi, Dir_File_Name
   508                              <1> 	;mov	edi, [PATH_Array_Ptr]
   509 00007A5E B010                <1> 	mov	al, 16
   510 00007A60 F6E4                <1> 	mul	ah
   511 00007A62 8B3C24              <1> 	mov	edi, [esp]
   512                              <1> 	;push	edi 
   513 00007A65 01C7                <1> 	add	edi, eax
   514 00007A67 E828030000          <1> 	call	convert_file_name
   515                              <1> 	;pop	edi
   516                              <1> pass_ppdn_convert_sub_dir_name:
   517 00007A6C 89DE                <1> 	mov	esi, ebx
   518                              <1> repeat_ppdn_check_last_slash:
   519 00007A6E AC                  <1> 	lodsb
   520 00007A6F 3C2F                <1> 	cmp	al, '/'
   521 00007A71 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   522 00007A73 3C21                <1> 	cmp	al, 21h
   523 00007A75 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   524                              <1> end_of_parse_dir_name:
   525 00007A77 5F                  <1> 	pop	edi
   526 00007A78 F5                  <1> 	cmc  
   527                              <1> 	;mov	al, [PATH_CDLevel]
   528                              <1> 	;mov	ah, [PATH_Level]
   529 00007A79 66A1[D4DC0000]      <1> 	mov	ax, [PATH_CDLevel]
   530 00007A7F C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_ppdn_dot_dot:
   533 00007A80 AC                  <1> 	lodsb
   534 00007A81 3C21                <1> 	cmp	al, 21h
   535 00007A83 73F2                <1> 	jnb	short end_of_parse_dir_name 
   536                              <1> loc_ppdn_dot_dot_prev_level:
   537 00007A85 66A1[D4DC0000]      <1> 	mov	ax, [PATH_CDLevel]
   538 00007A8B 80EC01              <1> 	sub	ah, 1
   539 00007A8E 80D400              <1> 	adc	ah, 0
   540 00007A91 38E0                <1> 	cmp	al, ah
   541 00007A93 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   542 00007A95 88E0                <1> 	mov	al, ah
   543                              <1> pass_ppdn_set_al_to_ah:
   544 00007A97 66A3[D4DC0000]      <1> 	mov	[PATH_CDLevel], ax
   545 00007A9D 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 00007A9F 8935[37DC0000]      <1> 	mov	[CDLF_FNAddress], esi
   590 00007AA5 66A3[35DC0000]      <1> 	mov	[CDLF_AttributesMask], ax
   591 00007AAB 66890D[3BDC0000]    <1> 	mov	[CDLF_DEType], cx
   592                              <1> 
   593 00007AB2 31DB                <1> 	xor	ebx, ebx
   594 00007AB4 881D[4CDC0000]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   595                              <1> 
   596 00007ABA 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
   597 00007AC0 381D[78DB0000]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   598 00007AC6 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   599 00007AC8 8A1D[76DB0000]      <1>         mov     bl, [DirBuff_DRV]
   600 00007ACE 80EB41              <1> 	sub	bl, 'A'
   601 00007AD1 38DF                <1> 	cmp	bh, bl
   602 00007AD3 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   603 00007AD5 8B15[7DDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
   604 00007ADB 3B15[48D30000]      <1> 	cmp	edx, [Current_Dir_FCluster]
   605 00007AE1 7412                <1> 	je	short loc_cdir_locatefile_search
   606                              <1> 
   607                              <1> loc_lcdf_reload_current_dir1:
   608 00007AE3 30DB                <1> 	xor	bl, bl
   609                              <1> loc_lcdf_reload_current_dir2:
   610 00007AE5 89DE                <1> 	mov	esi, ebx
   611 00007AE7 81C600010900        <1>         add     esi, Logical_DOSDisks
   612 00007AED E872000000          <1> 	call	reload_current_directory 
   613 00007AF2 735B                <1> 	jnc	short loc_locatefile_search_again 
   614 00007AF4 C3                  <1> 	retn  
   615                              <1> 
   616                              <1> loc_cdir_locatefile_search:
   617 00007AF5 31DB                <1> 	xor	ebx, ebx
   618 00007AF7 E8A5000000          <1> 	call	find_directory_entry
   619 00007AFC 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   620                              <1> 
   621                              <1> loc_locatefile_check_stc_reason:
   622 00007AFE 08ED                <1> 	or	ch, ch
   623 00007B00 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   624                              <1> 
   625                              <1> loc_locatefile_check_next_entryblock:
   626 00007B02 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
   627 00007B08 28DB                <1> 	sub	bl, bl
   628 00007B0A 0FB7F3              <1> 	movzx	esi, bx
   629 00007B0D 81C600010900        <1>         add     esi, Logical_DOSDisks
   630                              <1> 
   631 00007B13 803D[4CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
   632 00007B1A 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   633                              <1>             
   634 00007B1C 803D[4DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   635 00007B23 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   636 00007B25 C3                  <1> 	retn  
   637                              <1> 
   638                              <1> loc_locatefile_check_FAT_type:
   639 00007B26 803D[4DD30000]03    <1> 	cmp	byte [Current_FATType], 3
   640 00007B2D 7218                <1> 	jb	short loc_cdir_locate_file_retn
   641                              <1> 
   642                              <1> loc_locatefile_load_subdir_cluster:
   643 00007B2F A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   644 00007B34 E81D1A0000          <1> 	call	get_next_cluster
   645 00007B39 730D                <1> 	jnc	short loc_locatefile_next_cluster
   646 00007B3B 09C0                <1> 	or	eax, eax
   647 00007B3D 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   648 00007B3F F9                  <1> 	stc
   649                              <1> loc_locatefile_file_notfound:
   650 00007B40 B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   651 00007B45 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 00007B46 F5                  <1> 	cmc ;stc
   657                              <1> loc_cdir_locate_file_retn:
   658 00007B47 C3                  <1> 	retn
   659                              <1> 
   660                              <1> loc_locatefile_next_cluster:
   661 00007B48 E8EF1B0000          <1> 	call	load_FAT_sub_directory
   662                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   663 00007B4D 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   664                              <1> 
   665                              <1> loc_locatefile_search_again:
   666 00007B4F 8B35[37DC0000]      <1> 	mov	esi, [CDLF_FNAddress] 
   667 00007B55 66A1[35DC0000]      <1> 	mov	ax, [CDLF_AttributesMask]
   668 00007B5B 668B0D[3BDC0000]    <1> 	mov	cx, [CDLF_DEType] 
   669 00007B62 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 00007B64 A0[4DD30000]        <1> 	mov	al, [Current_FATType]
   681 00007B69 3C02                <1> 	cmp	al, 2
   682 00007B6B 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   683 00007B6D 8A25[4CD30000]      <1> 	mov	ah, [Current_Dir_Level]
   684 00007B73 08C0                <1> 	or	al, al
   685 00007B75 740A                <1> 	jz	short loc_reload_FS_directory
   686 00007B77 08E4                <1> 	or	ah, ah
   687 00007B79 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   688                              <1> loc_reload_FAT_12_16_root_directory:
   689 00007B7B E8311B0000          <1> 	call	load_FAT_root_directory
   690 00007B80 C3                  <1> 	retn
   691                              <1> loc_reload_FS_directory:
   692 00007B81 20E4                <1> 	and	ah, ah
   693 00007B83 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   694                              <1> loc_reload_FS_root_directory: 
   695 00007B85 E8EE1B0000          <1> 	call	load_FS_root_directory
   696 00007B8A C3                  <1> 	retn
   697                              <1> loc_reload_FS_sub_directory:
   698 00007B8B A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
   699 00007B90 E8E41B0000          <1> 	call	load_FS_sub_directory
   700 00007B95 C3                  <1> 	retn 
   701                              <1> loc_reload_FAT_sub_directory:
   702 00007B96 A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
   703 00007B9B E89C1B0000          <1> 	call	load_FAT_sub_directory
   704 00007BA0 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 00007BA1 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   750 00007BA8 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   751                              <1> 
   752                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   753                              <1> 
   754 00007BAE BF00000800          <1>   	mov	edi, Directory_Buffer
   755 00007BB3 66A3[48DC0000]      <1> 	mov	[FDE_AttrMask], ax
   756                              <1> 
   757 00007BB9 29C0                <1> 	sub	eax, eax
   758                              <1>             
   759                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   760 00007BBB 66A3[4ADC0000]      <1> 	mov	[AmbiguousFileName], ax ; 0
   761                              <1> 
   762 00007BC1 6689D8              <1> 	mov	ax, bx
   763 00007BC4 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   764 00007BC8 01C7                <1> 	add     edi, eax
   765                              <1> 
   766 00007BCA 08ED                <1> 	or	ch, ch
   767 00007BCC 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   768                              <1> 
   769 00007BD2 08C9                <1> 	or      cl, cl
   770 00007BD4 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   771                              <1>  
   772                              <1> check_find_dir_entry:
   773 00007BDA 66A1[48DC0000]      <1> 	mov	ax, [FDE_AttrMask]
   774 00007BE0 8A2F                <1> 	mov	ch, [edi]
   775 00007BE2 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   776 00007BE5 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   777 00007BEB 56                  <1> 	push	esi
   778 00007BEC 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   779 00007BEF 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   780 00007BF2 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   781                              <1> 
   782 00007BF4 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   783 00007BF7 7505                <1> 	jne     short loc_check_attributes_mask
   784 00007BF9 E8ED010000          <1> 	call	save_longname_sub_component
   785                              <1> 
   786                              <1> loc_check_attributes_mask:
   787 00007BFE 88C6                <1> 	mov	dh, al
   788 00007C00 20D6                <1> 	and	dh, dl    
   789 00007C02 38F0                <1> 	cmp	al, dh
   790 00007C04 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   791 00007C0A 20D4                <1> 	and	ah, dl
   792 00007C0C 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   793 00007C12 80FA0F              <1> 	cmp	dl, 0Fh
   794 00007C15 751A                <1> 	jne	short pass_direntry_attr_check
   795                              <1> 
   796 00007C17 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   797 00007C19 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   798                              <1> 
   799 00007C1F 5E                  <1> 	pop	esi
   800 00007C20 6631C0              <1> 	xor	ax, ax
   801 00007C23 8A35[4CDC0000]      <1> 	mov	dh, [PreviousAttr]
   802 00007C29 66891D[79DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   803 00007C30 C3                  <1> 	retn
   804                              <1> 
   805                              <1> pass_direntry_attr_check:
   806 00007C31 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   807 00007C33 B908000000          <1> 	mov	ecx, 8
   808                              <1> loc_lodsb_find_dir:
   809 00007C38 AC                  <1> 	lodsb
   810 00007C39 3C2A                <1> 	cmp	al, '*'
   811 00007C3B 7508                <1> 	jne	short pass_fde_ambiguous1_check
   812 00007C3D FE05[4BDC0000]      <1>         inc     byte [AmbiguousFileName+1]
   813 00007C43 EB28                <1> 	jmp	short loc_check_direntry_extension
   814                              <1> 
   815                              <1> pass_fde_ambiguous1_check:
   816 00007C45 3C3F                <1> 	cmp	al, '?'
   817 00007C47 750D                <1> 	jne	short pass_fde_ambiguous2_check
   818 00007C49 FE05[4ADC0000]      <1> 	inc	byte [AmbiguousFileName]
   819 00007C4F 803F20              <1> 	cmp	byte [edi], 20h
   820 00007C52 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   821 00007C54 EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   822                              <1> 
   823                              <1> pass_fde_ambiguous2_check:
   824 00007C56 3C20                <1> 	cmp	al, 20h
   825 00007C58 750C                <1> 	jne	short loc_scasb_find_dir
   826 00007C5A 803F20              <1> 	cmp	byte [edi], 20h
   827 00007C5D 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   828 00007C5F EB0C                <1> 	jmp	short loc_check_direntry_extension
   829                              <1> 
   830                              <1> loc_find_dir_next_entry_prevdeleted:
   831 00007C61 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   832 00007C64 EB5E                <1> 	jmp	short loc_find_dir_next_entry
   833                              <1> 
   834                              <1> loc_scasb_find_dir:
   835 00007C66 3A07                <1> 	cmp	al, [edi]
   836 00007C68 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   837                              <1> loc_scasb_find_dir_inc_di:
   838 00007C6A 47                  <1> 	inc	edi
   839 00007C6B E2CB                <1> 	loop	loc_lodsb_find_dir
   840                              <1> 
   841                              <1> loc_check_direntry_extension:
   842 00007C6D BE08000000          <1> 	mov	esi, 8
   843 00007C72 89F7                <1> 	mov	edi, esi ; 8
   844 00007C74 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   845 00007C77 01EF                <1> 	add	edi, ebp
   846 00007C79 B103                <1> 	mov	cl, 3
   847                              <1> loc_lodsb_find_dir_ext:
   848 00007C7B AC                  <1> 	lodsb
   849 00007C7C 3C2A                <1> 	cmp	al, '*'
   850 00007C7E 7508                <1> 	jne	short pass_fde_ambiguous3_check
   851 00007C80 FE05[4BDC0000]      <1> 	inc	byte [AmbiguousFileName+1]
   852 00007C86 EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   853                              <1> 
   854                              <1> pass_fde_ambiguous3_check:
   855 00007C88 3C3F                <1> 	cmp	al, '?'
   856 00007C8A 750D                <1> 	jne	short pass_fde_ambiguous4_check
   857 00007C8C FE05[4ADC0000]      <1> 	inc	byte [AmbiguousFileName]
   858 00007C92 803F20              <1> 	cmp	byte [edi], 20h
   859 00007C95 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   860 00007C97 EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   861                              <1> 
   862                              <1> pass_fde_ambiguous4_check:
   863 00007C99 3C20                <1> 	cmp	al, 20h
   864 00007C9B 7541                <1> 	jne	short loc_scasb_find_dir_ext
   865 00007C9D 803F20              <1> 	cmp	byte [edi], 20h
   866 00007CA0 7404                <1> 	je	short loc_find_dir_proper_direntry
   867                              <1> 
   868                              <1> loc_find_dir_next_entry_ebp:
   869 00007CA2 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   870 00007CA4 EB1E                <1> 	jmp	short loc_find_dir_next_entry
   871                              <1> 
   872                              <1> loc_find_dir_proper_direntry:
   873 00007CA6 30C9                <1> 	xor	cl, cl
   874                              <1> loc_find_dir_proper_direntry_1:
   875 00007CA8 5E                  <1> 	pop	esi
   876 00007CA9 89EF                <1>         mov     edi, ebp
   877 00007CAB 8A2F                <1> 	mov	ch, [edi]
   878 00007CAD 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   879 00007CB0 66A1[4ADC0000]      <1> 	mov	ax, [AmbiguousFileName]
   880                              <1> loc_find_dir_proper_direntry_2:
   881 00007CB6 8A35[4CDC0000]      <1> 	mov     dh, [PreviousAttr]
   882 00007CBC 66891D[79DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   883 00007CC3 C3                  <1> 	retn
   884                              <1> 
   885                              <1> loc_find_dir_next_entry:
   886 00007CC4 8815[4CDC0000]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   887                              <1> loc_find_dir_next_entry_1:
   888 00007CCA 5E                  <1> 	pop	esi
   889 00007CCB 83C720              <1> 	add	edi, 32
   890                              <1> 	;inc	word [DirBuff_EntryCounter]
   891 00007CCE 6643                <1> 	inc	bx
   892 00007CD0 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   893 00007CD7 770E                <1> 	ja	short loc_ffde_stc_retn_255
   894 00007CD9 E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   895                              <1> 
   896                              <1> loc_scasb_find_dir_ext:
   897 00007CDE 3A07                <1> 	cmp	al, [edi]
   898 00007CE0 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   899                              <1> loc_scasb_find_dir_ext_inc_di:
   900 00007CE2 47                  <1> 	inc	edi
   901 00007CE3 E296                <1> 	loop    loc_lodsb_find_dir_ext
   902 00007CE5 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 00007CE7 31C9                <1> 	xor	ecx, ecx
   907 00007CE9 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 00007CEA B802000000          <1> 	mov	eax, 2 ; File Not Found
   913 00007CEF 8A35[4CDC0000]      <1> 	mov	dh, [PreviousAttr]
   914 00007CF5 66891D[79DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   915 00007CFC F9                  <1> 	stc
   916 00007CFD C3                  <1> 	retn
   917                              <1> 
   918                              <1> loc_find_free_deleted_entry_0:
   919 00007CFE 66A1[48DC0000]      <1> 	mov	ax, [FDE_AttrMask]
   920 00007D04 8A2F                <1> 	mov	ch, [edi]
   921 00007D06 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   922 00007D09 08C9                <1> 	or	cl, cl 
   923 00007D0B 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 00007D0D 80F9FF              <1> 	cmp	cl, 0FFh
   927 00007D10 7432                <1> 	je	short loc_find_free_deleted_entry_1
   928 00007D12 EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   929                              <1> 
   930                              <1> loc_check_ffde_0_repeat:
   931 00007D14 08ED                <1> 	or	ch, ch
   932 00007D16 7511                <1> 	jnz	short loc_check_ffde_0_next
   933                              <1> 
   934                              <1> loc_check_ffde_retn_2:
   935 00007D18 6629C0              <1> 	sub	ax, ax
   936 00007D1B 8A35[4CDC0000]      <1> 	mov	dh, [PreviousAttr]
   937 00007D21 66891D[79DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   938 00007D28 C3                  <1> 	retn
   939                              <1>  
   940                              <1> loc_check_ffde_0_next:
   941 00007D29 6643                <1> 	inc	bx
   942 00007D2B 83C720              <1> 	add	edi, 32
   943                              <1> 	;inc	word [DirBuff_EntryCounter]
   944                              <1> 	 
   945 00007D2E 663B1D[7BDB0000]    <1>         cmp	bx, [DirBuff_LastEntry]
   946 00007D35 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   947 00007D37 8815[4CDC0000]      <1> 	mov	[PreviousAttr], dl
   948 00007D3D 8A2F                <1> 	mov	ch, [edi]
   949 00007D3F 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   950 00007D42 EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   951                              <1> 
   952                              <1> loc_find_free_deleted_entry_1:
   953 00007D44 28D2                <1> 	sub	dl, dl      
   954                              <1> loc_find_free_deleted_entry_2:
   955 00007D46 20ED                <1> 	and	ch, ch  
   956 00007D48 74CE                <1> 	jz	short loc_check_ffde_retn_2
   957 00007D4A 80FDE5              <1> 	cmp	ch, 0E5h
   958 00007D4D 74C9                <1> 	je	short loc_check_ffde_retn_2
   959 00007D4F 6643                <1> 	inc	bx
   960 00007D51 83C720              <1> 	add	edi, 32
   961 00007D54 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   962 00007D5B 778A                <1> 	ja	short loc_ffde_stc_retn_255
   963 00007D5D 8A2F                <1> 	mov	ch, [edi]
   964 00007D5F EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   965                              <1> 
   966                              <1> pass_loc_check_ffde_0_err:
   967 00007D61 38CD                <1> 	cmp	ch, cl
   968 00007D63 741F                <1> 	je	short loc_check_ffde_attrib 
   969                              <1> 
   970 00007D65 6643                <1> 	inc	bx
   971 00007D67 83C720              <1> 	add	edi, 32
   972 00007D6A 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   973 00007D71 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   974 00007D77 8815[4CDC0000]      <1> 	mov	[PreviousAttr], dl
   975 00007D7D 8A2F                <1> 	mov	ch, [edi]
   976 00007D7F 8A570B              <1> 	mov	dl, [edi+0Bh]
   977 00007D82 EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   978                              <1> 
   979                              <1> loc_check_ffde_attrib:
   980 00007D84 88C6                <1> 	mov	dh, al
   981 00007D86 20D6                <1> 	and	dh, dl    
   982 00007D88 38F0                <1> 	cmp	al, dh
   983 00007D8A 759D                <1> 	jne	short loc_check_ffde_0_next
   984 00007D8C 20D4                <1> 	and	ah, dl
   985 00007D8E 7599                <1> 	jnz	short loc_check_ffde_0_next
   986 00007D90 30C9                <1> 	xor	cl, cl 
   987 00007D92 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 00007D94 56                  <1> 	push	esi  
  1006 00007D95 57                  <1> 	push	edi
  1007                              <1> 
  1008 00007D96 B90B000000          <1> 	mov	ecx, 11
  1009 00007D9B B020                <1> 	mov	al, 20h
  1010 00007D9D F3AA                <1> 	rep	stosb
  1011                              <1> 
  1012 00007D9F 8B3C24              <1> 	mov	edi, [esp]
  1013                              <1> 
  1014 00007DA2 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 00007DA4 B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1024                              <1> loc_check_first_dot:
  1025 00007DA6 8A06                <1> 	mov	al, [esi]
  1026 00007DA8 3C2E                <1> 	cmp	al, 2Eh
  1027 00007DAA 750C                <1> 	jne	short pass_check_first_dot
  1028 00007DAC 8807                <1> 	mov	[edi], al
  1029 00007DAE 47                  <1> 	inc	edi
  1030 00007DAF 46                  <1> 	inc	esi
  1031 00007DB0 FEC9                <1> 	dec	cl
  1032 00007DB2 75F2                <1> 	jnz	short loc_check_first_dot
  1033                              <1> 	;;(ecx <= 12)
  1034                              <1> 	;;loop	loc_check_first_dot 
  1035 00007DB4 EB30                <1> 	jmp	short stop_convert_file
  1036                              <1> 
  1037                              <1> loc_get_fchar:
  1038 00007DB6 8A06                <1> 	mov	al, [esi]
  1039                              <1> pass_check_first_dot:
  1040 00007DB8 3C61                <1> 	cmp	al, 61h ; 'a'
  1041 00007DBA 7208                <1> 	jb	short pass_name_capitalize
  1042 00007DBC 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1043 00007DBE 7704                <1> 	ja	short pass_name_capitalize
  1044 00007DC0 24DF                <1> 	and	al, 0DFh
  1045 00007DC2 8806                <1> 	mov	[esi], al
  1046                              <1> pass_name_capitalize:
  1047 00007DC4 3C21                <1> 	cmp	al, 21h
  1048 00007DC6 721E                <1> 	jb	short stop_convert_file
  1049 00007DC8 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1050 00007DCA 750C                <1> 	jne	short pass_dot_space
  1051                              <1> add_dot_space: 
  1052 00007DCC 80F904              <1> 	cmp	cl, 4
  1053 00007DCF 760E                <1> 	jna	short inc_and_loop
  1054 00007DD1 47                  <1> 	inc	edi
  1055 00007DD2 FECD                <1> 	dec	ch ; 06/03/2016
  1056 00007DD4 FEC9                <1> 	dec	cl
  1057 00007DD6 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 00007DD8 8807                <1> 	mov	[edi], al
  1069                              <1> loc_after_double_dot:
  1070                              <1> 	; 06/03/2016
  1071 00007DDA FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1072 00007DDC 740A                <1> 	jz	short stop_convert_file_x
  1073 00007DDE 47                  <1> 	inc	edi
  1074                              <1> inc_and_loop:
  1075 00007DDF FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1076 00007DE1 7403                <1> 	jz	short stop_convert_file	
  1077 00007DE3 46                  <1> 	inc	esi
  1078                              <1> 	;;(ecx <= 12)
  1079                              <1> 	;;loop	loc_get_fchar
  1080 00007DE4 EBD0                <1> 	jmp	short loc_get_fchar
  1081                              <1> 
  1082                              <1> stop_convert_file:
  1083                              <1> 	; 06/03/2016
  1084 00007DE6 30ED                <1> 	xor	ch, ch
  1085                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1086                              <1> stop_convert_file_x:
  1087 00007DE8 5F                  <1> 	pop	edi
  1088 00007DE9 5E                  <1> 	pop	esi
  1089 00007DEA 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 00007DEB 57                  <1> 	push	edi
  1109 00007DEC 56                  <1> 	push	esi
  1110                              <1> 	;push	ebx
  1111                              <1> 	;push	ecx
  1112                              <1> 	;push	edx
  1113 00007DED 50                  <1> 	push	eax
  1114                              <1>            
  1115 00007DEE 29C9                <1> 	sub	ecx, ecx
  1116                              <1> 	;sub	eax, eax
  1117 00007DF0 B11A                <1> 	mov	cl, 26
  1118                              <1> 
  1119 00007DF2 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1120 00007DF5 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1121 00007DF7 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1122                              <1> 
  1123 00007DF9 88C4                <1> 	mov	ah, al
  1124 00007DFB 80EC40              <1> 	sub	ah, 40h
  1125 00007DFE 8825[4EDC0000]      <1> 	mov	[LFN_EntryLength], ah
  1126                              <1> 	
  1127 00007E04 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 00007E06 7753                <1> 	ja	short loc_pslnsc_retn
  1131                              <1> 
  1132 00007E08 2407                <1> 	and	al, 07h ; 0Fh
  1133 00007E0A A2[4DDC0000]        <1> 	mov	[LongNameFound], al
  1134                              <1> 
  1135 00007E0F FEC8                <1> 	dec	al
  1136                              <1> 	;mov	cl, 26
  1137 00007E11 F6E1                <1> 	mul	cl
  1138                              <1> 
  1139 00007E13 89C6                <1> 	mov	esi, eax
  1140 00007E15 01CE                <1> 	add	esi, ecx
  1141                              <1> 		; to make is an ASCIZZ string
  1142                              <1> 		; with ax+26 bytes length
  1143 00007E17 81C6[50DC0000]      <1> 	add	esi, LongFileName
  1144 00007E1D 66C7060000          <1> 	mov	word [esi], 0   
  1145 00007E22 EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1146                              <1> 
  1147                              <1> pass_pslnsc_last_long_entry:
  1148 00007E24 3C04                <1> 	cmp	al, 04h
  1149 00007E26 7733                <1> 	ja	short loc_pslnsc_retn
  1150 00007E28 FE0D[4DDC0000]      <1> 	dec	byte [LongNameFound]
  1151 00007E2E 3A05[4DDC0000]      <1> 	cmp	al, [LongNameFound]
  1152 00007E34 7525                <1> 	jne	short loc_pslnsc_retn
  1153                              <1> 
  1154                              <1> loc_pslsc_move_ldir_name1:
  1155 00007E36 FEC8                <1> 	dec	al
  1156                              <1> 	;mov	cl, 26
  1157 00007E38 F6E1                <1> 	mul	cl
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name2:
  1160 00007E3A 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1161 00007E3D 880D[4FDC0000]      <1> 	mov	[LFN_CheckSum], cl 
  1162 00007E43 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1163 00007E45 BF[50DC0000]        <1> 	mov	edi, LongFileName
  1164 00007E4A 01C7                <1> 	add	edi, eax
  1165 00007E4C 46                  <1> 	inc	esi
  1166 00007E4D B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1167 00007E4F F366A5              <1> 	rep	movsw
  1168 00007E52 83C603              <1> 	add	esi, 3
  1169 00007E55 A5                  <1> 	movsd	; char 6 & 7 
  1170 00007E56 A5                  <1> 	movsd	; char 8 & 9
  1171 00007E57 A5                  <1> 	movsd	; char 10 & 11
  1172 00007E58 46                  <1> 	inc	esi
  1173 00007E59 46                  <1> 	inc	esi 
  1174 00007E5A A5                  <1> 	movsd   ; char 12 & 13 
  1175                              <1> 
  1176                              <1> loc_pslnsc_retn:
  1177 00007E5B 58                  <1>  	pop	eax
  1178                              <1> 	;pop	edx
  1179                              <1> 	;pop	ecx
  1180                              <1> 	;pop	ebx
  1181 00007E5C 5E                  <1> 	pop	esi  
  1182 00007E5D 5F                  <1> 	pop	edi
  1183                              <1>  
  1184 00007E5E 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 00007E5F 57                  <1> 	push	edi
  1205 00007E60 B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1206 00007E65 31C0                <1> 	xor	eax, eax
  1207 00007E67 F3AB                <1> 	rep	stosd 
  1208 00007E69 5F                  <1> 	pop	edi
  1209                              <1> 
  1210 00007E6A 668B06              <1> 	mov	ax, [esi]
  1211 00007E6D 80FC3A              <1> 	cmp	ah, ':'
  1212 00007E70 741C                <1> 	je	short loc_ppn_change_drive
  1213 00007E72 A0[4ED30000]        <1> 	mov	al, [Current_Drv]
  1214 00007E77 EB33                <1> 	jmp	short pass_ppn_change_drive
  1215                              <1> 
  1216                              <1> pass_ppn_cdir:
  1217 00007E79 8B35[72DD0000]      <1> 	mov	esi, [First_Path_Pos]
  1218 00007E7F AC                  <1> 	lodsb
  1219                              <1> loc_ppn_get_filename:
  1220 00007E80 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 00007E83 B10C                <1> 	mov	cl, 12
  1224                              <1> loc_ppn_get_fnchar_next:
  1225 00007E85 AA                  <1> 	stosb
  1226 00007E86 AC                  <1> 	lodsb
  1227 00007E87 3C21                <1> 	cmp	al, 21h
  1228 00007E89 7274                <1> 	jb	short loc_ppn_clc_return 
  1229 00007E8B E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1230                              <1> loc_ppn_return:
  1231 00007E8D C3                  <1> 	retn
  1232                              <1> 
  1233                              <1> loc_ppn_change_drive:
  1234 00007E8E 24DF                <1> 	and	al, 0DFh
  1235 00007E90 2C41                <1> 	sub	al, 'A'; A:
  1236 00007E92 726F                <1> 	jc	short loc_ppn_invalid_drive
  1237 00007E94 3805[E2C10000]      <1> 	cmp	[Last_DOS_DiskNo], al
  1238 00007E9A 7267                <1> 	jb	short loc_ppn_invalid_drive
  1239                              <1> 
  1240 00007E9C 46                  <1> 	inc	esi
  1241 00007E9D 46                  <1> 	inc	esi
  1242 00007E9E 8A26                <1> 	mov	ah, [esi]
  1243 00007EA0 80FC21              <1> 	cmp	ah, 21h
  1244 00007EA3 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 00007EA5 8807                <1> 	mov	[edi], al ; Drv 
  1249 00007EA7 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 00007EAB C3                  <1> 	retn
  1255                              <1> 
  1256                              <1> pass_ppn_change_drive:
  1257 00007EAC 8935[72DD0000]      <1> 	mov	[First_Path_Pos], esi
  1258 00007EB2 C705[76DD0000]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1258 00007EBA 0000                <1>
  1259 00007EBC AA                  <1> 	stosb
  1260 00007EBD 8A06                <1> 	mov	al, [esi]
  1261                              <1> loc_scan_ppn_dslash:
  1262 00007EBF 3C2F                <1> 	cmp	al, '/'
  1263 00007EC1 7506                <1>   	jne	short loc_scan_next_slash_pos
  1264 00007EC3 8935[76DD0000]      <1> 	mov	[Last_Slash_Pos], esi
  1265                              <1> loc_scan_next_slash_pos:
  1266 00007EC9 46                  <1> 	inc	esi
  1267 00007ECA 8A06                <1> 	mov	al, [esi]
  1268 00007ECC 3C20                <1> 	cmp	al, 20h
  1269 00007ECE 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1270 00007ED0 833D[76DD0000]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1271 00007ED7 76A0                <1> 	jna	short pass_ppn_cdir
  1272                              <1> 	
  1273 00007ED9 8B0D[76DD0000]      <1> 	mov	ecx, [Last_Slash_Pos]
  1274 00007EDF 8B35[72DD0000]      <1> 	mov	esi, [First_Path_Pos]
  1275 00007EE5 29F1                <1> 	sub	ecx, esi
  1276 00007EE7 41                  <1> 	inc	ecx
  1277                              <1> 	;cmp	ecx, 64
  1278 00007EE8 80F940              <1> 	cmp	cl, 64
  1279 00007EEB 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1280                              <1> 
  1281 00007EED 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1282 00007EEF F3A4                <1> 	rep	movsb
  1283                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1284 00007EF1 8B35[76DD0000]      <1> 	mov	esi, [Last_Slash_Pos]
  1285 00007EF7 46                  <1> 	inc	esi
  1286 00007EF8 89C7                <1> 	mov	edi, eax
  1287 00007EFA AC                  <1> 	lodsb
  1288 00007EFB 3C21                <1> 	cmp	al, 21h
  1289 00007EFD 7381                <1> 	jnb	short loc_ppn_get_filename
  1290                              <1> loc_ppn_clc_return:
  1291                              <1> 	;clc
  1292 00007EFF 31C0                <1> 	xor	eax, eax
  1293 00007F01 C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> loc_ppn_invalid_drive_stc:
  1296 00007F02 F5                  <1> 	cmc	 ; stc
  1297                              <1> loc_ppn_invalid_drive:
  1298                              <1> 	; cf = 1
  1299                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1300 00007F03 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 00007F07 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 00007F08 66B80008            <1> 	mov	ax, 0800h 
  1338                              <1> 		; it must not be volume name or longname
  1339 00007F0C E844DDFFFF          <1> 	call	find_first_file
  1340 00007F11 7216                <1> 	jc	short loc_fln_retn
  1341                              <1>  
  1342                              <1> loc_fln_check_FAT_Type:
  1343 00007F13 803D[4DD30000]01    <1> 	cmp	byte [Current_FATType], 1
  1344 00007F1A 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1345                              <1> 
  1346 00007F1C E839000000          <1> 	call	get_fs_longname
  1347 00007F21 C3                  <1> 	retn
  1348                              <1> 
  1349                              <1> loc_fln_check_longname_yes_sign:
  1350 00007F22 08FF                <1> 	or	bh, bh
  1351 00007F24 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1352                              <1> loc_fln_longname_not_found_retn:
  1353 00007F26 31C0                <1> 	xor	eax, eax 
  1354                              <1> 	; cf = 1 & al = 0 -> longname not found
  1355 00007F28 F9                  <1> 	stc
  1356                              <1> loc_fln_retn:
  1357 00007F29 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 00007F2A 803D[4DDC0000]01    <1>         cmp     byte [LongNameFound], 1
  1368 00007F31 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1369                              <1>              
  1370                              <1> loc_fln_calculate_checksum: 
  1371 00007F33 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 00007F38 3805[4FDC0000]      <1> 	cmp	[LFN_CheckSum], al
  1382 00007F3E 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1383                              <1> 
  1384 00007F40 BE[50DC0000]        <1> 	mov	esi, LongFileName
  1385 00007F45 A0[4DD30000]        <1> 	mov	al, [Current_FATType]
  1386 00007F4A 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 00007F4B 30C0                <1> 	xor	al, al
  1411 00007F4D 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 00007F52 D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1420 00007F54 0206                <1> 	add	al, [esi]
  1421 00007F56 46                  <1> 	inc	esi
  1422                              <1> 	;add	al, ah
  1423 00007F57 E2F9                <1> 	loop	loc_next_sum
  1424 00007F59 C3                  <1> 	retn
  1425                              <1> 
  1426                              <1> get_fs_longname:
  1427                              <1> 	; temporary (13/02/2016)
  1428 00007F5A 31C0                <1> 	xor eax, eax
  1429 00007F5C F9                  <1> 	stc
  1430 00007F5D 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 00007F5E 80E107              <1> 	and	cl, 07h
  1454 00007F61 880D[CCDD0000]      <1> 	mov	byte [mkdir_attrib], cl
  1455                              <1> 
  1456 00007F67 56                  <1> 	push	esi
  1457 00007F68 31DB                <1> 	xor	ebx, ebx
  1458 00007F6A 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  1459 00007F70 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1460 00007F75 01DE                <1> 	add	esi, ebx
  1461 00007F77 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 00007F78 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1466 00007F7C 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1467 00007F7E B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  1468 00007F83 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 00007F88 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 00007F89 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1480 00007F8D 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1481                              <1> 
  1482                              <1> loc_make_fs_directory:
  1483 00007F8F A1[48D30000]        <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 00007F94 E8B8150000          <1> 	call	make_fs_directory
  1488 00007F99 C3                  <1> 	retn
  1489                              <1> 
  1490                              <1> loc_mkdir_check_free_sectors:
  1491 00007F9A 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1492 00007F9E 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1493 00007FA1 39C1                <1> 	cmp	ecx, eax
  1494 00007FA3 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1495                              <1> 
  1496                              <1> loc_make_fat_directory:
  1497 00007FA5 891D[BCDD0000]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1498 00007FAB 890D[C8DD0000]      <1> 	mov	[mkdir_FreeSectors], ecx
  1499                              <1> 
  1500                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1501 00007FB1 A2[CEDD0000]        <1> 	mov	byte [mkdir_SecPerClust], al
  1502                              <1> 
  1503                              <1> loc_mkdir_gffc_1:
  1504 00007FB6 E8F2170000          <1> 	call	get_first_free_cluster
  1505 00007FBB 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 00007FBD A3[C0DD0000]        <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 00007FC2 31C0                <1> 	xor	eax, eax
  1522 00007FC4 89C1                <1>         mov	ecx, eax
  1523 00007FC6 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 00007FC8 E8D2FAFFFF          <1> 	call	locate_current_dir_file
  1528 00007FCD 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 00007FCF 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1532 00007FD2 752B                <1> 	jne	short loc_mkdir_stc_return
  1533                              <1> 
  1534                              <1> loc_mkdir_add_new_cluster:
  1535 00007FD4 3805[4DD30000]      <1> 	cmp	byte [Current_FATType], al ; 2
  1536                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1537 00007FDA 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1538 00007FDC 803D[4CD30000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1539                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1540 00007FE3 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1541                              <1> 
  1542 00007FE5 B00C                <1> 	mov	al, 12 ; No more files 
  1543                              <1> loc_mkdir_gffc_retn:
  1544 00007FE7 C3                  <1> 	retn
  1545                              <1> 
  1546                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1547 00007FE8 8B0D[C8DD0000]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1548                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1549 00007FEE A0[CEDD0000]        <1> 	mov	al, [mkdir_SecPerClust]
  1550 00007FF3 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1551 00007FF6 39C1                <1> 	cmp	ecx, eax
  1552 00007FF8 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 00007FFA 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 00007FFE C3                  <1> 	retn
  1563                              <1> 
  1564                              <1> loc_mkdir_stc_return:
  1565 00007FFF F9                  <1> 	stc
  1566 00008000 C3                  <1> 	retn 
  1567                              <1> 
  1568                              <1> loc_mkdir_gffc_2:
  1569 00008001 E8A7170000          <1> 	call	get_first_free_cluster
  1570 00008006 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 00008008 A3[C0DD0000]        <1> 	mov	[mkdir_FFCluster], eax
  1578                              <1> 
  1579 0000800D A1[C4DD0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1580                              <1> 
  1581 00008012 E825170000          <1> 	call	load_FAT_sub_directory 
  1582 00008017 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1583                              <1> 
  1584 00008019 31FF                <1> 	xor	edi, edi
  1585                              <1> loc_mkdir_set_ff_dir_entry_1:
  1586                              <1> 	; 27/02/2016
  1587 0000801B 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1588                              <1> 	; EDI = Directory Entry Address
  1589 0000801C 8B35[BCDD0000]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1590 00008022 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1591                              <1> 
  1592 00008027 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1593                              <1> 			; CH = 0 -> File size is 0
  1594 0000802B 0A0D[CCDD0000]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1595 00008031 E8B0010000          <1> 	call	make_directory_entry
  1596                              <1> 
  1597 00008036 5E                  <1> 	pop	esi
  1598                              <1> 
  1599 00008037 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1600 0000803E E880020000          <1> 	call	save_directory_buffer
  1601 00008043 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1602                              <1> 
  1603                              <1> loc_mkdir_return:
  1604 00008049 C3                  <1> 	retn
  1605                              <1> 
  1606                              <1> loc_mkdir_add_new_subdir_cluster:
  1607 0000804A 8B15[7DDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  1608 00008050 8915[C4DD0000]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1609                              <1> 
  1610 00008056 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1611 0000805B E8DC160000          <1> 	call	load_FAT_sub_directory 
  1612 00008060 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 00008062 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 00008064 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1623 00008068 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1624 0000806C 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1625 0000806F 6689C1              <1> 	mov	cx, ax
  1626 00008072 6629C0              <1> 	sub	ax, ax ; 0
  1627 00008075 F3AB                <1> 	rep	stosd ; clear directory buffer
  1628                              <1> 
  1629 00008077 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1630 0000807E E840020000          <1> 	call	save_directory_buffer 
  1631 00008083 72C4                <1> 	jc	short loc_mkdir_return
  1632                              <1> 
  1633                              <1> loc_mkdir_save_added_cluster:
  1634 00008085 A1[C4DD0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1635 0000808A 8B0D[C0DD0000]      <1> 	mov	ecx, [mkdir_FFCluster]
  1636                              <1> 	; 01/03/2016
  1637 00008090 31D2                <1> 	xor	edx, edx
  1638 00008092 8915[6EDB0000]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1639 00008098 E8E3170000          <1> 	call	update_cluster
  1640 0000809D 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1641 0000809F 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1642 000080A1 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1643                              <1> 
  1644                              <1> loc_mkdir_save_fat_buffer_0:
  1645 000080A3 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1646 000080A8 A3[C4DD0000]        <1> 	mov	[mkdir_LastDirCluster], eax
  1647                              <1> 
  1648 000080AD 31C9                <1> 	xor	ecx, ecx
  1649 000080AF 49                  <1> 	dec	ecx ; FFFFFFFFh
  1650                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1651 000080B0 E8CB170000          <1> 	call	update_cluster
  1652 000080B5 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1653 000080B7 09C0                <1> 	or	eax, eax
  1654 000080B9 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 000080BB 803D[6EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1659 000080C2 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1660                              <1> 
  1661 000080C4 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 000080C8 50                  <1> 	push	eax
  1664 000080C9 E8041B0000          <1> 	call	calculate_fat_freespace
  1665 000080CE 58                  <1> 	pop	eax
  1666 000080CF F9                  <1> 	stc
  1667                              <1> loc_mkdir_save_fat_buffer_retn:
  1668 000080D0 C3                  <1> 	retn
  1669                              <1> 
  1670                              <1> loc_mkdir_save_fat_buffer_1:
  1671                              <1> 	; byte [FAT_BuffValidData] = 2 
  1672 000080D1 E8671A0000          <1> 	call	save_fat_buffer
  1673 000080D6 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1674                              <1> 
  1675                              <1> 	; 01/03/2016
  1676 000080D8 803D[6EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1677 000080DF 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1678                              <1> 
  1679                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1680 000080E1 A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1681 000080E6 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1682 000080EA 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 000080EF 09C9                <1> 	or	ecx, ecx 
  1689 000080F1 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1690                              <1> 
  1691 000080F3 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1692 000080F7 E8D61A0000          <1> 	call	calculate_fat_freespace
  1693                              <1> 
  1694                              <1> loc_mkdir_save_fat_buffer_2:
  1695 000080FC C605[CFDD0000]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1696 00008103 E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1697                              <1> 
  1698                              <1> loc_mkdir_update_sub_dir_cluster:
  1699 00008108 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1700 0000810D 29C9                <1> 	sub	ecx, ecx ; 0
  1701                              <1> 	; 01/03/2016
  1702 0000810F 890D[6EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1703 00008115 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1704                              <1> 
  1705                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1706 00008116 E865170000          <1> 	call	update_cluster
  1707 0000811B 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1708 0000811D 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1709 0000811F 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1710                              <1> 	; 01/03/2016
  1711 00008121 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 00008123 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1716                              <1> 	; Load disk sectors as a directory cluster
  1717 00008128 E80F160000          <1> 	call	load_FAT_sub_directory 
  1718 0000812D 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 0000812F BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1724                              <1> 
  1725                              <1> 	; 02/03/2016
  1726 00008134 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1727 00008138 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1728 0000813C F7E1                <1> 	mul 	ecx
  1729 0000813E 89C1                <1> 	mov	ecx, eax
  1730 00008140 6629C0              <1> 	sub	ax, ax
  1731 00008143 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 00008145 BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1742                              <1> 	
  1743 0000814A 56                  <1> 	push	esi
  1744                              <1> 
  1745 0000814B BE[D0DD0000]        <1> 	mov	esi, mkdir_Name
  1746 00008150 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1747                              <1> 
  1748 00008155 A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1749 0000815A 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1750                              <1> 			; CH = 0 -> File size is 0
  1751 0000815E E883000000          <1> 	call	make_directory_entry
  1752                              <1> 
  1753 00008163 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 Format—Page 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 00008168 29C0                <1> 	sub	eax, eax
  1769 0000816A 3805[4CD30000]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1770 00008170 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1771 00008172 A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1772                              <1> loc_mkdir_set_ff_dir_entry_3:
  1773 00008177 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1774                              <1> 
  1775                              <1> 	;mov	cx, 10h
  1776 0000817D E864000000          <1> 	call	make_directory_entry
  1777                              <1> 
  1778 00008182 5E                  <1> 	pop	esi
  1779                              <1> 
  1780 00008183 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1781 0000818A E834010000          <1> 	call	save_directory_buffer
  1782 0000818F 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1783                              <1>  
  1784                              <1> retn_make_fat_directory:
  1785 00008195 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 00008196 E8A2190000          <1> 	call	save_fat_buffer
  1791 0000819B 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1792                              <1> 
  1793 000081A1 803D[6EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1794 000081A8 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1795                              <1> 
  1796                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1797 000081AA A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1798 000081AF 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1799 000081B3 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 000081B8 09C9                <1> 	or	ecx, ecx 
  1806 000081BA 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1807                              <1> 
  1808 000081BC 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space
  1809 000081C0 E80D1A0000          <1> 	call	calculate_fat_freespace
  1810                              <1> 
  1811                              <1> loc_mkdir_save_fat_buffer_4:	
  1812 000081C5 C605[CFDD0000]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1813                              <1> 
  1814                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1815 000081CC E88D010000          <1> 	call	update_parent_dir_lmdt
  1816                              <1> 
  1817                              <1> 	; 01/03/2016
  1818 000081D1 803D[CFDD0000]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1819 000081D8 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1820                              <1> 
  1821                              <1> loc_mkdir_retn_new_dir_cluster:
  1822 000081DE A1[C0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1823 000081E3 31D2                <1> 	xor	edx, edx
  1824                              <1> loc_mkdir_retn:
  1825 000081E5 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 000081E6 51                  <1> 	push	ecx
  1850                              <1> 
  1851 000081E7 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1852 000081EA 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1853 000081EE C1E810              <1> 	shr	eax, 16
  1854 000081F1 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1855 000081F5 6631C0              <1> 	xor	ax, ax 
  1856 000081F8 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1857                              <1> 			     ; CrtTimeTenth, 13
  1858 000081FC 08ED                <1> 	or	ch, ch
  1859 000081FE 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1860                              <1> 
  1861 00008200 8B03                <1> 	mov	eax, [ebx]
  1862                              <1>         
  1863                              <1> loc_make_direntry_set_filesize:
  1864 00008202 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1865                              <1> 	
  1866 00008205 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 0000820A 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 0000820F 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1874 00008213 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1875 00008217 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1876 0000821B 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1877 0000821F 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1878 00008223 59                  <1> 	pop	ecx
  1879                              <1> 
  1880 00008224 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 00008225 B404                <1> 	mov	ah, 04h ; Return Current Date
  1891 00008227 E8CAB9FFFF          <1> 	call	int1Ah 
  1892                              <1> 
  1893 0000822C 88E8                <1> 	mov	al, ch ; <- century BCD
  1894 0000822E 240F                <1> 	and	al, 0Fh
  1895 00008230 88EC                <1> 	mov	ah, ch
  1896 00008232 C0EC04              <1> 	shr	ah, 4
  1897 00008235 D50A                <1> 	aad
  1898 00008237 88C5                <1> 	mov	ch, al ; -> century 
  1899                              <1> 
  1900 00008239 88C8                <1> 	mov	al, cl ; <- year BCD
  1901 0000823B 240F                <1> 	and	al, 0Fh
  1902 0000823D 88CC                <1> 	mov	ah, cl
  1903 0000823F C0EC04              <1> 	shr	ah, 4
  1904 00008242 D50A                <1> 	aad
  1905 00008244 88C1                <1> 	mov	cl, al ; -> year
  1906                              <1> 
  1907 00008246 88E8                <1> 	mov	al, ch
  1908 00008248 B464                <1> 	mov	ah, 100
  1909 0000824A F6E4                <1> 	mul	ah
  1910 0000824C 30ED                <1> 	xor	ch, ch
  1911 0000824E 6601C8              <1> 	add	ax, cx
  1912 00008251 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1913 00008255 6689C1              <1> 	mov	cx, ax
  1914                              <1> 
  1915 00008258 88F0                <1> 	mov	al, dh ; <- month in bcd
  1916 0000825A 240F                <1> 	and	al, 0Fh
  1917 0000825C 88F4                <1> 	mov	ah, dh
  1918 0000825E C0EC04              <1> 	shr	ah, 4
  1919 00008261 D50A                <1> 	aad
  1920 00008263 88C6                <1> 	mov	dh, al ; -> month
  1921                              <1> 
  1922 00008265 88D0                <1> 	mov	al, dl ; <- day BCD
  1923 00008267 240F                <1> 	and	al, 0Fh
  1924 00008269 88D4                <1> 	mov	ah, dl
  1925 0000826B C0EC04              <1> 	shr	ah, 4
  1926 0000826E D50A                <1> 	aad
  1927 00008270 88C2                <1> 	mov	dl, al ; -> day
  1928                              <1> 
  1929 00008272 88C8                <1> 	mov	al, cl ; count of years from 1980
  1930 00008274 66C1E004            <1> 	shl	ax, 4
  1931 00008278 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1932 0000827A 66C1E005            <1> 	shl	ax, 5
  1933 0000827E 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1934                              <1> 	
  1935 00008280 6650                <1> 	push	ax ; push date
  1936                              <1> 
  1937 00008282 B402                <1> 	mov	ah, 02h ; Return Current Time
  1938 00008284 E86DB9FFFF          <1> 	call	int1Ah
  1939                              <1> 
  1940 00008289 88E8                <1> 	mov	al, ch ; <- hours BCD
  1941 0000828B 240F                <1> 	and	al, 0Fh
  1942 0000828D 88EC                <1> 	mov	ah, ch
  1943 0000828F C0EC04              <1> 	shr	ah, 4
  1944 00008292 D50A                <1> 	aad
  1945 00008294 88C5                <1> 	mov	ch, al ; -> hours
  1946                              <1> 
  1947 00008296 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1948 00008298 240F                <1> 	and	al, 0Fh
  1949 0000829A 88CC                <1> 	mov	ah, cl
  1950 0000829C C0EC04              <1> 	shr	ah, 4
  1951 0000829F D50A                <1> 	aad
  1952 000082A1 88C1                <1> 	mov	cl, al ; -> minutes
  1953                              <1> 
  1954 000082A3 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1955 000082A5 240F                <1> 	and	al, 0Fh
  1956 000082A7 88F4                <1> 	mov	ah, dh
  1957 000082A9 C0EC04              <1> 	shr	ah, 4
  1958 000082AC D50A                <1> 	aad
  1959 000082AE 88C6                <1> 	mov	dh, al ; -> seconds
  1960                              <1> 
  1961 000082B0 88E8                <1> 	mov	al, ch ; hours
  1962 000082B2 66C1E006            <1> 	shl	ax, 6
  1963 000082B6 08C8                <1> 	or	al, cl ; minutes
  1964 000082B8 66C1E005            <1> 	shl	ax, 5
  1965 000082BC 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 000082BE 08F0                <1> 	or	al, dh ; seconds
  1969                              <1> 
  1970 000082C0 665A                <1> 	pop	dx ; pop date
  1971                              <1> 	
  1972 000082C2 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 000082C3 BB00000800          <1> 	mov	ebx, Directory_Buffer
  1991 000082C8 803D[78DB0000]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1992 000082CF 7403                <1> 	je	short loc_save_dir_buffer
  1993 000082D1 31C0                <1> 	xor	eax, eax
  1994 000082D3 C3                  <1> 	retn            
  1995                              <1> 
  1996                              <1> loc_save_dir_buffer:
  1997 000082D4 56                  <1> 	push	esi
  1998 000082D5 31DB                <1> 	xor	ebx, ebx 
  1999 000082D7 8A3D[76DB0000]      <1>         mov     bh, [DirBuff_DRV]
  2000 000082DD 80EF41              <1> 	sub	bh, 'A'
  2001 000082E0 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2002 000082E5 01DE                <1> 	add	esi, ebx
  2003 000082E7 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2004                              <1> 	; CH = FS Type (A1h for FS)
  2005                              <1> 	; CL = FAT Type (0 for FS)
  2006 000082EB 08C9                <1> 	or	cl, cl
  2007 000082ED 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2008                              <1> 
  2009                              <1> loc_save_dir_buffer_check_cluster_no:    
  2010 000082EF A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2011 000082F4 28FF                <1> 	sub	bh, bh ; ebx = 0
  2012 000082F6 09C0                <1> 	or	eax, eax
  2013 000082F8 7540                <1> 	jnz	short loc_save_sub_dir_buffer
  2014 000082FA 8A25[77DB0000]      <1> 	mov	ah, [DirBuff_FATType]
  2015 00008300 FEC3                <1> 	inc	bl ;  bl = 1
  2016 00008302 38DC                <1> 	cmp	ah, bl
  2017 00008304 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2018 00008306 FEC3                <1> 	inc	bl ; bl = 2
  2019 00008308 38E3                <1> 	cmp	bl, ah
  2020 0000830A 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2021                              <1> 
  2022                              <1> loc_save_root_dir_buffer:
  2023 0000830C 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2024 00008310 6683C30F            <1> 	add	bx, 15
  2025 00008314 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2026 00008318 6609DB              <1> 	or	bx, bx
  2027 0000831B 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2028                              <1> 	;mov	ecx, ebx 
  2029 0000831D 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2030 00008320 EB23                <1> 	jmp	short loc_write_directory_to_disk
  2031                              <1> 
  2032                              <1> loc_save_dir_buff_stc_retn:
  2033 00008322 F9                  <1> 	stc
  2034                              <1> loc_save_dir_buff_inv_data_retn:
  2035 00008323 B00D                <1> 	mov	al, 0Dh ; Invalid data !
  2036 00008325 C605[78DB0000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2037 0000832C 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 0000832E B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error 
  2042                              <1> 
  2043                              <1> loc_save_dir_buff_retn:
  2044 00008333 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2045 00008338 5E                  <1> 	pop	esi
  2046 00008339 C3                  <1> 	retn
  2047                              <1>  
  2048                              <1> loc_save_sub_dir_buffer:
  2049                              <1> 	; ebx  = 0
  2050 0000833A 83E802              <1> 	sub	eax, 2
  2051 0000833D 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2052 00008340 F7E3                <1> 	mul	ebx
  2053 00008342 034668              <1>         add     eax, [esi+LD_DATABegin]
  2054                              <1>  	;mov	ecx, ebx
  2055                              <1> 
  2056                              <1> loc_write_directory_to_disk:
  2057 00008345 89D9                <1>  	mov	ecx, ebx
  2058 00008347 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2059 0000834C E8A23A0000          <1> 	call	disk_write
  2060 00008351 72DB                <1> 	jc	short loc_write_directory_to_disk_err
  2061                              <1> 
  2062                              <1> loc_save_dir_buff_validate_retn:
  2063 00008353 C605[78DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2064 0000835A 31C0                <1> 	xor	eax, eax
  2065                              <1> 	; 26/02/2016
  2066 0000835C 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 0000835E 29C0                <1> 	sub	eax, eax
  2082 00008360 8A25[4CD30000]      <1> 	mov	ah, [Current_Dir_Level]
  2083 00008366 A0[4DD30000]        <1> 	mov	al, [Current_FATType]
  2084 0000836B 3C01                <1> 	cmp	al, 1
  2085 0000836D 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2086                              <1>     
  2087                              <1> loc_update_parent_dir_lm_date_time:
  2088 0000836F 08E4                <1> 	or	ah, ah
  2089 00008371 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2090                              <1> 
  2091 00008373 56                  <1> 	push	esi ; *
  2092 00008374 8825[F0DD0000]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2093 0000837A 8B15[48D30000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2094 00008380 8915[F1DD0000]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2095                              <1> 
  2096 00008386 FECC                <1> 	dec	ah
  2097 00008388 B90C000000          <1> 	mov	ecx, 12
  2098 0000838D BE[AFDB0000]        <1>         mov     esi, PATH_Array
  2099                              <1> 
  2100 00008392 8825[4CD30000]      <1> 	mov	[Current_Dir_Level], ah
  2101 00008398 08E4                <1> 	or	ah, ah
  2102 0000839A 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2103 0000839C 803D[4DD30000]02    <1> 	cmp	byte [Current_FATType], 2
  2104 000083A3 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2105 000083A5 28C0                <1> 	sub	al, al ; eax = 0
  2106 000083A7 EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2107                              <1> 
  2108                              <1> loc_UPDLMDT_proc_retn:
  2109 000083A9 C3                  <1> 	retn
  2110                              <1>          
  2111                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2112 000083AA B010                <1> 	mov	al, 16
  2113 000083AC F6E4                <1> 	mul	ah 
  2114 000083AE 01C6                <1> 	add	esi, eax
  2115                              <1> 
  2116                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2117 000083B0 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2118                              <1> 
  2119                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2120 000083B3 A3[48D30000]        <1> 	mov	[Current_Dir_FCluster], eax
  2121                              <1> 
  2122 000083B8 83C610              <1> 	add	esi, 16
  2123 000083BB 66BF[D6DC]          <1> 	mov	di, Dir_File_Name  
  2124 000083BF F3A4                <1> 	rep	movsb
  2125                              <1> 	
  2126 000083C1 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2127 000083C6 29DB                <1> 	sub	ebx, ebx
  2128 000083C8 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  2129 000083CE 01DE                <1> 	add	esi, ebx
  2130 000083D0 E88FF7FFFF          <1> 	call	reload_current_directory
  2131 000083D5 7232                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2132                              <1> 
  2133                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2134 000083D7 BE[D6DC0000]        <1> 	mov	esi, Dir_File_Name        
  2135 000083DC 6631C9              <1> 	xor	cx, cx
  2136 000083DF 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2137 000083E3 E8B7F6FFFF          <1>         call    locate_current_dir_file
  2138                              <1> 	; EDI = DirBuff Directory Entry Address
  2139 000083E8 721F                <1> 	jc short loc_update_parent_dir_lmdt_restore_cdirlevel
  2140                              <1> 
  2141 000083EA E836FEFFFF          <1> 	call	convert_current_date_time
  2142 000083EF 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2143 000083F3 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2144 000083F7 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2145                              <1> 
  2146 000083FB C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2147 00008402 E8BCFEFFFF          <1> 	call	save_directory_buffer
  2148 00008407 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 00008409 8A25[F0DD0000]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2153 0000840F 8825[4CD30000]      <1> 	mov	[Current_Dir_Level], ah
  2154 00008415 8B15[F1DD0000]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2155 0000841B 8915[48D30000]      <1> 	mov	[Current_Dir_FCluster], edx
  2156                              <1> 
  2157 00008421 5E                  <1> 	pop	esi ; *
  2158 00008422 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 00008423 66A3[1CDE0000]      <1> 	mov	[DLN_EntryNumber], ax
  2173 00008429 C605[1EDE0000]40    <1>         mov     byte [DLN_40h], 40h
  2174                              <1> 
  2175 00008430 E858000000          <1> 	call	locate_current_dir_entry
  2176 00008435 7308                <1> 	jnc	short loc_dln_check_attributes
  2177 00008437 C3                  <1> 	retn
  2178                              <1> 
  2179                              <1> loc_dln_longname_not_found:
  2180 00008438 B802000000          <1> 	mov	eax, 2
  2181 0000843D F9                  <1> 	stc
  2182 0000843E C3                  <1> 	retn
  2183                              <1> 
  2184                              <1> loc_dln_check_attributes:
  2185 0000843F B00F                <1> 	mov	al, 0Fh  ; long name
  2186 00008441 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2187 00008444 38C4                <1> 	cmp	ah, al
  2188 00008446 75F0                <1> 	jne	short loc_dln_longname_not_found
  2189 00008448 8A27                <1> 	mov	ah, [edi]
  2190 0000844A 2A25[1EDE0000]      <1> 	sub	ah, [DLN_40h]
  2191 00008450 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2192 00008452 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2193 00008455 77E1                <1> 	ja	short loc_dln_longname_not_found
  2194                              <1>              
  2195 00008457 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2196 0000845A C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2197 00008461 C605[1EDE0000]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2198                              <1> 	  
  2199                              <1> loc_dln_delete_next_ln_entry:
  2200 00008468 80FC01              <1> 	cmp	ah, 1
  2201 0000846B 7616                <1> 	jna	short loc_dln_longname_retn
  2202                              <1> loc_dln_delete_next_ln_entry_0:
  2203 0000846D 66FF05[1CDE0000]    <1> 	inc	word [DLN_EntryNumber]
  2204 00008474 0FB705[1CDE0000]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2205 0000847B E80D000000          <1> 	call	locate_current_dir_entry
  2206 00008480 73BD                <1> 	jnc	short loc_dln_check_attributes
  2207                              <1> 
  2208                              <1> loc_dln_longname_stc_retn:
  2209 00008482 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 00008483 E83BFEFFFF          <1> 	call	save_directory_buffer
  2215 00008488 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2216                              <1> 
  2217                              <1> loc_dln_longname_retn_xor_eax:
  2218 0000848A 31C0                <1> 	xor	eax, eax
  2219 0000848C 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 0000848D 56                  <1> 	push	esi
  2244 0000848E 89C1                <1> 	mov	ecx, eax
  2245 00008490 BA20000000          <1> 	mov	edx, 32
  2246 00008495 F7E2                <1> 	mul	edx 
  2247 00008497 A3[28DE0000]        <1> 	mov	[LCDE_ByteOffset], eax
  2248 0000849C 31DB                <1> 	xor	ebx, ebx
  2249 0000849E 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  2250 000084A4 A0[76DB0000]        <1>         mov     al, [DirBuff_DRV]
  2251 000084A9 2C41                <1> 	sub	al, 'A'
  2252 000084AB BE00010900          <1>         mov     esi, Logical_DOSDisks
  2253 000084B0 01DE                <1> 	add	esi, ebx
  2254 000084B2 38C7                <1> 	cmp	bh, al
  2255 000084B4 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2256                              <1> loc_lcde_cdl_check:
  2257 000084BA 803D[4CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2258 000084C1 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 000084C3 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2263 000084C7 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2264                              <1> 
  2265                              <1> loc_lcde_cdl_check_FAT12_16:
  2266 000084C9 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2267 000084CD 6648                <1> 	dec	ax
  2268                              <1> 	;xor	dx, dx  
  2269 000084CF 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2270 000084D2 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2271 000084D4 66890D[20DE0000]    <1> 	mov	[LCDE_EntryIndex], cx
  2272 000084DB 31C0                <1> 	xor	eax, eax
  2273 000084DD E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2274                              <1> 
  2275                              <1> loc_lcde_stc_12h_retn:
  2276 000084E2 5E                  <1> 	pop	esi
  2277 000084E3 89CB                <1> 	mov	ebx, ecx
  2278 000084E5 89D1                <1> 	mov	ecx, edx
  2279 000084E7 B812000000          <1> 	mov	eax, 12h ; No more files
  2280 000084EC C3                  <1> 	retn 
  2281                              <1> 
  2282                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2283 000084ED 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2284 000084F0 30FF                <1> 	xor	bh, bh
  2285 000084F2 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2286 000084F6 66F7E3              <1> 	mul	bx
  2287 000084F9 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2288 000084FC 755D                <1> 	jnz	short loc_lcde_invalid_format
  2289                              <1> 	;mov	ecx, eax
  2290 000084FE 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2291 00008501 A1[28DE0000]        <1> 	mov	eax, [LCDE_ByteOffset]
  2292                              <1> 	;sub	edx, edx
  2293 00008506 F7F1                <1> 	div	ecx
  2294 00008508 3DFFFF0000          <1> 	cmp	eax, 65535
  2295 0000850D 774C                <1> 	ja	short loc_lcde_invalid_format
  2296                              <1> 
  2297                              <1> 	; cluster sequence number of directory (< 65536)
  2298 0000850F 66A3[22DE0000]      <1> 	mov	[LCDE_ClusterSN], ax 
  2299                              <1> 
  2300 00008515 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2301 00008518 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2302 0000851C 6629D2              <1>         sub     dx, dx  ; 0
  2303 0000851F 66F7F3              <1> 	div	bx 
  2304 00008522 66A3[20DE0000]      <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 00008528 A1[48D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2308                              <1> 
  2309                              <1> loc_lcde_get_next_cluster:
  2310 0000852D 66833D[22DE0000]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2311 00008535 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2312 00008537 A3[24DE0000]        <1> 	mov	[LCDE_Cluster], eax
  2313 0000853C E815100000          <1> 	call	get_next_cluster
  2314 00008541 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2315 00008543 66FF0D[22DE0000]    <1>   	dec	word [LCDE_ClusterSN]
  2316 0000854A EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2317                              <1> 
  2318                              <1> loc_lcde_reload_current_directory:
  2319 0000854C 51                  <1> 	push	ecx
  2320 0000854D E812F6FFFF          <1> 	call	reload_current_directory
  2321 00008552 59                  <1> 	pop	ecx
  2322 00008553 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2323 00008559 5E                  <1> 	pop	esi
  2324 0000855A C3                  <1> 	retn
  2325                              <1> 
  2326                              <1> loc_lcde_invalid_format:
  2327 0000855B 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 00008560 F9                  <1> 	stc
  2331 00008561 5E                  <1> 	pop	esi 
  2332 00008562 C3                  <1> 	retn  
  2333                              <1> 
  2334                              <1> loc_lcde_check_gnc_error:
  2335 00008563 09C0                <1> 	or	eax, eax
  2336 00008565 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2337 00008567 66FF0D[22DE0000]    <1> 	dec	word [LCDE_ClusterSN]
  2338 0000856E 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2339 00008570 A1[24DE0000]        <1> 	mov	eax, [LCDE_Cluster]
  2340                              <1> 
  2341                              <1> loc_lcde_check_dir_buffer_cluster:
  2342 00008575 3B05[7DDB0000]      <1> 	cmp	eax, [DirBuff_Cluster]
  2343 0000857B 755C                <1> 	jne	short loc_lcde_load_dir_cluster
  2344 0000857D 803D[78DB0000]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2345 00008584 7727                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2346 00008586 803D[4CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2347 0000858D 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 0000858F 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2351 00008593 7359                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2352                              <1> 	;
  2353 00008595 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2354 00008599 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2355 0000859D 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2356                              <1> 
  2357 000085A1 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2358 000085A4 EB54                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2359                              <1> 
  2360                              <1> loc_lcde_validate_dirBuff:
  2361 000085A6 C605[78DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2362                              <1> 
  2363                              <1> lcde_check_dir_buffer_cluster_next:
  2364 000085AD 0FB71D[20DE0000]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2365 000085B4 663B1D[7BDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2366 000085BB 779E                <1> 	ja	short loc_lcde_invalid_format 
  2367 000085BD B820000000          <1> 	mov	eax, 32
  2368 000085C2 F7E3                <1> 	mul	ebx
  2369                              <1> 	;or	edx, edx
  2370                              <1> 	;jnz	short loc_lcde_invalid_format
  2371                              <1> 
  2372 000085C4 BF00000800          <1> 	mov	edi, Directory_Buffer  
  2373 000085C9 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2374                              <1> 
  2375                              <1> loc_lcde_dir_buffer_last_check:
  2376 000085CB A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2377 000085D0 0FB60D[78DB0000]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2378                              <1> 
  2379                              <1> loc_lcde_retn:
  2380 000085D7 5E                  <1> 	pop	esi
  2381 000085D8 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 000085D9 50                  <1> 	push	eax
  2387 000085DA E8E4FCFFFF          <1> 	call	save_directory_buffer
  2388 000085DF 58                  <1> 	pop	eax
  2389 000085E0 72F5                <1> 	jc	short loc_lcde_retn
  2390                              <1> 
  2391                              <1> loc_lcde_load_dir_cluster_n2:
  2392 000085E2 C605[78DB0000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2393 000085E9 A3[7DDB0000]        <1> 	mov	[DirBuff_Cluster], eax
  2394                              <1> 
  2395                              <1> loc_lcde_load_dir_cluster_0:
  2396 000085EE 83E802              <1> 	sub	eax, 2
  2397 000085F1 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2398 000085F5 F7E1                <1> 	mul	ecx
  2399 000085F7 034668              <1>         add     eax, [esi+LD_DATABegin]
  2400                              <1> 
  2401                              <1> loc_lcde_load_dir_cluster_1:
  2402 000085FA BB00000800          <1> 	mov	ebx, Directory_Buffer
  2403                              <1> 	; ecx = sector count
  2404 000085FF E8FE370000          <1> 	call	disk_read
  2405 00008604 73A0                <1> 	jnc	short loc_lcde_validate_dirBuff
  2406                              <1> 
  2407                              <1> 	; 23/03/2016
  2408 00008606 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  2409 0000860B 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 0000860D 29C0                <1> 	sub	eax, eax
  2423 0000860F 88FC                <1> 	mov	ah, bh
  2424 00008611 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2425 00008616 01C6                <1> 	add	esi, eax
  2426                              <1> 
  2427 00008618 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2428 0000861C 7312                <1> 	jnb	short loc_del_fat_file 
  2429                              <1>               
  2430 0000861E 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2431 00008622 7406                <1> 	je	short loc_del_fs_file
  2432                              <1> 
  2433                              <1> loc_del_file_invalid_format:
  2434 00008624 30E4                <1> 	xor	ah, ah
  2435 00008626 B00B                <1> 	mov	al, 0Bh ; Invalid Format
  2436 00008628 F9                  <1> 	stc 
  2437 00008629 C3                  <1> 	retn
  2438                              <1> 
  2439                              <1> loc_del_fs_file:
  2440 0000862A E8200F0000          <1> 	call	delete_fs_file
  2441 0000862F C3                  <1> 	retn
  2442                              <1> 
  2443                              <1> loc_del_fat_file:
  2444 00008630 E808000000          <1> 	call	delete_directory_entry
  2445 00008635 7205                <1> 	jc	short loc_del_file_err_retn 
  2446                              <1> 
  2447                              <1> loc_delfile_unlink_cluster_chain:
  2448 00008637 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 0000863C 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 0000863D 881D[BADD0000]      <1> 	mov	[DelFile_LNEL], bl
  2474 00008643 66890D[B8DD0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2475                              <1> 
  2476 0000864A 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2477 0000864E C1E010              <1> 	shl	eax, 16
  2478 00008651 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2479                              <1> 
  2480 00008655 A3[B4DD0000]        <1> 	mov	[DelFile_FCluster], eax
  2481                              <1> 
  2482                              <1> loc_del_short_name:
  2483 0000865A C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2484                              <1> 
  2485 0000865D C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2486 00008664 E85AFCFFFF          <1> 	call	save_directory_buffer
  2487 00008669 723D                <1> 	jc	short loc_delete_direntry_err_return
  2488                              <1>  
  2489                              <1> loc_del_long_name:
  2490 0000866B 0FB615[BADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2491 00008672 08D2                <1> 	or	dl, dl
  2492 00008674 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2493                              <1> 
  2494 00008676 8835[BADD0000]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2495                              <1>   
  2496 0000867C 0FB705[B8DD0000]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2497 00008683 29D0                <1> 	sub	eax, edx
  2498                              <1> 	;jnc	short loc_del_long_name_continue
  2499 00008685 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 00008687 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 0000868C 801D[BADD0000]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2512                              <1> 
  2513 00008693 E8C6FCFFFF          <1> 	call	update_parent_dir_lmdt
  2514 00008698 B700                <1> 	mov	bh, 0
  2515 0000869A 80D700              <1> 	adc	bh, 0
  2516                              <1> 
  2517 0000869D 8A1D[BADD0000]      <1> 	mov	bl, byte [DelFile_LNEL]
  2518                              <1>  
  2519                              <1> loc_delete_direntry_return:
  2520 000086A3 A1[B4DD0000]        <1> 	mov	eax, [DelFile_FCluster]
  2521                              <1> loc_delete_direntry_err_return:
  2522 000086A8 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 000086A9 803D[4DD30000]00    <1> 	cmp	byte [Current_FATType], 0
  2541 000086B0 7706                <1> 	ja	short loc_rename_directory_entry
  2542                              <1> 
  2543 000086B2 E8990E0000          <1> 	call	rename_fs_file_or_directory
  2544 000086B7 C3                  <1> 	retn 
  2545                              <1> 	
  2546                              <1> loc_rename_directory_entry:
  2547 000086B8 881D[BADD0000]      <1> 	mov	[DelFile_LNEL], bl
  2548 000086BE 66890D[B8DD0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2549 000086C5 A3[B4DD0000]        <1> 	mov	[DelFile_FCluster], eax
  2550                              <1> 
  2551 000086CA 0FB7C1              <1> 	movzx	eax, cx
  2552 000086CD E8BBFDFFFF          <1> 	call	locate_current_dir_entry
  2553 000086D2 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2554                              <1> 
  2555                              <1> loc_rename_direntry_pop_retn:
  2556 000086D4 C3                  <1> 	retn
  2557                              <1> 
  2558                              <1> loc_rename_direntry_pop_invd_retn:
  2559 000086D5 F9                  <1> 	stc
  2560                              <1> loc_rename_direntry_invd_retn:
  2561 000086D6 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  2562                              <1> loc_rename_retn:
  2563 000086DB C3                  <1> 	retn 
  2564                              <1> 
  2565                              <1> loc_rename_direntry_check_fcluster:
  2566 000086DC 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2567 000086E0 66C1E210            <1> 	shl	dx, 16
  2568 000086E4 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2569 000086E8 3B15[B4DD0000]      <1> 	cmp	edx, [DelFile_FCluster]
  2570 000086EE 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 000086F0 E89FF6FFFF          <1> 	call	convert_file_name
  2581                              <1> 
  2582 000086F5 C605[78DB0000]02    <1>         mov     byte [DirBuff_ValidData], 2
  2583 000086FC E8C2FBFFFF          <1> 	call	save_directory_buffer
  2584 00008701 72D8                <1> 	jc	short loc_rename_retn
  2585                              <1> 
  2586                              <1> loc_rename_direntry_del_ln:
  2587 00008703 0FB615[BADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2588 0000870A 08D2                <1> 	or	dl, dl
  2589 0000870C 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2590                              <1> 
  2591 0000870E 0FB705[B8DD0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2592 00008715 29D0                <1> 	sub	eax, edx
  2593 00008717 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 00008719 E805FDFFFF          <1> 	call	delete_longname
  2598                              <1> 
  2599                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2600 0000871E E83BFCFFFF          <1> 	call	update_parent_dir_lmdt
  2601 00008723 31C0                <1> 	xor	eax, eax 
  2602 00008725 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 00008726 3C02                <1> 	cmp	al, 2
  2643 00008728 0F846D010000        <1> 	je	msftdf_df2_check_directory
  2644 0000872E A2[36DF0000]        <1> 	mov	[move_cmd_phase], al
  2645                              <1> 
  2646                              <1> msftdf_parse_sf_path:
  2647                              <1> 	; ESI = ASCIIZ pathname (Source)
  2648 00008733 57                  <1> 	push	edi 
  2649 00008734 BF[34DE0000]        <1> 	mov	edi, SourceFile_Drv
  2650 00008739 E821F7FFFF          <1> 	call	parse_path_name
  2651 0000873E 5E                  <1> 	pop	esi
  2652 0000873F 7211                <1> 	jc	short msftdf_psf_retn
  2653                              <1> 
  2654                              <1> msftdf_parse_df_path:
  2655                              <1> 	; ESI = ASCIIZ pathname	(Destination)
  2656 00008741 BF[B4DE0000]        <1> 	mov	edi, DestinationFile_Drv
  2657 00008746 E814F7FFFF          <1> 	call	parse_path_name
  2658 0000874B 7306                <1> 	jnc	short msftdf_check_sf_drv
  2659                              <1> 
  2660 0000874D 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  2661 0000874F 7602                <1> 	jna	short msftdf_check_sf_drv
  2662                              <1> 
  2663                              <1> msftdf_stc_retn:
  2664 00008751 F9                  <1> 	stc
  2665                              <1> msftdf_psf_retn:
  2666 00008752 C3                  <1> 	retn 
  2667                              <1> 
  2668                              <1> msftdf_check_sf_drv:
  2669 00008753 A0[34DE0000]        <1> 	mov	al, [SourceFile_Drv]
  2670                              <1> 
  2671                              <1> msftdf_check_df_drv:
  2672 00008758 8A15[B4DE0000]      <1> 	mov	dl, [DestinationFile_Drv]
  2673                              <1> 
  2674                              <1> msftdf_compare_sf_df_drv:
  2675 0000875E 29DB                <1> 	sub	ebx, ebx
  2676 00008760 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  2677 00008766 38C2                <1> 	cmp	dl, al
  2678 00008768 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 0000876A 88C6                <1> 	mov	dh, al ; destination file's drive number
  2683 0000876C B811000000          <1> 	mov	eax, 11h ; Not the same drive
  2684 00008771 F9                  <1> 	stc
  2685 00008772 C3                  <1> 	retn 
  2686                              <1> 
  2687                              <1> msftdf_check_sf_df_drv_ok:
  2688 00008773 8815[37DF0000]      <1> 	mov	[msftdf_sf_df_drv], dl
  2689                              <1> 
  2690 00008779 29C0                <1>         sub	eax, eax
  2691 0000877B 88D4                <1> 	mov	ah, dl
  2692 0000877D 0500010900          <1> 	add	eax, Logical_DOSDisks
  2693 00008782 A3[38DF0000]        <1> 	mov	[msftdf_drv_offset], eax
  2694                              <1> 
  2695 00008787 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  2696 00008789 7407                <1> 	je	short msftdf_df_check_directory
  2697                              <1> 
  2698                              <1> msftdf_change_drv:
  2699 0000878B E829C1FFFF          <1> 	call 	change_current_drive
  2700 00008790 725B                <1> 	jc	short msftdf_df_error_retn
  2701                              <1> 	  
  2702                              <1> msftdf_check_destination_file:
  2703                              <1> msftdf_df_check_directory:
  2704 00008792 BE[B5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  2705 00008797 803E20              <1> 	cmp	byte [esi], 20h
  2706 0000879A 760F                <1> 	jna	short msftdf_df_find_1
  2707                              <1> 
  2708                              <1> msftdf_df_change_directory:
  2709 0000879C FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2710 000087A2 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2711 000087A4 E8A2F0FFFF          <1> 	call	change_current_directory
  2712 000087A9 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 000087AB BE[F6DE0000]        <1>         mov     esi, DestinationFile_Name
  2719 000087B0 803E20              <1> 	cmp	byte [esi], 20h
  2720 000087B3 761F                <1> 	jna	short msftdf_df_copy_sf_name
  2721                              <1> 
  2722                              <1> msftdf_df_find_2:
  2723 000087B5 6631C0              <1> 	xor	ax, ax ; DestinationFile_AttributesMask -> any/zero
  2724 000087B8 E898D4FFFF          <1> 	call	find_first_file
  2725 000087BD 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 000087BF 3C02                <1> 	cmp	al, 2
  2730 000087C1 7529                <1> 	jne	short msftdf_df_stc_retn
  2731                              <1>               
  2732                              <1> msftdf_convert_df_direntry_name:
  2733 000087C3 BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  2734 000087C8 BF[06DF0000]        <1> 	mov	edi, DestinationFile_DirEntry
  2735 000087CD E8C2F5FFFF          <1> 	call	convert_file_name
  2736 000087D2 EB1A                <1>   	jmp	short msftdf_restore_current_dir_1
  2737                              <1> 
  2738                              <1> msftdf_df_copy_sf_name:
  2739 000087D4 89F7                <1> 	mov	edi, esi
  2740 000087D6 57                  <1> 	push	edi 
  2741 000087D7 BE[76DE0000]        <1>         mov     esi, SourceFile_Name
  2742 000087DC B90C000000          <1> 	mov	ecx, 12
  2743                              <1> msftdf_df_copy_sf_name_loop:
  2744 000087E1 AC                  <1> 	lodsb
  2745 000087E2 AA                  <1>         stosb
  2746 000087E3 08C0                <1> 	or	al, al
  2747 000087E5 7402                <1> 	jz	short msftdf_df_copy_sf_name_ok	
  2748 000087E7 E2F8                <1>         loop    msftdf_df_copy_sf_name_loop
  2749                              <1> msftdf_df_copy_sf_name_ok:	
  2750 000087E9 5E                  <1> 	pop	esi  
  2751 000087EA EBC9                <1> 	jmp	short msftdf_df_find_2
  2752                              <1> 
  2753                              <1> msftdf_df_stc_retn:
  2754 000087EC F9                  <1> 	stc
  2755                              <1> msftdf_restore_cdir_failed:
  2756                              <1> msftdf_df_error_retn:
  2757 000087ED C3                  <1> 	retn
  2758                              <1> 
  2759                              <1> msftdf_restore_current_dir_1:
  2760 000087EE 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2761 000087F5 760D                <1> 	jna	short msftdf_sf_check_directory
  2762 000087F7 8B35[38DF0000]      <1> 	mov	esi, [msftdf_drv_offset] 
  2763 000087FD E869C1FFFF          <1> 	call	restore_current_directory
  2764 00008802 72E9                <1> 	jc	short msftdf_restore_cdir_failed
  2765                              <1> 
  2766                              <1> msftdf_sf_check_directory:
  2767 00008804 BE[35DE0000]        <1> 	mov	esi, SourceFile_Directory
  2768 00008809 803E20              <1> 	cmp	byte [esi], 20h
  2769 0000880C 760F                <1> 	jna	short msftdf_sf_find
  2770                              <1> msftdf_sf_change_directory:
  2771 0000880E FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2772 00008814 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2773 00008816 E830F0FFFF          <1> 	call	change_current_directory
  2774 0000881B 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 0000881D BE[76DE0000]        <1>         mov     esi, SourceFile_Name  ; Offset 66
  2781 00008822 66B80018            <1> 	mov	ax, 1800h ; Only files
  2782 00008826 E82AD4FFFF          <1> 	call	find_first_file
  2783 0000882B 7217                <1> 	jc	short msftdf_return
  2784                              <1> 
  2785                              <1> msftdf_sf_ambgfn_check:
  2786 0000882D 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  2787 00008830 7407                <1> 	jz	short msftdf_sf_found
  2788                              <1> 
  2789                              <1> msftdf_ambiguous_file_name_error:
  2790 00008832 B802000000          <1> 	mov	eax, 2 ; File not found error
  2791 00008837 F9                  <1> 	stc
  2792 00008838 C3                  <1> 	retn
  2793                              <1> 
  2794                              <1> msftdf_sf_found:
  2795 00008839 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  2796 0000883C 7416                <1> 	jz	short msftdf_save_sf_structure
  2797                              <1> 
  2798                              <1> msftdf_permission_denied_retn:
  2799 0000883E B805000000          <1> 	mov	eax, 05h ; Access (Permission) denied !
  2800 00008843 F9                  <1> 	stc
  2801                              <1> msftdf_rest_cdir_err_retn:
  2802                              <1> msftdf_return:
  2803 00008844 C3                  <1> 	retn
  2804                              <1> 
  2805                              <1> msftdf_phase_1_return:
  2806 00008845 31C0                <1> 	xor	eax, eax
  2807 00008847 A2[36DF0000]        <1> 	mov	[move_cmd_phase], al ; 0
  2808 0000884C FEC0                <1> 	inc	al ; mov al, 1
  2809 0000884E BB[9B880000]        <1> 	mov	ebx, msftdf_df2_check_directory
  2810                              <1> 	;mov	edx, 0FFFFFFFFh 
  2811 00008853 C3                  <1> 	retn
  2812                              <1> 
  2813                              <1> msftdf_save_sf_structure:
  2814 00008854 BE[44DD0000]        <1> 	mov	esi, FindFile_DirEntry
  2815 00008859 BF[86DE0000]        <1> 	mov	edi, SourceFile_DirEntry
  2816 0000885E B908000000          <1> 	mov	ecx, 8
  2817 00008863 F3A5                <1> 	rep	movsd
  2818                              <1> 
  2819                              <1> msftdf_df_copy_sf_parameters:
  2820 00008865 BE0B000000          <1> 	mov	esi, 11
  2821 0000886A 89F7                <1> 	mov	edi, esi
  2822 0000886C 81C6[86DE0000]      <1> 	add	esi, SourceFile_DirEntry
  2823 00008872 81C7[06DF0000]      <1> 	add	edi, DestinationFile_DirEntry
  2824                              <1> 	;mov	ecx, 21
  2825 00008878 B115                <1> 	mov	cl, 21
  2826 0000887A F3A4                <1> 	rep	movsb
  2827                              <1> 
  2828                              <1> msftdf_restore_current_dir_2:
  2829 0000887C 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2830 00008883 760D                <1> 	jna	short msftdf_df2_check_move_cmd_phase
  2831 00008885 8B35[38DF0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2832 0000888B E8DBC0FFFF          <1> 	call	restore_current_directory
  2833 00008890 72B2                <1> 	jc	short msftdf_rest_cdir_err_retn
  2834                              <1> 
  2835                              <1> msftdf_df2_check_move_cmd_phase:
  2836 00008892 803D[36DF0000]01    <1> 	cmp	byte [move_cmd_phase], 1
  2837 00008899 74AA                <1> 	je	short msftdf_phase_1_return
  2838                              <1> 
  2839                              <1> msftdf_df2_check_directory:
  2840 0000889B BE[B5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  2841 000088A0 803E20              <1> 	cmp	byte [esi], 20h
  2842 000088A3 760F                <1> 	jna	short msftdf_make_dfde_locate_ffe_on_directory
  2843                              <1> msftdf_df2_change_directory:
  2844 000088A5 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2845 000088AB 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2846 000088AD E899EFFFFF          <1> 	call	change_current_directory
  2847 000088B2 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 000088B4 31C0                <1> 	xor	eax, eax
  2859 000088B6 89C1                <1> 	mov	ecx, eax
  2860 000088B8 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 000088BA E8E0F1FFFF          <1> 	call	locate_current_dir_file
  2865 000088BF 733F                <1> 	jnc	msftdf_make_dfde_set_ff_dir_entry
  2866                              <1> 	
  2867                              <1> 	;cmp	eax, 2
  2868 000088C1 3C02                <1>         cmp	al, 2
  2869 000088C3 7537                <1> 	jne	short msftdf_error_retn
  2870                              <1> 
  2871                              <1> msftdf_add_new_dir_entry_check_fs:
  2872 000088C5 8B35[38DF0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2873 000088CB A1[7DDB0000]        <1> 	mov 	eax, [DirBuff_Cluster]
  2874 000088D0 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2875 000088D4 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 000088D6 30ED                <1> 	xor	ch, ch ; cx = 0 --> add a new subdir section
  2881 000088D8 E8750C0000          <1> 	call	add_new_fs_section
  2882 000088DD 721E                <1>         jc	short msftdf_dsfde_error_retn
  2883                              <1> 	;mov	[createfile_LastDirCluster], eax
  2884                              <1> 
  2885 000088DF E8950E0000          <1> 	call	load_FS_sub_directory 
  2886                              <1> 	;mov	ebx, Directory_Buffer 
  2887 000088E4 7318                <1> 	jnc	short msftdf_add_new_fs_subdir_section_ok
  2888 000088E6 C3                  <1> 	retn	 
  2889                              <1> 
  2890                              <1> msftdf_add_new_subdir_cluster:
  2891 000088E7 E863150000          <1> 	call	add_new_cluster
  2892 000088EC 720F                <1> 	jc	short msftdf_dsfde_error_retn
  2893                              <1> 	
  2894                              <1> 	;mov	[createfile_LastDirCluster], eax
  2895                              <1> 
  2896 000088EE E8490E0000          <1> 	call	load_FAT_sub_directory
  2897 000088F3 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 000088F5 50                  <1> 	push	eax
  2903 000088F6 E863FAFFFF          <1> 	call	update_parent_dir_lmdt
  2904 000088FB 58                  <1> 	pop	eax
  2905                              <1> 
  2906                              <1> msftdf_error_retn:
  2907 000088FC F9                  <1> 	stc
  2908                              <1> msftdf_dsfde_restore_cdir_failed:
  2909                              <1> msftdf_dsfde_error_retn:
  2910 000088FD C3                  <1> 	retn
  2911                              <1> 
  2912                              <1> msftdf_add_new_fs_subdir_section_ok:
  2913                              <1> msftdf_add_new_subdir_cluster_ok:
  2914 000088FE 89DF                <1> 	mov	edi, ebx ; Directory buffer address
  2915                              <1> 
  2916                              <1> msftdf_make_dfde_set_ff_dir_entry:
  2917 00008900 8B15[48D30000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2918 00008906 8915[9CDF0000]      <1> 	mov	[createfile_FFCluster], edx
  2919                              <1> 	; EDI = Directory entry offset
  2920 0000890C BE[06DF0000]        <1> 	mov	esi, DestinationFile_DirEntry
  2921 00008911 B908000000          <1> 	mov	ecx, 8
  2922 00008916 F3A5                <1> 	rep	movsd
  2923                              <1> 
  2924 00008918 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  2925 0000891F E89FF9FFFF          <1> 	call	save_directory_buffer
  2926 00008924 72CF                <1> 	jc	short msftdf_make_dfde_err_upd_pdir_lmdt
  2927                              <1> 
  2928                              <1> msftdf_make_dfde_update_pdir_lmdt:
  2929 00008926 E833FAFFFF          <1> 	call	update_parent_dir_lmdt
  2930                              <1> 
  2931                              <1> msftdf_dsfde_restore_current_dir_1:
  2932 0000892B 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2933 00008932 760D                <1> 	jna	short msftdf_dsfde_check_directory
  2934 00008934 8B35[38DF0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2935 0000893A E82CC0FFFF          <1> 	call	restore_current_directory
  2936 0000893F 72BC                <1> 	jc	short msftdf_dsfde_restore_cdir_failed
  2937                              <1> 
  2938                              <1> msftdf_dsfde_check_directory:
  2939 00008941 BE[35DE0000]        <1> 	mov	esi, SourceFile_Directory
  2940 00008946 803E20              <1> 	cmp	byte [esi], 20h
  2941 00008949 760F                <1> 	jna	short msftdf_dsfde_find_file
  2942                              <1> 
  2943                              <1> msftdf_dsfde_change_directory:
  2944 0000894B FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  2945 00008951 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  2946 00008953 E8F3EEFFFF          <1> 	call	change_current_directory
  2947 00008958 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 0000895A BE[76DE0000]        <1> 	mov	esi, SourceFile_Name  ; Offset 66
  2954 0000895F 668B460E            <1> 	mov	ax, [esi+14] ; 80 -> SourceFile_AttributesMask
  2955 00008963 E8EDD2FFFF          <1> 	call	find_first_file
  2956 00008968 7293                <1> 	jc	short msftdf_dsfde_error_retn
  2957                              <1> 
  2958                              <1> msftdf_dsfde_delete_direntry:
  2959 0000896A 8B35[38DF0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2960                              <1> 	
  2961 00008970 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2962 00008974 770A                <1> 	ja	short msftdf_delete_FAT_direntry
  2963                              <1> 	
  2964 00008976 30DB                <1> 	xor	bl, bl
  2965                              <1> 	; BL = 0 -> File
  2966                              <1> 	; EDI -> Directory buffer entry offset/address 
  2967 00008978 E8D60B0000          <1> 	call	delete_fs_directory_entry
  2968 0000897D 7315                <1> 	jnc	short msftdf_dsfde_restore_current_dir_2
  2969 0000897F C3                  <1> 	retn
  2970                              <1> 
  2971                              <1> msftdf_delete_FAT_direntry:	
  2972 00008980 8A1D[41DD0000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  2973 00008986 668B0D[6CDD0000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  2974                              <1> 	; ESI = Logical DOS drive description table address
  2975                              <1> 	; EDI = Directory buffer entry offset/address 
  2976 0000898D E8ABFCFFFF          <1> 	call	delete_directory_entry
  2977 00008992 721C                <1> 	jc	short msftdf_retn
  2978                              <1> 
  2979                              <1> msftdf_dsfde_restore_current_dir_2:
  2980 00008994 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2981 0000899B 7607                <1> 	jna	short msftdf_new_dir_fcluster_retn
  2982                              <1> 	;mov	esi, [msftdf_drv_offset]
  2983 0000899D E8C9BFFFFF          <1> 	call	restore_current_directory
  2984 000089A2 720C                <1> 	jc	short msftdf_retn
  2985                              <1> 
  2986                              <1> msftdf_new_dir_fcluster_retn:
  2987 000089A4 31C9                <1> 	xor	ecx, ecx 
  2988 000089A6 A1[9CDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  2989 000089AB BB[B4DE0000]        <1> 	mov	ebx, DestinationFile_Drv
  2990                              <1> 
  2991                              <1> msftdf_retn:
  2992 000089B0 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 000089B1 3C02                <1> 	cmp	al, 2
  3053 000089B3 0F844C020000        <1> 	je	csftdf2_check_cdrv
  3054                              <1> 
  3055                              <1> ; Phase 1
  3056                              <1> 
  3057 000089B9 A2[5CDF0000]        <1> 	mov	byte [copy_cmd_phase], al
  3058                              <1> 
  3059 000089BE 57                  <1> 	push	edi ; *
  3060                              <1> 
  3061                              <1> csftdf_parse_sf_path:
  3062 000089BF BF[34DE0000]        <1> 	mov	edi, SourceFile_Drv
  3063 000089C4 E896F4FFFF          <1> 	call	parse_path_name
  3064 000089C9 721C                <1> 	jc	short csftdf_parse_sf_path_failed
  3065                              <1> 
  3066                              <1> csftdf_parse_df_path:	
  3067 000089CB 5E                  <1> 	pop	esi ; * (pushed edi) 
  3068                              <1> 
  3069                              <1> csftdf_sf_check_filename_exists:
  3070 000089CC 803D[76DE0000]21    <1> 	cmp	byte [SourceFile_Name], 21h
  3071 000089D3 7215                <1> 	jb	short csftdf_sf_file_not_found_error
  3072                              <1> 
  3073 000089D5 BF[B4DE0000]        <1> 	mov	edi, DestinationFile_Drv
  3074 000089DA E880F4FFFF          <1> 	call	parse_path_name
  3075 000089DF 7310                <1> 	jnc	short csftdf_check_sf_cdrv
  3076                              <1> 	
  3077 000089E1 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  3078 000089E3 760C                <1> 	jna	short csftdf_check_sf_cdrv
  3079                              <1> 
  3080                              <1> csftdf_parse_df_path_failed:
  3081 000089E5 F9                  <1> 	stc 
  3082                              <1> csftdf_sf_error_retn: 
  3083 000089E6 C3                  <1> 	retn
  3084                              <1> 
  3085                              <1> csftdf_parse_sf_path_failed:	
  3086 000089E7 5F                  <1> 	pop	edi ; *
  3087 000089E8 EBFC                <1> 	jmp	short csftdf_sf_error_retn
  3088                              <1> 
  3089                              <1> csftdf_sf_file_not_found_error:
  3090 000089EA B802000000          <1> 	mov	eax, 2 ; File not found 
  3091 000089EF EBF5                <1> 	jmp	short csftdf_sf_error_retn
  3092                              <1> 
  3093                              <1> csftdf_check_sf_cdrv:
  3094 000089F1 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  3095                              <1> 
  3096 000089F7 883D[5FDF0000]      <1> 	mov	[csftdf_cdrv], bh ; 23/03/2016
  3097                              <1> 
  3098 000089FD 8A15[34DE0000]      <1> 	mov	dl, [SourceFile_Drv]
  3099 00008A03 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  3100 00008A05 7407                <1> 	je	short csftdf_sf_check_directory
  3101                              <1> 
  3102 00008A07 E8ADBEFFFF          <1> 	call	change_current_drive
  3103 00008A0C 72D8                <1> 	jc	short csftdf_sf_error_retn
  3104                              <1> 
  3105                              <1> csftdf_sf_check_directory:
  3106 00008A0E BE[35DE0000]        <1> 	mov	esi, SourceFile_Directory
  3107 00008A13 803E20              <1> 	cmp	byte [esi], 20h
  3108 00008A16 760F                <1> 	jna	short csftdf_find_sf
  3109                              <1> 
  3110                              <1> csftdf_sf_change_directory:
  3111 00008A18 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3112 00008A1E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3113 00008A20 E826EEFFFF          <1> 	call	change_current_directory
  3114 00008A25 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 00008A27 BE[76DE0000]        <1> 	mov	esi, SourceFile_Name
  3121 00008A2C 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3122 00008A30 E820D2FFFF          <1> 	call	find_first_file
  3123 00008A35 72AF                <1> 	jc	short csftdf_sf_error_retn
  3124                              <1> 
  3125                              <1> csftdf_sf_ambgfn_check:
  3126 00008A37 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3127 00008A3A 7407                <1> 	jz	short csftdf_sf_found
  3128                              <1> 
  3129                              <1> csftdf_ambiguous_file_name_error:
  3130 00008A3C B802000000          <1> 	mov	eax, 2 ; File not found error
  3131 00008A41 F9                  <1> 	stc
  3132 00008A42 C3                  <1> 	retn
  3133                              <1> 
  3134                              <1> csftdf_sf_found:
  3135 00008A43 A3[60DF0000]        <1> 	mov	[csftdf_filesize], eax
  3136                              <1> 
  3137 00008A48 09C0                <1> 	or	eax, eax
  3138 00008A4A 7507                <1> 	jnz	short csftdf_set_source_file_direnry
  3139                              <1> 
  3140                              <1> csftdf_sf_file_size_zero:
  3141 00008A4C B80E000000          <1> 	mov	eax, 0Eh ; TRDOS zero length error
  3142 00008A51 F9                  <1> 	stc
  3143 00008A52 C3                  <1> 	retn
  3144                              <1> 
  3145                              <1> csftdf_set_source_file_direnry:
  3146 00008A53 BE[44DD0000]        <1> 	mov	esi, FindFile_DirEntry
  3147 00008A58 BF[86DE0000]        <1> 	mov	edi, SourceFile_DirEntry
  3148 00008A5D B908000000          <1> 	mov	ecx, 8
  3149 00008A62 F3A5                <1> 	rep	movsd
  3150                              <1> 
  3151                              <1> csftdf_sf_restore_cdrv:
  3152                              <1> 	; 22/03/2016
  3153 00008A64 8A15[5FDF0000]      <1> 	mov	dl, [csftdf_cdrv]
  3154 00008A6A 3A15[4ED30000]      <1> 	cmp	dl, [Current_Drv]
  3155 00008A70 7407                <1> 	je	short csftdf_sf_restore_cdir
  3156 00008A72 E842BEFFFF          <1> 	call	change_current_drive 
  3157 00008A77 724F                <1> 	jc	short csftdf_df_error_retn ; 30/03/2016
  3158                              <1> 
  3159                              <1> csftdf_sf_restore_cdir:
  3160 00008A79 803D[E3C10000]00    <1> 	cmp	byte [Restore_CDIR], 0
  3161 00008A80 7612                <1> 	jna	short csftdf_df_check_filename_exists
  3162 00008A82 29C0                <1> 	sub	eax, eax
  3163 00008A84 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3164 00008A89 88D4                <1> 	mov	ah, dl ; byte [csftdf_cdrv]
  3165 00008A8B 01C6                <1> 	add	esi, eax
  3166 00008A8D E8D9BEFFFF          <1> 	call	restore_current_directory
  3167 00008A92 7234                <1> 	jc	short csftdf_df_error_retn
  3168                              <1>   
  3169                              <1> csftdf_df_check_filename_exists:
  3170 00008A94 803D[F6DE0000]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  3171 00008A9B 7716                <1> 	ja	short csftdf_check_df_cdrv
  3172                              <1> 
  3173                              <1> csftdf_copy_sf_name:
  3174 00008A9D BF[F6DE0000]        <1> 	mov	edi, DestinationFile_Name
  3175 00008AA2 BE[76DE0000]        <1> 	mov	esi, SourceFile_Name
  3176 00008AA7 B10C                <1> 	mov	cl, 12
  3177                              <1> 
  3178                              <1> csftdf_df_copy_sf_name_loop:
  3179 00008AA9 AC                  <1> 	lodsb
  3180 00008AAA AA                  <1> 	stosb
  3181 00008AAB 08C0                <1> 	or	al, al
  3182 00008AAD 7404                <1> 	jz	short csftdf_check_df_cdrv             
  3183 00008AAF FEC9                <1> 	dec	cl
  3184 00008AB1 75F6                <1> 	jnz	csftdf_df_copy_sf_name_loop
  3185                              <1> 
  3186                              <1> csftdf_check_df_cdrv:
  3187 00008AB3 8A15[B4DE0000]      <1> 	mov	dl, [DestinationFile_Drv]
  3188 00008AB9 3A15[4ED30000]      <1> 	cmp	dl, [Current_Drv]
  3189 00008ABF 7408                <1> 	je	short csftdf_df_check_directory
  3190                              <1> 
  3191 00008AC1 E8F3BDFFFF          <1> 	call	change_current_drive
  3192 00008AC6 7301                <1> 	jnc	short csftdf_df_check_directory
  3193                              <1> 
  3194                              <1> csftdf_df_error_retn:
  3195 00008AC8 C3                  <1> 	retn
  3196                              <1> 
  3197                              <1> csftdf_df_check_directory:
  3198 00008AC9 BE[B5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  3199 00008ACE 803E20              <1>         cmp     byte [esi], 20h
  3200 00008AD1 760F                <1> 	jna	short csftdf_find_df
  3201                              <1> 
  3202                              <1> csftdf_df_change_directory:
  3203 00008AD3 FE05[E3C10000]      <1> 	inc	byte [Restore_CDIR]
  3204 00008AD9 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  3205 00008ADB E86BEDFFFF          <1> 	call	change_current_directory
  3206 00008AE0 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 00008AE2 29DB                <1> 	sub	ebx, ebx
  3214 00008AE4 8A3D[B4DE0000]      <1> 	mov	bh,  [DestinationFile_Drv]
  3215 00008AEA 81C300010900        <1> 	add	ebx, Logical_DOSDisks
  3216 00008AF0 891D[8CDF0000]      <1> 	mov	[csftdf_df_drv_dt], ebx
  3217                              <1> 
  3218 00008AF6 BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  3219 00008AFB 6631C0              <1> 	xor	ax, ax 
  3220                              <1> 		; DestinationFile_AttributesMask -> any/zero
  3221 00008AFE E852D1FFFF          <1> 	call	find_first_file
  3222 00008B03 7218                <1> 	jc	short csftdf_df_check_error_code
  3223                              <1> 
  3224                              <1> csftdf_df_ambgfn_check:
  3225 00008B05 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3226 00008B08 7511                <1> 	jnz	short csftdf_df_error_stc_retn
  3227                              <1> 	
  3228                              <1> csftdf_df_found:
  3229 00008B0A C605[5EDF0000]01    <1> 	mov	byte [DestinationFileFound], 1
  3230 00008B11 80E11F              <1> 	and	cl, 1Fh ; Attributes, D-V-S-H-R
  3231 00008B14 7451                <1> 	jz	short csftdf_df_save_first_cluster
  3232                              <1> 
  3233                              <1> csftdf_df_permission_denied_retn:	 
  3234 00008B16 B805000000          <1> 	mov	eax, 05h ; Access/Permisson denied.
  3235                              <1> csftdf_df_error_stc_retn:
  3236 00008B1B F9                  <1> 	stc
  3237 00008B1C C3                  <1> 	retn
  3238                              <1> 
  3239                              <1> csftdf_df_check_error_code:
  3240                              <1> 	;cmp	eax, 2
  3241 00008B1D 3C02                <1> 	cmp	al, 2
  3242 00008B1F 75FA                <1> 	jne	short csftdf_df_error_stc_retn
  3243                              <1> 
  3244                              <1> 	; 21/03/2016
  3245                              <1> 	; (Capitalized file name)
  3246 00008B21 BE[34DD0000]        <1> 	mov	esi, FindFile_Name
  3247 00008B26 BF[F6DE0000]        <1> 	mov	edi, DestinationFile_Name
  3248 00008B2B A5                  <1> 	movsd
  3249 00008B2C A5                  <1> 	movsd	
  3250 00008B2D A5                  <1> 	movsd
  3251                              <1> 	;movsb
  3252                              <1> 
  3253 00008B2E C605[5EDF0000]00    <1> 	mov	byte [DestinationFileFound], 0
  3254                              <1> 
  3255                              <1> csftdf_check_disk_free_size_0:
  3256 00008B35 A1[A2DE0000]        <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 00008B3A 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3265                              <1> 
  3266 00008B40 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3267 00008B44 01C8                <1> 	add	eax, ecx
  3268 00008B46 48                  <1> 	dec	eax  ; file size (additional bytes) + 511 (round up)
  3269                              <1> csftdf_check_disk_free_size_3: ; 16/03/2016
  3270 00008B47 29D2                <1> 	sub	edx, edx
  3271 00008B49 F7F1                <1> 	div	ecx ; bytes per sector
  3272                              <1> 
  3273                              <1> csftdf_check_disk_free_size:
  3274 00008B4B 3B4674              <1> 	cmp	eax, [esi+LD_FreeSectors]
  3275 00008B4E 0F8294000000        <1>         jb      csftdf_check_disk_free_size_ok
  3276 00008B54 770A                <1> 	ja	short csftdf_df_insufficient_disk_space
  3277                              <1> 
  3278 00008B56 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0 ; FS needs FDT sector also.
  3279 00008B5A 0F8788000000        <1>         ja      csftdf_check_disk_free_size_ok 
  3280                              <1> 
  3281                              <1> csftdf_df_insufficient_disk_space:
  3282 00008B60 B827000000          <1> 	mov	eax, 27h ; insufficient disk space
  3283 00008B65 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 00008B67 81EF00000800        <1> 	sub	edi, Directory_Buffer  ; (<65536)
  3291 00008B6D 66C1EF05            <1> 	shr	di, 5 ; Convert entry offset to entry index/number
  3292 00008B71 66893D[2EDF0000]    <1> 	mov	[DestinationFile_DirEntryNumber], di ; (<2048)
  3293                              <1> 
  3294                              <1> csftdf_df_check_sf_df_fcluster:
  3295 00008B78 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  3296 00008B7C C1E210              <1> 	shl	edx, 16
  3297 00008B7F 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  3298 00008B83 8915[70DF0000]      <1> 	mov	[csftdf_df_cluster], edx
  3299                              <1> csftdf_df_check_sf_df_fcluster_1:
  3300 00008B89 668B15[9ADE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3301 00008B90 C1E210              <1> 	shl	edx, 16
  3302 00008B93 668B15[A0DE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3303 00008B9A 3B15[70DF0000]      <1> 	cmp	edx, [csftdf_df_cluster]
  3304 00008BA0 7512                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3305                              <1> csftdf_df_check_sf_df_drv:
  3306 00008BA2 8A15[34DE0000]      <1> 	mov	dl, [SourceFile_Drv]
  3307 00008BA8 3A15[B4DE0000]      <1> 	cmp	dl, [DestinationFile_Drv]
  3308 00008BAE 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 00008BB0 31C0                <1> 	xor	eax, eax ; mov eax, 0 -> Bad command or file name !
  3314 00008BB2 F9                  <1> 	stc
  3315 00008BB3 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 00008BB4 BF[06DF0000]        <1> 	mov	edi, DestinationFile_DirEntry
  3321 00008BB9 B908000000          <1> 	mov	ecx, 8
  3322 00008BBE F3A5                <1> 	rep	movsd
  3323                              <1> 	
  3324                              <1> csftdf_check_disk_free_size_2:
  3325 00008BC0 89C2                <1> 	mov	edx, eax ; Old destination file size
  3326                              <1> 
  3327                              <1> 	;mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3328 00008BC2 A1[60DF0000]        <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 00008BC7 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3338                              <1> 
  3339 00008BCD 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3340 00008BD1 01CA                <1> 	add	edx, ecx ; + 512
  3341 00008BD3 01C8                <1> 	add	eax, ecx ; + 512
  3342 00008BD5 4A                  <1> 	dec	edx ; old file size + 511 (round up)
  3343 00008BD6 48                  <1> 	dec	eax ; new file size + 511 (round up)
  3344 00008BD7 F7D9                <1> 	neg	ecx ; -512 ; 0FFFFFE00h
  3345 00008BD9 21CA                <1> 	and	edx, ecx ; = old sector count * 512 
  3346 00008BDB 21C8                <1> 	and	eax, ecx ; = new sector count * 512 
  3347                              <1> 
  3348 00008BDD 29D0                <1> 	sub	eax, edx ; new file size - old file size (on disk)
  3349 00008BDF 7607                <1> 	jna	short csftdf_check_disk_free_size_ok
  3350                              <1> 
  3351 00008BE1 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 00008BE3 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 00008BE8 A0[5CDF0000]        <1> 	mov	al, [copy_cmd_phase]
  3361 00008BED 3C01                <1> 	cmp	al, 1
  3362 00008BEF 7514                <1> 	jne	short csftdf2_check_cdrv
  3363                              <1> 	
  3364 00008BF1 31C0                <1> 	xor	eax, eax
  3365 00008BF3 A2[5CDF0000]        <1> 	mov	[copy_cmd_phase], al ; 0
  3366                              <1> 
  3367 00008BF8 8A15[5EDF0000]      <1> 	mov	dl, [DestinationFileFound]            
  3368 00008BFE 8A35[91DE0000]      <1> 	mov	dh, [SourceFile_DirEntry+11] ; Attributes
  3369                              <1>  
  3370                              <1> csftdf_return:	
  3371 00008C04 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 00008C05 803D[5EDF0000]00    <1> 	cmp	byte [DestinationFileFound], 0 
  3405 00008C0C 7739                <1> 	ja	short csftdf2_set_sf_percentage
  3406                              <1> 
  3407                              <1> csftdf2_create_file:
  3408 00008C0E BE[F6DE0000]        <1> 	mov	esi, DestinationFile_Name
  3409 00008C13 A1[60DF0000]        <1> 	mov	eax, [csftdf_filesize]
  3410 00008C18 30C9                <1> 	xor	cl, cl ; 0
  3411                              <1> 
  3412 00008C1A 31DB                <1> 	xor	ebx, ebx ; 0
  3413 00008C1C 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 00008C1D E8EC050000          <1> 	call	create_file
  3432                              <1> 	;pop	esi
  3433 00008C22 0F82A3050000        <1>         jc      csftdf2_rw_error
  3434                              <1> 
  3435                              <1> csftdf2_create_file_OK:
  3436 00008C28 A3[70DF0000]        <1> 	mov	[csftdf_df_cluster], eax
  3437                              <1> 	
  3438                              <1> 	; 24/03/2016
  3439 00008C2D 668915[2EDF0000]    <1> 	mov	[DestinationFile_DirEntryNumber], dx 
  3440                              <1> 
  3441                              <1> 	; 21/03/2016
  3442 00008C34 BE00000800          <1> 	mov	esi, Directory_Buffer
  3443 00008C39 C1E205              <1> 	shl	edx, 5 ; 32 * index number
  3444 00008C3C 01D6                <1> 	add	esi, edx
  3445 00008C3E BF[06DF0000]        <1> 	mov	edi, DestinationFile_DirEntry	
  3446 00008C43 B108                <1> 	mov	cl, 8 ; 32 bytes
  3447 00008C45 F3A5                <1> 	rep	movsd
  3448                              <1> 
  3449                              <1> csftdf2_set_sf_percentage:
  3450                              <1> 	; 17/03/2016
  3451 00008C47 31C0                <1> 	xor	eax, eax	
  3452 00008C49 A2[84DF0000]        <1> 	mov 	[csftdf_percentage], al ; 0, reset
  3453                              <1> 
  3454 00008C4E A3[7CDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax ; 0, reset
  3455 00008C53 A3[80DF0000]        <1> 	mov	[csftdf_df_wbytes], eax ; 0, reset
  3456                              <1> 
  3457 00008C58 8A25[34DE0000]      <1> 	mov	ah, [SourceFile_Drv]	
  3458 00008C5E BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3459 00008C63 01C6                <1> 	add	esi, eax
  3460                              <1> 	
  3461 00008C65 8935[88DF0000]      <1> 	mov	[csftdf_sf_drv_dt], esi ; 23/03/2016
  3462                              <1> 
  3463 00008C6B 668B15[9ADE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3464 00008C72 C1E210              <1> 	shl	edx, 16
  3465 00008C75 668B15[A0DE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3466 00008C7C 8915[6CDF0000]      <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 00008C82 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  3475 00008C86 880D[B2DE0000]      <1> 	mov	[SourceFile_SecPerClust], cl
  3476                              <1> 
  3477                              <1> 	; 17/03/2016
  3478 00008C8C 386E03              <1> 	cmp	[esi+LD_FATType], ch ; 0
  3479 00008C8F 7707                <1> 	ja	short csftdf2_set_sf_percent_rsize1
  3480                              <1> 
  3481 00008C91 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3482 00008C96 EB06                <1> 	jmp	short csftdf2_set_sf_percent_rsize2	
  3483                              <1>  
  3484                              <1> csftdf2_set_sf_percent_rsize1:
  3485 00008C98 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  3486 00008C9C F7E1                <1> 	mul	ecx
  3487                              <1> 	;sub	edx, edx
  3488                              <1> csftdf2_set_sf_percent_rsize2:
  3489 00008C9E A3[74DF0000]        <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 00008CA3 8B3D[8CDF0000]      <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 00008CA9 8A4F13              <1> 	mov	cl, [edi+LD_BPB+SecPerClust]
  3508 00008CAC 880D[32DF0000]      <1> 	mov	[DestinationFile_SecPerClust], cl
  3509                              <1> 
  3510                              <1> 	; 17/03/2016
  3511 00008CB2 386F03              <1> 	cmp	[edi+LD_FATType], ch ; 0
  3512 00008CB5 7707                <1> 	ja	short csftdf2_set_df_percent_wsize1
  3513                              <1> 	
  3514 00008CB7 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3515 00008CBC EB06                <1> 	jmp	short csftdf2_set_df_percent_wsize2	
  3516                              <1> 
  3517                              <1> csftdf2_set_df_percent_wsize1:
  3518 00008CBE 0FB74711            <1> 	movzx	eax, word [edi+LD_BPB+BytesPerSec]
  3519 00008CC2 F7E1                <1> 	mul	ecx
  3520                              <1> 	;sub	edx, edx
  3521                              <1> csftdf2_set_df_percent_wsize2:
  3522 00008CC4 A3[78DF0000]        <1> 	mov	[csftdf_w_size], eax
  3523                              <1> 
  3524 00008CC9 A1[60DF0000]        <1> 	mov	eax, [csftdf_filesize]
  3525                              <1> 
  3526 00008CCE 3D00000100          <1> 	cmp	eax, 65536 ; 64KB	; small file
  3527 00008CD3 721F                <1> 	jb	short csftdf2_load_file ; do not display percentage
  3528                              <1> 	
  3529                              <1> csftdf2_reset_wf_percent_ptr_chk_64k:
  3530 00008CD5 B201                <1> 	mov	dl, 1 ; 25/03/2016
  3531                              <1> 
  3532 00008CD7 3D00000400          <1> 	cmp	eax, 65536*4 ; 256KB
  3533 00008CDC 7310                <1> 	jnb	short csftdf2_enable_percentage_display ; big file
  3534                              <1> 
  3535                              <1> 	; 64-128KB file size for floppy disks
  3536 00008CDE 3815[34DE0000]      <1> 	cmp	byte [SourceFile_Drv], dl ; 1 ; read from floppy disk ?
  3537 00008CE4 7608                <1> 	jna	short csftdf2_enable_percentage_display
  3538                              <1> 
  3539 00008CE6 3815[B4DE0000]      <1> 	cmp	byte [DestinationFile_Drv], dl ; 1 ; write to floppy disk ?
  3540 00008CEC 7706                <1> 	ja	short csftdf2_load_file
  3541                              <1> 
  3542                              <1> csftdf2_enable_percentage_display:	
  3543 00008CEE 8815[84DF0000]      <1> 	mov	[csftdf_percentage], dl ; 1	
  3544                              <1> 	
  3545                              <1> csftdf2_load_file:
  3546                              <1> 	; 13/05/2016
  3547                              <1> 	; 19/03/2016
  3548                              <1> 	; 18/03/2016
  3549                              <1> 	; 17/03/2016
  3550 00008CF4 B40F                <1> 	mov	ah, 0Fh
  3551 00008CF6 E81C86FFFF          <1> 	call	_int10h
  3552                              <1> 	; 13/05/2016
  3553 00008CFB 883D[85DF0000]      <1> 	mov	[csftdf_videopage], bh ; active video page
  3554 00008D01 B403                <1> 	mov	ah, 03h
  3555 00008D03 E80F86FFFF          <1> 	call	_int10h
  3556 00008D08 668915[86DF0000]    <1> 	mov	[csftdf_cursorpos], dx
  3557                              <1> 
  3558 00008D0F 29C0                <1> 	sub	eax, eax
  3559 00008D11 A2[5DDF0000]        <1> 	mov	[csftdf_rw_err], al ; 0 
  3560                              <1> 
  3561                              <1> ; ///
  3562                              <1> csftdf_sf_amb: ; 15/03/2016
  3563 00008D16 8B0D[60DF0000]      <1> 	mov	ecx, [csftdf_filesize]	; 23/03/2016
  3564                              <1> 
  3565                              <1> 	; TRDOS 386 (TRDOS v2.0)
  3566                              <1> 	; Allocate contiguous memory block for loading the file
  3567                              <1> 	
  3568                              <1> 	;mov	ecx, [SourceFile_DirEntry+DirEntry_FileSize]
  3569                              <1> 	
  3570                              <1> 	;sub	eax, eax ; First free memory aperture
  3571                              <1> 	
  3572                              <1> 	; eax = 0 (Allocate memory from the beginning)
  3573                              <1> 	; ecx = File (Allocation) size in bytes
  3574                              <1> 	
  3575 00008D1C E864ACFFFF          <1> 	call	allocate_memory_block
  3576 00008D21 7304                <1> 	jnc	short loc_check_sf_save_loading_parms
  3577                              <1> 
  3578 00008D23 29C0                <1> 	sub	eax, eax
  3579 00008D25 29C9                <1> 	sub	ecx, ecx
  3580                              <1> 	
  3581                              <1> loc_check_sf_save_loading_parms:
  3582 00008D27 A3[64DF0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  3583 00008D2C 890D[68DF0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  3584                              <1> ; ///   
  3585                              <1> 	; 19/03/2016
  3586 00008D32 8B35[88DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt] ; logical dos drv desc. tbl.
  3587                              <1> 
  3588                              <1> 	; 17/03/2016
  3589 00008D38 09C0                <1> 	or	eax, eax ; contiguous free memory block address 
  3590 00008D3A 0F845B010000        <1>         jz      csftdf2_read_sf_cluster
  3591                              <1> 
  3592                              <1> 	; 18/03/2016
  3593 00008D40 8B1D[64DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3594                              <1> 
  3595 00008D46 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3596 00008D4A 0F8605020000        <1>         jna     csftdf2_load_fs_file
  3597                              <1> 
  3598                              <1> csftdf2_load_fat_file:
  3599 00008D50 53                  <1> 	push	ebx ; *
  3600                              <1> 
  3601                              <1> csftdf2_load_fat_file_next:
  3602 00008D51 BE[39C80000]        <1> 	mov	esi, msg_reading
  3603 00008D56 E859B2FFFF          <1> 	call	print_msg
  3604                              <1> 
  3605 00008D5B 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3606 00008D62 7605                <1> 	jna	short csftdf2_load_fat_file_1
  3607                              <1> 	
  3608 00008D64 E87C000000          <1> 	call	csftdf2_print_percentage ; 19/03/2016
  3609                              <1> 
  3610                              <1> csftdf2_load_fat_file_1:
  3611 00008D69 8B35[88DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3612 00008D6F 5B                  <1> 	pop	ebx ; *
  3613                              <1> 
  3614                              <1> csftdf2_load_fat_file_2:
  3615 00008D70 E8B8000000          <1> 	call	csftdf2_read_fat_file_sectors ; 19/03/2016
  3616 00008D75 0F8250040000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3617                              <1> 
  3618 00008D7B 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3619 00008D7D 7520                <1> 	jnz	short csftdf2_load_fat_file_ok
  3620                              <1> 
  3621 00008D7F 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3622 00008D86 76E8                <1> 	jna	short csftdf2_load_fat_file_2
  3623                              <1> 
  3624 00008D88 53                  <1> 	push	ebx ; *	
  3625                              <1> 
  3626                              <1> 	; Set cursor position
  3627                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3628 00008D89 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3629 00008D8F 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3630 00008D96 B402                <1> 	mov	ah, 2
  3631 00008D98 E87A85FFFF          <1> 	call	_int10h
  3632 00008D9D EBB2                <1> 	jmp	short csftdf2_load_fat_file_next
  3633                              <1> 	
  3634                              <1> csftdf2_load_fat_file_ok:
  3635 00008D9F 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3636 00008DA6 0F8651020000        <1>         jna     csftdf2_save_file ; 25/03/2016
  3637                              <1> 	
  3638                              <1> 	; "Reading... 100%"
  3639 00008DAC BF[51C80000]        <1> 	mov	edi, percentagestr
  3640 00008DB1 B031                <1> 	mov	al, '1'
  3641 00008DB3 AA                  <1> 	stosb
  3642 00008DB4 B030                <1> 	mov	al, '0'
  3643 00008DB6 AA                  <1> 	stosb
  3644 00008DB7 AA                  <1> 	stosb
  3645                              <1> 
  3646 00008DB8 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3647 00008DBE 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3648 00008DC5 B402                <1> 	mov	ah, 2
  3649 00008DC7 E84B85FFFF          <1> 	call	_int10h
  3650                              <1> 
  3651 00008DCC BE[39C80000]        <1> 	mov	esi, msg_reading
  3652 00008DD1 E8DEB1FFFF          <1> 	call	print_msg
  3653                              <1> 	
  3654 00008DD6 BE[51C80000]        <1> 	mov	esi, percentagestr
  3655 00008DDB E8D4B1FFFF          <1> 	call	print_msg
  3656                              <1> 
  3657 00008DE0 E918020000          <1>         jmp     csftdf2_save_file ; 25/03/2016
  3658                              <1> 
  3659                              <1> csftdf2_print_percentage:
  3660                              <1> 	; 19/03/2016
  3661                              <1> 	; 18/03/2016
  3662 00008DE5 B020                <1> 	mov	al, 20h
  3663 00008DE7 BF[51C80000]        <1> 	mov	edi, percentagestr
  3664 00008DEC AA                  <1> 	stosb
  3665 00008DED AA                  <1> 	stosb
  3666 00008DEE A1[7CDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3667 00008DF3 BA64000000          <1> 	mov	edx, 100
  3668 00008DF8 F7E2                <1> 	mul	edx
  3669 00008DFA 8B0D[60DF0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3670 00008E00 F7F1                <1> 	div	ecx
  3671 00008E02 B10A                <1> 	mov	cl, 10
  3672 00008E04 F6F1                <1> 	div	cl
  3673 00008E06 80C430              <1> 	add	ah, '0'
  3674 00008E09 8827                <1> 	mov	[edi], ah
  3675 00008E0B 20C0                <1> 	and	al, al
  3676 00008E0D 740A                <1> 	jz	short csftdf2_print_percent_1
  3677 00008E0F 4F                  <1> 	dec	edi
  3678 00008E10 6698                <1> 	cbw
  3679 00008E12 F6F1                <1> 	div	cl
  3680 00008E14 80C430              <1> 	add	ah, '0'
  3681 00008E17 8827                <1> 	mov	[edi], ah
  3682                              <1> 	;and	al, al
  3683                              <1> 	;jz	short csftdf2_print_percent_1
  3684                              <1> 	;dec	edi
  3685                              <1> 	;mov	[edi], '1' ; 100%		
  3686                              <1> 
  3687                              <1> csftdf2_print_percent_1:
  3688 00008E19 BE[51C80000]        <1> 	mov	esi, percentagestr
  3689                              <1> 	;call	print_msg
  3690                              <1> 	;retn
  3691 00008E1E E991B1FFFF          <1> 	jmp	print_msg
  3692                              <1> 
  3693                              <1> csftdf2_read_file_sectors:
  3694                              <1> 	; 19/03/2016
  3695 00008E23 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3696 00008E27 0F8627070000        <1>         jna     csftdf2_read_fs_file_sectors
  3697                              <1> 
  3698                              <1> csftdf2_read_fat_file_sectors:
  3699                              <1> 	; 19/03/2016
  3700                              <1> 	; 18/03/2016
  3701                              <1> 	; return:
  3702                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3703                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3704                              <1> 	;   CF = 1 -> read error (error code in AL)	
  3705                              <1> 
  3706                              <1> csftdf2_read_fat_file_secs_0:
  3707 00008E2D 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3708 00008E33 2B15[7CDF0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  3709 00008E39 3B15[74DF0000]      <1> 	cmp	edx, [csftdf_r_size]	
  3710 00008E3F 7306                <1> 	jnb	short csftdf2_read_fat_file_secs_1
  3711 00008E41 8915[74DF0000]      <1> 	mov	[csftdf_r_size], edx
  3712                              <1> 		
  3713                              <1> csftdf2_read_fat_file_secs_1:
  3714 00008E47 A1[74DF0000]        <1> 	mov	eax, [csftdf_r_size]
  3715 00008E4C 29D2                <1> 	sub	edx, edx
  3716 00008E4E 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3717 00008E52 01C8                <1> 	add	eax, ecx
  3718 00008E54 48                  <1> 	dec	eax
  3719 00008E55 F7F1                <1> 	div	ecx
  3720 00008E57 89C1                <1> 	mov	ecx, eax ; sector count
  3721 00008E59 A1[6CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3722                              <1> 
  3723                              <1> 	; EBX = memory block address (current)
  3724                              <1> 	
  3725 00008E5E E821090000          <1> 	call	read_fat_file_sectors
  3726 00008E63 7235                <1> 	jc	short csftdf2_read_fat_file_secs_3
  3727                              <1> 
  3728                              <1> 	; EBX = next memory address
  3729                              <1> 
  3730 00008E65 A1[7CDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3731 00008E6A 0305[74DF0000]      <1> 	add	eax, [csftdf_r_size]
  3732 00008E70 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3733 00008E76 39D0                <1> 	cmp	eax, edx
  3734 00008E78 7320                <1> 	jnb	short csftdf2_read_fat_file_secs_3 ; edx > 0
  3735 00008E7A A3[7CDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  3736                              <1> 
  3737 00008E7F 53                  <1> 	push	ebx ; *
  3738                              <1> 	; get next cluster (csftdf_r_size! bytes)
  3739 00008E80 A1[6CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3740 00008E85 E8CC060000          <1> 	call	get_next_cluster
  3741 00008E8A 5B                  <1> 	pop	ebx ; *
  3742 00008E8B 7306                <1> 	jnc	short csftdf2_read_fat_file_secs_2
  3743                              <1> 
  3744 00008E8D B815000000          <1> 	mov	eax, 15h ; Read error !
  3745 00008E92 C3                  <1> 	retn
  3746                              <1> 
  3747                              <1> csftdf2_read_fat_file_secs_2:
  3748 00008E93 29D2                <1> 	sub	edx, edx ; 0
  3749 00008E95 A3[6CDF0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  3750                              <1> 
  3751                              <1> csftdf2_read_fat_file_secs_3:
  3752 00008E9A C3                  <1> 	retn
  3753                              <1> 
  3754                              <1> csftdf2_read_sf_cluster:
  3755                              <1> 	; 19/03/2016
  3756 00008E9B BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3757                              <1> 
  3758 00008EA0 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3759 00008EA7 760D                <1> 	jna	short csftdf2_read_sf_clust_2
  3760                              <1> 
  3761 00008EA9 53                  <1> 	push	ebx ; *	
  3762                              <1> 
  3763                              <1> csftdf2_read_sf_clust_next:
  3764 00008EAA E836FFFFFF          <1> 	call	csftdf2_print_percentage
  3765                              <1> 
  3766                              <1> csftdf2_read_sf_clust_0:
  3767 00008EAF 8B35[88DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3768                              <1> csftdf2_read_sf_clust_1:
  3769 00008EB5 5B                  <1> 	pop	ebx ; *
  3770                              <1> 
  3771                              <1> csftdf2_read_sf_clust_2:
  3772 00008EB6 89DA                <1> 	mov	edx, ebx
  3773 00008EB8 0315[74DF0000]      <1> 	add	edx, [csftdf_r_size]
  3774 00008EBE 81FA00000800        <1> 	cmp	edx, Cluster_Buffer + 65536
  3775 00008EC4 772F                <1> 	ja	short csftdf2_write_df_cluster
  3776                              <1> 
  3777 00008EC6 E858FFFFFF          <1> 	call	csftdf2_read_file_sectors ; 19/03/2016
  3778 00008ECB 0F8280020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3779                              <1> 
  3780 00008ED1 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3781 00008ED3 7520                <1> 	jnz	short csftdf2_write_df_cluster
  3782                              <1> 
  3783 00008ED5 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3784 00008EDC 76D8                <1> 	jna	short csftdf2_read_sf_clust_2
  3785                              <1> 
  3786 00008EDE 53                  <1> 	push	ebx ; *	
  3787                              <1> 
  3788                              <1> 	; Set cursor position
  3789                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3790 00008EDF 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3791 00008EE5 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3792 00008EEC B402                <1> 	mov	ah, 2
  3793 00008EEE E82484FFFF          <1> 	call	_int10h
  3794 00008EF3 EBB5                <1> 	jmp	short csftdf2_read_sf_clust_next
  3795                              <1> 
  3796                              <1> csftdf2_write_df_cluster:
  3797                              <1> 	; 19/03/2016
  3798 00008EF5 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt]	
  3799 00008EFB BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3800                              <1> 
  3801                              <1> csftdf2_write_df_clust_next:
  3802 00008F00 E855000000          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016
  3803 00008F05 0F8246020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3804                              <1> 
  3805 00008F0B 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3806 00008F0D 750A                <1> 	jnz	short csftdf2_rw_f_clust_ok
  3807                              <1> 
  3808 00008F0F 81FB00000800        <1> 	cmp	ebx, Cluster_Buffer + 65536
  3809 00008F15 72E9                <1> 	jb	short csftdf2_write_df_clust_next
  3810                              <1> 	
  3811 00008F17 EB82                <1> 	jmp	short csftdf2_read_sf_cluster
  3812                              <1>  
  3813                              <1> csftdf2_rw_f_clust_ok:
  3814 00008F19 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3815 00008F20 0F86B2010000        <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  3816                              <1> 
  3817                              <1> 	; "100%"
  3818 00008F26 BF[51C80000]        <1> 	mov	edi, percentagestr
  3819 00008F2B B031                <1> 	mov	al, '1'
  3820 00008F2D AA                  <1> 	stosb
  3821 00008F2E B030                <1> 	mov	al, '0'
  3822 00008F30 AA                  <1> 	stosb
  3823 00008F31 AA                  <1> 	stosb
  3824                              <1> 
  3825 00008F32 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3826 00008F38 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3827 00008F3F B402                <1> 	mov	ah, 2
  3828 00008F41 E8D183FFFF          <1> 	call	_int10h
  3829                              <1> 
  3830 00008F46 BE[51C80000]        <1> 	mov	esi, percentagestr
  3831 00008F4B E864B0FFFF          <1> 	call	print_msg
  3832                              <1> 
  3833 00008F50 E983010000          <1>         jmp     csftdf2_save_fat_file_4
  3834                              <1> 
  3835                              <1> csftdf2_load_fs_file:
  3836                              <1> 	; temporary - 18/03/2016
  3837 00008F55 E96F020000          <1>         jmp     csftdf2_read_error
  3838                              <1> 
  3839                              <1> csftdf2_write_file_sectors:
  3840                              <1> 	; 19/03/2016
  3841 00008F5A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3842 00008F5E 0F86F1050000        <1>         jna     csftdf2_write_fs_file_sectors
  3843                              <1> 
  3844                              <1> csftdf2_write_fat_file_sectors:
  3845                              <1> 	; 19/03/2016
  3846                              <1> 	; 18/03/2016
  3847                              <1> 	; return:
  3848                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3849                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3850                              <1> 	;   CF = 1 -> write error (error code in AL)	
  3851                              <1> 
  3852                              <1> csftdf2_write_fat_file_secs_0:
  3853 00008F64 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3854 00008F6A 2B15[80DF0000]      <1> 	sub	edx, [csftdf_df_wbytes]
  3855 00008F70 3B15[78DF0000]      <1> 	cmp	edx, [csftdf_w_size]	
  3856 00008F76 7306                <1> 	jnb	short csftdf2_write_fat_file_secs_1
  3857 00008F78 8915[78DF0000]      <1> 	mov	[csftdf_w_size], edx		
  3858                              <1> 
  3859                              <1> csftdf2_write_fat_file_secs_1:
  3860 00008F7E A1[78DF0000]        <1> 	mov	eax, [csftdf_w_size]
  3861 00008F83 29D2                <1> 	sub	edx, edx
  3862 00008F85 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3863 00008F89 01C8                <1> 	add	eax, ecx
  3864 00008F8B 48                  <1> 	dec	eax
  3865 00008F8C F7F1                <1> 	div	ecx
  3866 00008F8E 89C1                <1> 	mov	ecx, eax ; sector count
  3867 00008F90 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3868                              <1> 
  3869                              <1> 	; EBX = memory block address (current)	
  3870                              <1> 
  3871 00008F95 E8920F0000          <1> 	call	write_fat_file_sectors
  3872 00008F9A 7259                <1> 	jc	short csftdf2_write_fat_file_secs_4
  3873                              <1> 
  3874                              <1> 	; EBX = next memory address
  3875                              <1> 
  3876 00008F9C A1[80DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3877 00008FA1 0305[78DF0000]      <1> 	add	eax, [csftdf_w_size]
  3878 00008FA7 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3879 00008FAD 39D0                <1> 	cmp	eax, edx
  3880 00008FAF 7344                <1> 	jnb	short csftdf2_write_fat_file_secs_4
  3881 00008FB1 A3[80DF0000]        <1> 	mov	[csftdf_df_wbytes], eax
  3882                              <1> 	;
  3883 00008FB6 A3[22DF0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  3884                              <1> 
  3885 00008FBB 53                  <1> 	push	ebx ; *
  3886                              <1> 
  3887 00008FBC 803D[5EDF0000]01    <1> 	cmp	byte [DestinationFileFound], 1
  3888 00008FC3 7210                <1> 	jb	short csftdf2_write_fat_file_secs_2
  3889                              <1> 
  3890                              <1> 	; get next cluster (csftdf_w_size! bytes)
  3891 00008FC5 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3892 00008FCA E887050000          <1> 	call	get_next_cluster
  3893 00008FCF 731C                <1> 	jnc	short csftdf2_write_fat_file_secs_3
  3894                              <1> 
  3895 00008FD1 21C0                <1> 	and	eax, eax ; end of cluster chain!?
  3896 00008FD3 7521                <1> 	jnz	short csftdf2_write_fat_file_secs_5 ; disk error !
  3897                              <1> 
  3898                              <1> csftdf2_write_fat_file_secs_2:
  3899 00008FD5 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  3900 00008FDA E8700E0000          <1> 	call	add_new_cluster		
  3901 00008FDF 7215                <1> 	jc	short csftdf2_write_fat_file_secs_5
  3902                              <1> 
  3903                              <1> 	; NOTE: Destination file size may be bigger than
  3904                              <1> 	; source file size when the last reading fails after here.
  3905                              <1> 	; (The last -empty- cluster of destination file must be 
  3906                              <1> 	; truncated and LMDT must be current date&time for partial
  3907                              <1> 	; copy result!) 
  3908 00008FE1 8B15[78DF0000]      <1> 	mov	edx, [csftdf_w_size] ; bytes per cluster
  3909 00008FE7 0115[22DF0000]      <1> 	add	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  3910                              <1> 
  3911                              <1> csftdf2_write_fat_file_secs_3:
  3912 00008FED 5B                  <1> 	pop	ebx ; *
  3913 00008FEE 29D2                <1> 	sub	edx, edx ; 0
  3914 00008FF0 A3[70DF0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  3915                              <1> 
  3916                              <1> csftdf2_write_fat_file_secs_4:
  3917 00008FF5 C3                  <1> 	retn
  3918                              <1> 
  3919                              <1> csftdf2_write_fat_file_secs_5:
  3920 00008FF6 5B                  <1> 	pop	ebx ; *
  3921 00008FF7 B81D000000          <1> 	mov	eax, 1Dh ; Write error !
  3922 00008FFC C3                  <1> 	retn
  3923                              <1> 
  3924                              <1> csftdf2_save_file:
  3925                              <1> 	; 25/03/2016
  3926                              <1> 	; 19/03/2016
  3927                              <1> 	; 18/03/2016
  3928 00008FFD 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; logical dos drv desc. tbl.
  3929                              <1> 
  3930 00009003 8B1D[64DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3931                              <1> 
  3932 00009009 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3933 0000900D 0F86F4010000        <1>         jna     csftdf2_save_fs_file
  3934                              <1> 
  3935                              <1> csftdf2_save_fat_file:
  3936 00009013 53                  <1> 	push	ebx; *
  3937                              <1> 
  3938 00009014 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3939 0000901B 7724                <1> 	ja	short csftdf2_save_fat_file_0
  3940                              <1> 
  3941                              <1> 	; Set cursor position
  3942                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3943 0000901D 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3944 00009023 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3945 0000902A B402                <1> 	mov	ah, 2
  3946 0000902C E8E682FFFF          <1> 	call	_int10h
  3947                              <1> 	
  3948 00009031 BE[45C80000]        <1> 	mov	esi, msg_writing
  3949 00009036 E879AFFFFF          <1> 	call	print_msg
  3950                              <1> 
  3951                              <1> csftdf2_save_fat_file_next:
  3952 0000903B 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 25/03/2016
  3953                              <1> 
  3954                              <1> csftdf2_save_fat_file_0:
  3955 00009041 5B                  <1> 	pop	ebx ; *
  3956                              <1> 
  3957                              <1> csftdf2_save_fat_file_1:
  3958 00009042 E813FFFFFF          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016	
  3959 00009047 0F827E010000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3960                              <1> 
  3961 0000904D 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3962 0000904F 756D                <1>         jnz     short csftdf2_save_fat_file_3 ; 25/03/2016
  3963                              <1> 
  3964 00009051 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3965 00009058 76E8                <1> 	jna	short csftdf2_save_fat_file_1
  3966                              <1> 
  3967 0000905A B020                <1> 	mov	al, 20h
  3968 0000905C BF[51C80000]        <1> 	mov	edi, percentagestr
  3969 00009061 AA                  <1> 	stosb
  3970 00009062 AA                  <1> 	stosb
  3971 00009063 A1[80DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3972 00009068 BA64000000          <1> 	mov	edx, 100
  3973 0000906D F7E2                <1> 	mul	edx
  3974 0000906F 8B0D[60DF0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3975 00009075 F7F1                <1> 	div	ecx
  3976 00009077 B10A                <1> 	mov	cl, 10
  3977 00009079 F6F1                <1> 	div	cl
  3978 0000907B 80C430              <1> 	add	ah, '0'
  3979 0000907E 8827                <1> 	mov	[edi], ah
  3980 00009080 20C0                <1> 	and	al, al
  3981 00009082 740A                <1> 	jz	short csftdf2_save_fat_file_2
  3982 00009084 4F                  <1> 	dec	edi
  3983 00009085 6698                <1> 	cbw
  3984 00009087 F6F1                <1> 	div	cl
  3985 00009089 80C430              <1> 	add	ah, '0'
  3986 0000908C 8827                <1> 	mov	[edi], ah
  3987                              <1> 	;and	al, al
  3988                              <1> 	;jz	short csftdf2_save_fat_file_2
  3989                              <1> 	;dec	edi
  3990                              <1> 	;mov	[edi], '1' ; 100%		
  3991                              <1> 
  3992                              <1> csftdf2_save_fat_file_2:
  3993 0000908E 53                  <1> 	push	ebx ; *
  3994                              <1> 
  3995 0000908F E802000000          <1> 	call	csftdf2_print_wr_percentage ; 25/03/2016
  3996                              <1> 
  3997 00009094 EBA5                <1>         jmp     csftdf2_save_fat_file_next
  3998                              <1> 
  3999                              <1> csftdf2_print_wr_percentage:
  4000                              <1> 	; Set cursor position
  4001                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  4002 00009096 8A3D[85DF0000]      <1> 	mov	bh, [csftdf_videopage]
  4003 0000909C 668B15[86DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  4004 000090A3 B402                <1> 	mov	ah, 2
  4005 000090A5 E86D82FFFF          <1> 	call	_int10h
  4006                              <1> 
  4007 000090AA BE[45C80000]        <1> 	mov	esi, msg_writing
  4008 000090AF E800AFFFFF          <1> 	call	print_msg
  4009                              <1> 
  4010 000090B4 BE[51C80000]        <1> 	mov	esi, percentagestr
  4011                              <1> 	;call	print_msg
  4012                              <1> 	;retn
  4013 000090B9 E9F6AEFFFF          <1> 	jmp	print_msg
  4014                              <1> 
  4015                              <1> csftdf2_save_fat_file_3:
  4016 000090BE 803D[84DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  4017 000090C5 7611                <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  4018                              <1> 
  4019                              <1> 	; "100%"
  4020 000090C7 BF[51C80000]        <1> 	mov	edi, percentagestr
  4021 000090CC B031                <1> 	mov	al, '1'
  4022 000090CE AA                  <1> 	stosb
  4023 000090CF B030                <1> 	mov	al, '0'
  4024 000090D1 AA                  <1> 	stosb
  4025 000090D2 AA                  <1> 	stosb
  4026                              <1> 
  4027 000090D3 E8BEFFFFFF          <1> 	call	csftdf2_print_wr_percentage
  4028                              <1> 
  4029                              <1> csftdf2_save_fat_file_4:
  4030 000090D8 803D[5EDF0000]00    <1> 	cmp	byte [DestinationFileFound], 0
  4031 000090DF 7647                <1> 	jna	short csftdf2_save_fat_file_6
  4032                              <1> 
  4033 000090E1 8B35[8CDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 31/03/2016	
  4034                              <1> 
  4035 000090E7 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4036 000090EC E865040000          <1> 	call	get_next_cluster
  4037 000090F1 7235                <1> 	jc	short csftdf2_save_fat_file_6 ; eocc! or disk error!
  4038                              <1> 
  4039 000090F3 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4040                              <1> 	;xor	ecx, ecx
  4041                              <1> 	;mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  4042                              <1> 	;dec	ecx ; 0FFFFFFFFh
  4043                              <1> 	;shr	ecx, 4 ; 28 bit ; 0FFFFFFFh
  4044 000090F8 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4045 000090FD E87E070000          <1> 	call	update_cluster
  4046 00009102 7224                <1> 	jc	short csftdf2_save_fat_file_6 ; really last cluster!?
  4047                              <1> 
  4048 00009104 A3[70DF0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  4049                              <1> 	
  4050                              <1> 	; byte [FAT_BuffValidData] = 2 
  4051 00009109 E82F0A0000          <1> 	call	save_fat_buffer
  4052 0000910E 730E                <1> 	jnc	short csftdf2_save_fat_file_5
  4053                              <1> 	
  4054 00009110 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  4055 00009116 8915[22DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4056 0000911C EB58                <1> 	jmp	short csftdf2_save_fat_file_err3
  4057                              <1> 
  4058                              <1> csftdf2_save_fat_file_5:
  4059 0000911E A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  4060                              <1> 
  4061                              <1> 	; EAX = First cluster to be truncated/unlinked
  4062                              <1> 	; ESI = Logical dos drive description table address
  4063 00009123 E8480C0000          <1> 	call	truncate_cluster_chain
  4064                              <1> 
  4065                              <1> csftdf2_save_fat_file_6:
  4066                              <1> 	; 28/03/2016
  4067 00009128 BE[91DE0000]        <1> 	mov	esi, SourceFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4068 0000912D BF[11DF0000]        <1> 	mov	edi, DestinationFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4069 00009132 A4                  <1> 	movsb ; +11
  4070 00009133 A5                  <1> 	movsd ; +12 .. +15
  4071 00009134 66A5                <1> 	movsw ; +16 .. +17
  4072                              <1> 		; + 18
  4073 00009136 83C604              <1> 	add	esi, 4
  4074 00009139 83C704              <1> 	add	edi, 4
  4075 0000913C A5                  <1> 	movsd	; DirEntry_WrtTime ; +22 .. +25
  4076                              <1> 
  4077 0000913D 8B15[60DF0000]      <1> 	mov	edx, [csftdf_filesize]
  4078 00009143 8915[22DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4079                              <1> 
  4080 00009149 E8D7F0FFFF          <1> 	call	convert_current_date_time
  4081                              <1> 	; DX = Date in dos dir entry format
  4082                              <1> 	; AX = Time in dos dir entry format
  4083 0000914E EB4D                <1> 	jmp	short csftdf2_save_fat_file_7
  4084                              <1> 
  4085                              <1> csftdf2_save_fat_file_err1:
  4086 00009150 5B                  <1> 	pop	ebx ; *	
  4087                              <1> csftdf2_save_fat_file_err2:
  4088 00009151 A1[80DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  4089 00009156 8B15[22DF0000]      <1> 	mov	edx, [DestinationFile_DirEntry+DirEntry_FileSize]
  4090 0000915C 39C2                <1> 	cmp	edx, eax
  4091 0000915E 7616                <1> 	jna	short csftdf2_save_fat_file_err3
  4092 00009160 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last (empty) cluster
  4093                              <1> 	; ESI = Logical dos drive description table address
  4094 00009165 E8060C0000          <1> 	call	truncate_cluster_chain
  4095 0000916A 720A                <1> 	jc	short csftdf2_save_fat_file_err3
  4096 0000916C A1[80DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]	
  4097 00009171 A3[22DF0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  4098                              <1> csftdf2_save_fat_file_err3:
  4099 00009176 E8AAF0FFFF          <1> 	call	convert_current_date_time
  4100                              <1> 	; DX = Date in dos dir entry format
  4101                              <1> 	; AX = Time in dos dir entry format
  4102 0000917B C605[13DF0000]00    <1> 	mov	byte [DestinationFile_DirEntry+DirEntry_CrtTimeTenth], 0
  4103 00009182 66A3[14DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtTime], ax
  4104 00009188 668915[16DF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtDate], dx		
  4105 0000918F 66A3[1CDF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtTime], ax
  4106 00009195 668915[1EDF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtDate], dx
  4107 0000919C F9                  <1> 	stc
  4108                              <1> csftdf2_save_fat_file_7:
  4109 0000919D 9C                  <1> 	pushf
  4110 0000919E 668915[18DF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_LastAccDate], dx
  4111 000091A5 BE[06DF0000]        <1> 	mov	esi, DestinationFile_DirEntry
  4112 000091AA BF00000800          <1> 	mov	edi, Directory_Buffer
  4113 000091AF 0FB70D[2EDF0000]    <1> 	movzx	ecx, word [DestinationFile_DirEntryNumber] ; (<2048)
  4114 000091B6 66C1E105            <1> 	shl	cx, 5 ; 32 * directory entry number
  4115 000091BA 01CF                <1> 	add	edi, ecx
  4116                              <1> 	;mov	ecx, 8
  4117 000091BC 66B90800            <1> 	mov	cx, 8
  4118 000091C0 F3A5                <1> 	rep	movsd
  4119 000091C2 9D                  <1> 	popf
  4120 000091C3 730B                <1> 	jnc	short csftdf2_write_file_OK
  4121                              <1> 	 		
  4122                              <1> csftdf2_write_error:
  4123                              <1> 	; 18/03/2016
  4124 000091C5 B01D                <1> 	mov	al, 1Dh ; write error
  4125 000091C7 EB02                <1> 	jmp	short csftdf2_rw_error
  4126                              <1> 
  4127                              <1> 	; 16/03/2016
  4128                              <1> csftdf2_read_error:
  4129 000091C9 B015                <1> 	mov	al, 15h ; ; Drive not ready or read error!
  4130                              <1> csftdf2_rw_error:
  4131 000091CB A2[5DDF0000]        <1> 	mov	[csftdf_rw_err], al 
  4132                              <1> 
  4133                              <1> csftdf2_write_file_OK:
  4134                              <1> 	; 18/03/2016
  4135 000091D0 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  4136 000091D7 E8E7F0FFFF          <1> 	call	save_directory_buffer
  4137                              <1> 
  4138                              <1>  	; Update last modification date&time of destination
  4139                              <1> 	; file's (parent) directory
  4140 000091DC E87DF1FFFF          <1> 	call	update_parent_dir_lmdt
  4141                              <1> 	;
  4142 000091E1 A1[64DF0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  4143                              <1> 
  4144 000091E6 21C0                <1> 	and	eax, eax
  4145 000091E8 750E                <1> 	jnz	short csftdf2_dealloc_mblock
  4146                              <1> 
  4147 000091EA 88C5                <1> 	mov	ch, al ; 0 (Cluster r/w, not full loading)
  4148                              <1> csftdf2_dealloc_retn:
  4149 000091EC 8A0D[5DDF0000]      <1> 	mov	cl, [csftdf_rw_err]
  4150 000091F2 A1[70DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  4151 000091F7 C3                  <1> 	retn
  4152                              <1> 
  4153                              <1> csftdf2_dealloc_mblock:
  4154 000091F8 8B0D[68DF0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  4155 000091FE E883A9FFFF          <1> 	call	deallocate_memory_block
  4156 00009203 B5FF                <1>         mov     ch, 0FFh ; (File was full loaded at memory)
  4157 00009205 EBE5                <1> 	jmp	short csftdf2_dealloc_retn
  4158                              <1> 
  4159                              <1> csftdf2_save_fs_file:
  4160                              <1> 	; temporary - (21/03/2016)
  4161 00009207 B81D000000          <1> 	mov	eax, 1Dh ; write error
  4162 0000920C F9                  <1> 	stc
  4163 0000920D C3                  <1> 	retn
  4164                              <1> 
  4165                              <1> create_file:
  4166                              <1> 	; 31/03/2016
  4167                              <1> 	; 24/03/2016
  4168                              <1> 	; 23/03/2016
  4169                              <1> 	; 21/03/2016
  4170                              <1> 	; 20/03/2016
  4171                              <1> 	; 19/03/2016 (TRDOS 396 = TRDOS v2.0)
  4172                              <1> 	; 03/09/2011 (FILE.ASM, 'proc_create_file')
  4173                              <1> 	; 09/08/2010
  4174                              <1> 	;
  4175                              <1> 	; INPUT ->
  4176                              <1> 	; 	EAX = File Size
  4177                              <1> 	; 	ESI = ASCIIZ File Name
  4178                              <1> 	; 	CL = File Attributes 
  4179                              <1> 	;	EBX = FFFFFFFFh -> create empty file 
  4180                              <1> 	;			 (only for FAT fs) 
  4181                              <1> 	; OUTPUT ->
  4182                              <1> 	;     CF = 0 ->
  4183                              <1> 	;	EAX = New file's first cluster
  4184                              <1> 	; 	ESI = Logical Dos Drv Descr. Table Addr.
  4185                              <1> 	; 	EBX = offset CreateFile_Size
  4186                              <1> 	; 	ECX = Sectors per cluster (<256) 
  4187                              <1> 	; 	EDX = Directory entry index/number (<65536)
  4188                              <1> 	;     CF = 1 -> error code in AL
  4189                              <1> 
  4190                              <1> ;	test	cl, 18h (directory or volume name)
  4191                              <1> ;	jnz	short loc_createfile_access_denied
  4192 0000920E 80E107              <1> 	and	cl, 07h ; S, H, R
  4193 00009211 880D[ACDF0000]      <1>         mov     [createfile_attrib], cl 
  4194                              <1> 
  4195 00009217 89D9                <1> 	mov	ecx, ebx
  4196 00009219 89F3                <1> 	mov	ebx, esi ; ASCIIZ File Name address
  4197 0000921B 29D2                <1> 	sub	edx, edx
  4198 0000921D 8A35[4ED30000]      <1>         mov     dh, [Current_Drv]
  4199 00009223 BE00010900          <1>         mov     esi, Logical_DOSDisks
  4200 00009228 01D6                <1> 	add	esi, edx
  4201                              <1> 
  4202 0000922A 8815[B7DF0000]      <1> 	mov	[createfile_UpdatePDir], dl ; 0 ; 31/03/2016 
  4203                              <1> 
  4204                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  4205 00009230 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  4206 00009234 730A                <1> 	jnb	short loc_createfile_check_file_sytem
  4207 00009236 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  4208 0000923B 66BA0000            <1> 	mov	dx, 0
  4209                              <1> 	; err retn: EDX = 0, EBX = File name offset
  4210                              <1> 	; ESI -> Dos drive description table address	
  4211 0000923F C3                  <1> 	retn
  4212                              <1> 
  4213                              <1> ;loc_createfile_access_denied:
  4214                              <1> ;	mov	eax, 05h ; access denied (invalid attributes input)
  4215                              <1> ;	stc
  4216                              <1> ;	retn
  4217                              <1> 
  4218                              <1> loc_createfile_check_file_sytem:
  4219 00009240 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  4220 00009244 730A                <1> 	jnb	short loc_createfile_chk_empty_FAT_file_sign1
  4221                              <1> 
  4222 00009246 A3[98DF0000]        <1> 	mov	[createfile_size], eax
  4223                              <1> 	; ESI = Logical Dos Drive Description Table address
  4224                              <1> 	; EBX = ASCIIZ File Name address
  4225 0000924B E9FE020000          <1> 	jmp	create_fs_file
  4226                              <1> 
  4227                              <1> loc_createfile_chk_empty_FAT_file_sign1:
  4228                              <1> 	; ECX = FFFFFFFFh -> create empty file if drive has FAT fs
  4229 00009250 41                  <1> 	inc	ecx
  4230 00009251 7506                <1> 	jnz	short loc_createfile_chk_empty_FAT_file_sign2
  4231 00009253 890D[98DF0000]      <1> 	mov	[createfile_size], ecx ; 0 ; empty file
  4232                              <1> 
  4233                              <1> loc_createfile_chk_empty_FAT_file_sign2:
  4234                              <1> 	; 23/03/2016
  4235 00009259 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec]
  4236 0000925D 66890D[B4DF0000]    <1> 	mov	[createfile_BytesPerSec], cx
  4237                              <1> 	
  4238                              <1> 	; EBX = ASCIIZ File Name address
  4239 00009264 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  4240 00009268 8815[ADDF0000]      <1> 	mov	[createfile_SecPerClust], dl
  4241 0000926E 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  4242 00009271 39D1                <1> 	cmp	ecx, edx ; byte [createfile_SecPerClust]
  4243 00009273 7306                <1> 	jnb	short loc_create_fat_file
  4244                              <1> 	  
  4245                              <1> loc_createfile_insufficient_disk_space:
  4246 00009275 B827000000          <1> 	mov	eax, 27h
  4247                              <1> loc_createfile_gffc_retn:
  4248 0000927A C3                  <1> 	retn
  4249                              <1> 
  4250                              <1> loc_create_fat_file:
  4251 0000927B 891D[90DF0000]      <1> 	mov	[createfile_Name_Offset], ebx
  4252 00009281 890D[94DF0000]      <1> 	mov	[createfile_FreeSectors], ecx
  4253                              <1> 
  4254                              <1> loc_createfile_gffc_1:
  4255 00009287 E821050000          <1> 	call	get_first_free_cluster
  4256 0000928C 72EC                <1> 	jc	short loc_createfile_gffc_retn
  4257                              <1> 
  4258 0000928E A3[9CDF0000]        <1> 	mov	[createfile_FFCluster], eax
  4259                              <1> 
  4260                              <1> loc_createfile_locate_ffe_on_directory:
  4261                              <1> 	; Current directory fcluster <> Directory buffer cluster
  4262                              <1> 	; Current directory will be reloaded by
  4263                              <1> 	; 'locate_current_dir_file' procedure
  4264                              <1> 	;
  4265                              <1> 	; ESI = Logical Dos Drv Desc. Table Adress
  4266 00009293 56                  <1> 	push	esi ; *
  4267 00009294 31C0                <1> 	xor	eax, eax
  4268                              <1> 
  4269 00009296 A3[6EDB0000]        <1> 	mov	dword [FAT_ClusterCounter], eax ; 0
  4270                              <1> 	; 21/03/2016
  4271 0000929B A2[B6DF0000]        <1> 	mov	byte [createfile_wfc], al ; 0 
  4272                              <1> 
  4273 000092A0 89C1                <1>  	mov	ecx, eax
  4274 000092A2 6649                <1> 	dec	cx ; FFFFh  
  4275                              <1> 	; CX = FFFFh -> find first deleted or free entry
  4276                              <1> 	; ESI would be ASCIIZ filename Address if the call
  4277                              <1> 	; would not be for first free or deleted dir entry  
  4278 000092A4 E8F6E7FFFF          <1> 	call	locate_current_dir_file
  4279 000092A9 0F83EE000000        <1> 	jnc	loc_createfile_set_ff_dir_entry
  4280 000092AF 5E                  <1> 	pop	esi ; *
  4281                              <1> 	 ; ESI = Logical DOS Drv. Description Table Address 
  4282 000092B0 83F802              <1> 	cmp	eax, 2
  4283 000092B3 7402                <1> 	je	short loc_createfile_add_new_cluster
  4284                              <1> loc_createfile_locate_file_stc_retn:
  4285 000092B5 F9                  <1> 	stc
  4286 000092B6 C3                  <1> 	retn
  4287                              <1> 
  4288                              <1> loc_createfile_add_new_cluster:
  4289 000092B7 803D[4DD30000]02    <1> 	cmp	byte [Current_FATType], 2
  4290                              <1> 	;cmp	byte [esi+LD_FATType], 2
  4291 000092BE 770C                <1> 	ja	short loc_createfile_add_new_cluster_check_fsc
  4292 000092C0 803D[4CD30000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  4293                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  4294 000092C7 7303                <1> 	jnb	short loc_createfile_add_new_cluster_check_fsc
  4295                              <1> 	
  4296                              <1> 	;mov	eax, 12
  4297 000092C9 B00C                <1> 	mov	al, 12 ; No more files 
  4298                              <1> 
  4299                              <1> loc_createfile_anc_retn:
  4300 000092CB C3                  <1> 	retn
  4301                              <1> 
  4302                              <1> loc_createfile_add_new_cluster_check_fsc:
  4303 000092CC 8B0D[94DF0000]      <1> 	mov	ecx, [createfile_FreeSectors]
  4304 000092D2 0FB605[ADDF0000]    <1> 	movzx	eax, byte [createfile_SecPerClust]
  4305 000092D9 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  4306 000092DC 39C1                <1> 	cmp	ecx, eax
  4307 000092DE 7295                <1>         jb	short loc_createfile_insufficient_disk_space
  4308                              <1> 
  4309                              <1> loc_createfile_add_new_subdir_cluster:
  4310 000092E0 8B15[7DDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  4311 000092E6 8915[A0DF0000]      <1> 	mov	[createfile_LastDirCluster], edx	
  4312                              <1> 
  4313 000092EC A1[9CDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4314 000092F1 E846040000          <1> 	call	load_FAT_sub_directory 
  4315 000092F6 72D3                <1> 	jc	short loc_createfile_anc_retn
  4316                              <1> 
  4317                              <1> pass_createfile_add_new_subdir_cluster:
  4318                              <1> 	;movzx	eax, word [esi+LD_BPB+BytesPerSec]
  4319 000092F8 0FB705[B4DF0000]    <1> 	movzx	eax, word [createfile_BytesPerSec] ; 23/03/2016
  4320 000092FF F7E1                <1> 	mul	ecx ; ecx = directory buffer sector count
  4321 00009301 89C1                <1> 	mov	ecx, eax
  4322 00009303 C1E902              <1> 	shr	ecx, 2 ; dword count
  4323 00009306 29C0                <1> 	sub	eax, eax ; 0
  4324 00009308 F3AB                <1> 	rep	stosd 
  4325                              <1> 	;
  4326 0000930A C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4327 00009311 E8ADEFFFFF          <1> 	call	save_directory_buffer
  4328 00009316 72B3                <1> 	jc	short loc_createfile_anc_retn
  4329                              <1> 
  4330                              <1> loc_createfile_save_added_subdir_cluster:
  4331 00009318 A1[A0DF0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4332 0000931D 8B0D[9CDF0000]      <1> 	mov	ecx, [createfile_FFCluster]
  4333 00009323 E858050000          <1> 	call	update_cluster
  4334 00009328 7304                <1> 	jnc	short loc_createfile_save_fat_buffer_0
  4335 0000932A 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4336 0000932C 751A                <1> 	jnz	short loc_createfile_save_fat_buffer_stc_retn
  4337                              <1> 
  4338                              <1> loc_createfile_save_fat_buffer_0:
  4339 0000932E A1[9CDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4340 00009333 A3[A0DF0000]        <1> 	mov	[createfile_LastDirCluster], eax
  4341 00009338 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh ; 28 bit
  4342 0000933D E83E050000          <1> 	call	update_cluster
  4343 00009342 7306                <1> 	jnc	short loc_createfile_save_fat_buffer_1
  4344 00009344 09C0                <1> 	or	eax, eax ; Was it free cluster
  4345 00009346 7402                <1> 	jz	short loc_createfile_save_fat_buffer_1
  4346                              <1> 
  4347                              <1> loc_createfile_save_fat_buffer_stc_retn:
  4348 00009348 F9                  <1> 	stc
  4349                              <1> loc_createfile_save_fat_buffer_retn:
  4350                              <1> loc_createfile_gffc_2_stc_retn:
  4351 00009349 C3                  <1> 	retn
  4352                              <1> 
  4353                              <1> loc_createfile_save_fat_buffer_1:
  4354                              <1> 	; byte [FAT_BuffValidData] = 2 
  4355 0000934A E8EE070000          <1> 	call	save_fat_buffer
  4356 0000934F 72F8                <1> 	jc	short loc_createfile_save_fat_buffer_retn
  4357                              <1> 
  4358 00009351 803D[6EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4359 00009358 7222                <1> 	jb	short loc_createfile_save_fat_buffer_2
  4360                              <1> 
  4361                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4362 0000935A A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4363                              <1> 
  4364 0000935F C605[6EDB0000]00    <1> 	mov	byte [FAT_ClusterCounter], 0 ; 21/03/2016
  4365                              <1> 
  4366 00009366 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4367 0000936A E863080000          <1> 	call	calculate_fat_freespace
  4368                              <1> 
  4369                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4370                              <1> 	;jnz	short loc_createfile_save_fat_buffer_2
  4371                              <1> 
  4372                              <1> 	; ecx > 0 -> Recalculation is needed
  4373 0000936F 09C9                <1> 	or	ecx, ecx 
  4374 00009371 7409                <1> 	jz	short loc_createfile_save_fat_buffer_2
  4375                              <1> 
  4376 00009373 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4377 00009377 E856080000          <1> 	call	calculate_fat_freespace
  4378                              <1> 
  4379                              <1> loc_createfile_save_fat_buffer_2:
  4380                              <1> 	;call	update_parent_dir_lmdt
  4381                              <1> 
  4382                              <1> loc_createfile_gffc_2:
  4383 0000937C E82C040000          <1> 	call	get_first_free_cluster
  4384 00009381 72C6                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4385                              <1> 
  4386 00009383 A3[9CDF0000]        <1> 	mov	[createfile_FFCluster], eax
  4387                              <1> 
  4388 00009388 A1[A0DF0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4389                              <1> 	
  4390 0000938D E8AA030000          <1> 	call	load_FAT_sub_directory 
  4391 00009392 72B5                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4392                              <1> 
  4393 00009394 BF00000800          <1> 	mov	edi, Directory_Buffer
  4394                              <1> 
  4395 00009399 6629DB              <1> 	sub	bx, bx ; directory entry index/number = 0
  4396                              <1> 
  4397 0000939C 56                  <1> 	push	esi ; * ; 23/03/2016
  4398                              <1> 
  4399                              <1> loc_createfile_set_ff_dir_entry:
  4400 0000939D 66891D[AEDF0000]    <1> 	mov	[createfile_DirIndex], bx
  4401                              <1> 
  4402                              <1>         ; EDI = Directory entry address
  4403 000093A4 8B35[90DF0000]      <1> 	mov	esi, [createfile_Name_Offset]
  4404 000093AA A1[9CDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4405 000093AF A3[A4DF0000]        <1> 	mov	[createfile_Cluster], eax ; 24/03/2016
  4406 000093B4 B5FF                <1> 	mov	ch, 0FFh
  4407 000093B6 8A0D[ACDF0000]      <1>         mov	cl, [createfile_attrib] ; file attributes
  4408                              <1> 	; CH > 0 -> File size is in EBX
  4409 000093BC BB[98DF0000]        <1> 	mov	ebx, createfile_size
  4410                              <1>   
  4411 000093C1 E820EEFFFF          <1> 	call	make_directory_entry
  4412                              <1> 	
  4413 000093C6 5E                  <1> 	pop	esi ; * ; ESI = Logical Dos Drv Desc. Table address
  4414                              <1> 
  4415 000093C7 C605[78DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4416 000093CE E8F0EEFFFF          <1> 	call	save_directory_buffer
  4417 000093D3 7221                <1> 	jc	short loc_createfile_set_ff_dir_entry_retn
  4418                              <1> 
  4419 000093D5 C605[B7DF0000]01    <1> 	mov	byte [createfile_UpdatePDir], 1 ; 31/03/2016 
  4420                              <1> 
  4421                              <1> loc_createfile_get_set_write_file_cluster:
  4422 000093DC A1[98DF0000]        <1> 	mov	eax, [createfile_size]
  4423 000093E1 09C0                <1> 	or	eax, eax
  4424 000093E3 7570                <1> 	jnz	short loc_createfile_get_set_wfc_cont
  4425 000093E5 40                  <1> 	inc	eax
  4426                              <1> 	; 23/03/2016
  4427 000093E6 0FB61D[ADDF0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4428                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512
  4429 000093ED 0FB70D[B4DF0000]    <1>         movzx   ecx, word [createfile_BytesPerSec] ; 512
  4430 000093F4 EB7C                <1> 	jmp	loc_createfile_set_cluster_count 
  4431                              <1> 
  4432                              <1> loc_createfile_set_ff_dir_entry_retn:
  4433 000093F6 C3                  <1> 	retn
  4434                              <1> 
  4435                              <1> loc_createfile_write_fcluster_to_disk:
  4436 000093F7 034668              <1> 	add	eax, [esi+LD_DATABegin] ; convert to physical address
  4437 000093FA BB00000700          <1> 	mov	ebx, Cluster_Buffer
  4438                              <1> 	; ESI = Logical DOS Drv. Desc. Tbl. address
  4439                              <1> 	; EAX = Disk address
  4440                              <1> 	; EBX = Sector Buffer
  4441                              <1> 	; ECX = sectors per cluster
  4442 000093FF E8EF290000          <1> 	call	disk_write
  4443 00009404 7211                <1> 	jc	short loc_createfile_dsk_wr_err
  4444                              <1> 
  4445                              <1> loc_createfile_update_fat_cluster:
  4446                              <1> 	; 21/03/2016	
  4447 00009406 803D[B6DF0000]00    <1> 	cmp	byte [createfile_wfc], 0 
  4448 0000940D 7712                <1> 	ja	short loc_createfile_update_fat_cluster_n1
  4449                              <1> 
  4450 0000940F FE05[B6DF0000]      <1> 	inc	byte [createfile_wfc] ; 1
  4451 00009415 EB24                <1> 	jmp	short loc_createfile_update_fat_cluster_n2
  4452                              <1> 
  4453                              <1> loc_createfile_dsk_wr_err:
  4454                              <1> 	; 23/03/2016
  4455 00009417 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  4456 0000941C E9BD000000          <1> 	jmp	loc_createfile_stc_retn
  4457                              <1> 
  4458                              <1> loc_createfile_update_fat_cluster_n1:
  4459 00009421 A1[A8DF0000]        <1> 	mov	eax, [createfile_PCluster]
  4460 00009426 8B0D[A4DF0000]      <1> 	mov	ecx, [createfile_Cluster]
  4461 0000942C E84F040000          <1> 	call	update_cluster
  4462 00009431 7308                <1> 	jnc	short loc_createfile_update_fat_cluster_n2
  4463 00009433 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4464 00009435 0F85A3000000        <1> 	jnz	loc_createfile_stc_retn
  4465                              <1> 
  4466                              <1> loc_createfile_update_fat_cluster_n2:
  4467 0000943B A1[A4DF0000]        <1>         mov	eax, [createfile_Cluster]
  4468 00009440 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4469 00009445 E836040000          <1> 	call	update_cluster
  4470 0000944A 734E                <1> 	jnc	short loc_createfile_save_fat_buffer_3
  4471 0000944C 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4472 0000944E 744A                <1> 	jz	short loc_createfile_save_fat_buffer_3
  4473                              <1> 
  4474                              <1> loc_createfile_upd_fat_fcluster_stc_retn:
  4475 00009450 E989000000          <1> 	jmp	loc_createfile_stc_retn
  4476                              <1> 
  4477                              <1> loc_createfile_get_set_wfc_cont:
  4478                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512	
  4479 00009455 0FB70D[B4DF0000]    <1> 	movzx	ecx, word [createfile_BytesPerSec] ; 512
  4480 0000945C 01C8                <1> 	add	eax, ecx
  4481 0000945E 48                  <1> 	dec	eax  ; add eax, 511
  4482 0000945F 29D2                <1> 	sub	edx, edx
  4483 00009461 F7F1                <1> 	div	ecx
  4484 00009463 0FB61D[ADDF0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4485 0000946A 01D8                <1> 	add	eax, ebx
  4486 0000946C 48                  <1> 	dec	eax  ; add eax, SecPerClust - 1
  4487 0000946D 6631D2              <1> 	xor	dx, dx
  4488 00009470 F7F3                <1> 	div	ebx
  4489                              <1> 
  4490                              <1> loc_createfile_set_cluster_count:
  4491 00009472 A3[B0DF0000]        <1> 	mov 	[createfile_CCount], eax
  4492                              <1> 	
  4493 00009477 BF00000700          <1> 	mov	edi, Cluster_Buffer
  4494 0000947C 89C8                <1> 	mov	eax, ecx ; Bytes per Sector
  4495 0000947E F7E3                <1> 	mul	ebx ; Sectors per Cluster 
  4496                              <1> 	; EAX = Bytes per Cluster
  4497 00009480 89C1                <1> 	mov	ecx, eax
  4498 00009482 C1E902              <1> 	shr	ecx, 2 ; dword count
  4499 00009485 31C0                <1> 	xor	eax, eax
  4500 00009487 F3AB                <1> 	rep	stosd ; clear cluster buffer
  4501                              <1> 
  4502 00009489 A1[A4DF0000]        <1> 	mov	eax, [createfile_Cluster] ; 24/03/2016
  4503                              <1> 
  4504 0000948E 89D9                <1> 	mov	ecx, ebx
  4505                              <1> 
  4506                              <1> loc_createfile_get_set_wf_fclust_cont:
  4507 00009490 83E802              <1> 	sub	eax, 2
  4508 00009493 F7E1                <1> 	mul	ecx
  4509                              <1> 	; EAX = Logical DOS disk address (offset)
  4510 00009495 E95DFFFFFF          <1>         jmp     loc_createfile_write_fcluster_to_disk
  4511                              <1> 
  4512                              <1> loc_createfile_save_fat_buffer_3:
  4513                              <1> 	; byte [FAT_BuffValidData] = 2
  4514 0000949A E89E060000          <1> 	call	save_fat_buffer
  4515 0000949F 723D                <1> 	jc	loc_createfile_stc_retn
  4516                              <1> 
  4517                              <1> 	; 21/03/2016
  4518 000094A1 803D[6EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4519 000094A8 721B                <1> 	jb	short loc_createfile_save_fat_buffer_4
  4520                              <1> 
  4521                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4522 000094AA A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4523 000094AF 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4524 000094B3 E81A070000          <1> 	call	calculate_fat_freespace
  4525                              <1> 
  4526                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4527                              <1> 	;jnz	short loc_createfile_save_fat_buffer_4
  4528                              <1> 
  4529                              <1> 	; ecx > 0 -> Recalculation is needed
  4530 000094B8 09C9                <1> 	or	ecx, ecx 
  4531 000094BA 7409                <1> 	jz	short loc_createfile_save_fat_buffer_4
  4532                              <1> 
  4533 000094BC 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4534 000094C0 E80D070000          <1> 	call	calculate_fat_freespace
  4535                              <1> 
  4536                              <1> loc_createfile_save_fat_buffer_4:
  4537 000094C5 FF0D[B0DF0000]      <1> 	dec	dword [createfile_CCount]
  4538                              <1> 	;jz	short loc_createfile_upd_dir_modif_date_time
  4539 000094CB 743F                <1> 	jz	short loc_createfile_stc_retn_cc ; 31/03/2016
  4540                              <1> 
  4541                              <1> loc_createfile_get_set_write_next_cluster:
  4542 000094CD E8DB020000          <1> 	call	get_first_free_cluster
  4543 000094D2 720A                <1> 	jc	short loc_createfile_stc_retn
  4544                              <1> 
  4545                              <1> loc_createfile_get_set_write_next_cluster_1:
  4546 000094D4 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  4547 000094D7 7213                <1> 	jb	short loc_createfile_get_set_write_next_cluster_2
  4548                              <1> 
  4549                              <1> loc_createfile_wnc_insufficient_disk_space:	
  4550 000094D9 B827000000          <1> 	mov	eax, 27h ; Insufficient disk space
  4551                              <1> 
  4552                              <1> loc_createfile_stc_retn:
  4553 000094DE 803D[B6DF0000]01    <1> 	cmp	byte [createfile_wfc], 1
  4554 000094E5 7324                <1> 	jnb	short loc_createfile_err_retn
  4555 000094E7 C3                  <1> 	retn
  4556                              <1> 
  4557                              <1> loc_createfile_wnc_inv_format_retn:
  4558                              <1> 	;mov	eax, 0Bh
  4559 000094E8 B00B                <1> 	mov	al, 0Bh ; Invalid format
  4560 000094EA EBF2                <1> 	jmp	short loc_createfile_stc_retn
  4561                              <1> 	         
  4562                              <1> loc_createfile_get_set_write_next_cluster_2:
  4563 000094EC 83F802              <1> 	cmp	eax, 2
  4564 000094EF 72F7                <1> 	jb	short loc_createfile_wnc_inv_format_retn
  4565                              <1> 
  4566                              <1> loc_createfile_get_set_write_next_cluster_3:
  4567 000094F1 8B0D[A4DF0000]      <1> 	mov	ecx, [createfile_Cluster]
  4568 000094F7 A3[A4DF0000]        <1> 	mov	[createfile_Cluster], eax
  4569 000094FC 890D[A8DF0000]      <1> 	mov	[createfile_PCluster], ecx
  4570 00009502 0FB60D[ADDF0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust]
  4571 00009509 EB85                <1> 	jmp	short loc_createfile_get_set_wf_fclust_cont
  4572                              <1> 
  4573                              <1> loc_createfile_err_retn:
  4574 0000950B F9                  <1> 	stc
  4575                              <1> 
  4576                              <1> ;loc_createfile_upd_dir_modif_date_time:
  4577                              <1> loc_createfile_stc_retn_cc: ; 31/03/2016
  4578 0000950C 9C                  <1> 	pushf	; cpu is here for an error return or completion 
  4579 0000950D 50                  <1> 	push	eax ; error code if cf = 1
  4580                              <1> 
  4581                              <1> 	;call	update_parent_dir_lmdt
  4582                              <1> 
  4583                              <1> ;loc_createfile_stc_retn_cc:
  4584 0000950E A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4585 00009513 09C0                <1> 	or	eax, eax
  4586 00009515 741A                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4587 00009517 8A3D[4ED30000]      <1> 	mov	bh, [Current_Drv]
  4588 0000951D B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  4589                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  4590                              <1> 	; (If EAX value is negative, Free Cluster Count will be decreased)
  4591 0000951F E8AE060000          <1>   	call	calculate_fat_freespace
  4592                              <1>         ; ESI = Logical DOS Drive Description Table Address 
  4593                              <1>         ;jc	short loc_createfile_stc_retn_pop_eax_cf
  4594 00009524 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  4595 00009526 7409                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4596                              <1> 
  4597                              <1> loc_createfile_stc_retn_recalc_FAT_freespace:
  4598 00009528 66BB00FF            <1> 	mov	bx, 0FF00h ; bh = 0FFh -> 
  4599                              <1> 	; ESI = Logical DOS Drv DT Addr
  4600                              <1> 	; BL = 0 -> Recalculate 
  4601 0000952C E8A1060000          <1> 	call	calculate_fat_freespace
  4602                              <1> 
  4603                              <1> loc_createfile_stc_retn_pop_eax:
  4604 00009531 58                  <1> 	pop	eax
  4605 00009532 9D                  <1> 	popf
  4606 00009533 7218                <1> 	jc	short loc_createfile_retn
  4607                              <1> 
  4608                              <1> loc_createfile_retn_fcluster:
  4609 00009535 A1[9CDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4610 0000953A BB[98DF0000]        <1> 	mov	ebx, createfile_size
  4611                              <1> 	;movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  4612 0000953F 0FB60D[ADDF0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust] ; 23/03/2016
  4613 00009546 0FB715[AEDF0000]    <1> 	movzx	edx, word [createfile_DirIndex]
  4614                              <1> 
  4615                              <1> loc_createfile_retn:
  4616 0000954D C3                  <1> 	retn
  4617                              <1> 
  4618                              <1> create_fs_file:
  4619                              <1> 	; temporary (21/03/2016)
  4620 0000954E C3                  <1> 	retn
  4621                              <1> 
  4622                              <1> delete_fs_file:
  4623                              <1> 	; temporary (28/02/2016)
  4624 0000954F C3                  <1> 	retn
  4625                              <1> 
  4626                              <1> rename_fs_file_or_directory:
  4627 00009550 C3                  <1> 	retn
  4628                              <1> 
  4629                              <1> make_fs_directory:
  4630                              <1> 	; temporary (21/02/2016)
  4631 00009551 C3                  <1> 	retn
  4632                              <1> 
  4633                              <1> add_new_fs_section:
  4634                              <1> 	; temporary (11/03/2016)
  4635 00009552 C3                  <1> 	retn
  4636                              <1> 
  4637                              <1> delete_fs_directory_entry:
  4638                              <1> 	; temporary (11/03/2016)
  4639 00009553 C3                  <1> 	retn
  4640                              <1> 
  4641                              <1> csftdf2_read_fs_file_sectors:
  4642                              <1> 	; temporary (19/03/2016)
  4643 00009554 C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> csftdf2_write_fs_file_sectors:
  4646                              <1> 	; temporary (19/03/2016)
  4647 00009555 C3                  <1> 	retn
  1881                                  %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: 16/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 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 00009556 A3[62DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
    34                              <1> check_next_cluster_fat_type:
    35 0000955B 29D2                <1> 	sub	edx, edx ; 0
    36 0000955D 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    37 00009561 7250                <1> 	jb	short get_FAT12_next_cluster
    38 00009563 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    39                              <1> get_FAT16_next_cluster:
    40 00009569 BB00030000          <1> 	mov	ebx, 300h ;768
    41 0000956E F7F3                <1> 	div	ebx
    42                              <1> 	; EAX = Count of 3 FAT sectors
    43                              <1> 	; EDX = Cluster Offset (< 768)
    44 00009570 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    45 00009573 89D3                <1> 	mov	ebx, edx ; Byte Offset
    46 00009575 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    47 0000957B 66BA0300            <1> 	mov	dx, 3
    48 0000957F F7E2                <1> 	mul	edx  
    49                              <1> 	; EAX = FAT Sector (<= 256)
    50                              <1> 	; EDX = 0
    51 00009581 8A0E                <1> 	mov	cl, [esi+LD_Name]
    52 00009583 803D[66DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    53 0000958A 0F86CC000000        <1>         jna     load_FAT_sectors0
    54 00009590 3A0D[67DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    55 00009596 0F85C0000000        <1>         jne     load_FAT_sectors0
    56 0000959C 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
    57 000095A2 0F85BA000000        <1>         jne     load_FAT_sectors1
    58                              <1> 	;movzx	eax, word [ebx]
    59 000095A8 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 000095AB 6683F8F7            <1> 	cmp	ax, 0FFF7h
    69 000095AF 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    70                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    71 000095B1 EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    72                              <1> 
    73                              <1> get_FAT12_next_cluster:
    74 000095B3 BB00040000          <1> 	mov	ebx, 400h ;1024
    75 000095B8 F7F3                <1> 	div	ebx
    76                              <1> 	; EAX = Count of 3 FAT sectors
    77                              <1> 	; EDX = Cluster Offset (< 1024)
    78 000095BA 6650                <1> 	push	ax
    79 000095BC 66B80300            <1> 	mov	ax, 3	
    80 000095C0 66F7E2              <1> 	mul	dx    	; Multiply by 3
    81 000095C3 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    82 000095C6 6689C3              <1>         mov	bx, ax 	; Byte Offset
    83 000095C9 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    84 000095CF 6658                <1> 	pop	ax
    85 000095D1 66BA0300            <1> 	mov	dx, 3
    86 000095D5 F7E2                <1> 	mul	edx 
    87                              <1> 	; EAX = FAT Sector (<= 12)
    88                              <1> 	; EDX = 0
    89 000095D7 8A0E                <1> 	mov	cl, [esi+LD_Name]
    90 000095D9 803D[66DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    91 000095E0 767A                <1> 	jna	short load_FAT_sectors0
    92 000095E2 3A0D[67DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    93 000095E8 7572                <1> 	jne	short load_FAT_sectors0
    94 000095EA 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
    95 000095F0 7570                <1> 	jne	short load_FAT_sectors1
    96 000095F2 A1[62DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
    97 000095F7 66D1E8              <1> 	shr	ax, 1
    98                              <1> 	;movzx	eax, word [ebx]
    99 000095FA 668B03              <1> 	mov	ax, [ebx]
   100 000095FD 7314                <1> 	jnc	short get_FAT12_nc_even
   101 000095FF 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 00009603 663DF70F            <1> 	cmp	ax, 0FF7h
   108 00009607 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 00009609 31C0                <1> 	xor	eax, eax ; 0
   113                              <1> loc_pass_gnc_FAT16_eoc_check:
   114                              <1> loc_pass_gnc_FAT32_eoc_check:
   115 0000960B 8B0D[62DB0000]      <1> 	mov	ecx, [FAT_CurrentCluster]
   116 00009611 F5                  <1> 	cmc
   117 00009612 C3                  <1> 	retn
   118                              <1> 
   119                              <1> get_FAT12_nc_even:
   120 00009613 80E40F              <1> 	and	ah, 0Fh
   121 00009616 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   122                              <1> 
   123                              <1> get_FAT32_next_cluster:
   124 00009618 BB80010000          <1> 	mov	ebx, 180h ;384
   125 0000961D F7F3                <1> 	div	ebx
   126                              <1> 	; EAX = Count of 3 FAT sectors
   127                              <1> 	; EDX = Cluster Offset (< 384)
   128 0000961F 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   129 00009623 89D3                <1> 	mov	ebx, edx ; Byte Offset
   130 00009625 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   131 0000962B 66BA0300            <1> 	mov	dx, 3
   132 0000962F 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 00009631 8A0E                <1> 	mov	cl, [esi+LD_Name]
   138 00009633 803D[66DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   139 0000963A 7620                <1> 	jna	short load_FAT_sectors0
   140 0000963C 3A0D[67DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
   141 00009642 7518                <1> 	jne	short load_FAT_sectors0
   142 00009644 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   143 0000964A 7516                <1> 	jne	short load_FAT_sectors1
   144 0000964C 8B03                <1> 	mov	eax, [ebx]
   145 0000964E 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   146 00009653 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   147 00009658 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   148                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   149 0000965A EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   150                              <1> 
   151                              <1> load_FAT_sectors0:
   152 0000965C 880D[67DB0000]      <1> 	mov	[FAT_BuffDrvName], cl
   153                              <1> load_FAT_sectors1:
   154 00009662 A3[6ADB0000]        <1> 	mov	[FAT_BuffSector], eax
   155 00009667 89C3                <1> 	mov	ebx, eax
   156 00009669 034660              <1>         add     eax, [esi+LD_FATBegin]
   157 0000966C 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   158 00009670 7706                <1>         ja      short load_FAT_sectors3
   159 00009672 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   160 00009676 EB03                <1> 	jmp	short load_FAT_sectors4
   161                              <1> load_FAT_sectors3:
   162 00009678 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   163                              <1> load_FAT_sectors4:
   164 0000967B 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   165 0000967D 83F903              <1>         cmp     ecx, 3
   166 00009680 7605                <1>         jna     short load_FAT_sectors5
   167 00009682 B903000000          <1> 	mov	ecx, 3
   168                              <1> load_FAT_sectors5:
   169 00009687 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   170 0000968C E871270000          <1> 	call	disk_read
   171 00009691 730D                <1> 	jnc	short load_FAT_sectors_ok
   172                              <1> 	; 23/03/2016
   173 00009693 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   174 00009698 C605[66DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   175 0000969F C3                  <1> 	retn
   176                              <1> load_FAT_sectors_ok:
   177 000096A0 C605[66DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
   178 000096A7 A1[62DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
   179 000096AC 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 000096B1 8A1E                <1> 	mov	bl, [esi+LD_Name]
   204 000096B3 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   205                              <1> 
   206                              <1> 	;mov	[DirBuff_DRV], bl
   207                              <1> 	;mov	[DirBuff_FATType], bh
   208 000096B6 66891D[76DB0000]    <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 000096BD 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 000096C1 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   219 000096C6 7414                <1> 	je	short lrd_mov_ecx_32
   220 000096C8 89D0                <1> 	mov	eax, edx
   221 000096CA 6683C00F            <1> 	add	ax, 15 ; round up 
   222 000096CE 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
   223 000096D2 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
   224 000096D4 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
   225 000096D8 664A                <1> 	dec	dx    ; Last entry number of root dir
   226                              <1> 	; cx = Dir Buffer sector count             
   227 000096DA EB0B                <1> 	jmp	short lrd_check_dir_buffer
   228                              <1> 
   229                              <1> lrd_mov_ecx_32:
   230 000096DC B920000000          <1> 	mov	ecx, 32
   231 000096E1 664A                <1> 	dec	dx ; 511
   232 000096E3 66B80040            <1> 	mov	ax, 32*512 
   233                              <1>  
   234                              <1> lrd_check_dir_buffer:
   235 000096E7 29DB                <1> 	sub	ebx, ebx ; 0
   236 000096E9 881D[78DB0000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   237 000096EF 668915[7BDB0000]    <1> 	mov	[DirBuff_LastEntry], dx
   238 000096F6 891D[7DDB0000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   239 000096FC 66A3[81DB0000]      <1> 	mov	[DirBuffer_Size], ax
   240                              <1> 
   241 00009702 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   242                              <1> read_directory:
   243 00009705 BB00000800          <1> 	mov	ebx, Directory_Buffer
   244 0000970A 51                  <1> 	push	ecx ; Directory buffer sector count
   245 0000970B 53                  <1> 	push	ebx
   246 0000970C E8F1260000          <1> 	call	disk_read
   247 00009711 5B                  <1> 	pop	ebx
   248 00009712 720B                <1> 	jc	short load_DirBuff_error
   249                              <1> 
   250                              <1> validate_DirBuff_and_return:
   251 00009714 59                  <1> 	pop	ecx ; Number of loaded sectors
   252 00009715 C605[78DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
   253 0000971C 31C0                <1> 	xor	eax, eax ; 0 = no error
   254 0000971E C3                  <1> 	retn
   255                              <1> 
   256                              <1> load_DirBuff_error:
   257 0000971F 89C8                <1> 	mov	eax, ecx ; remaining sectors
   258 00009721 59                  <1> 	pop	ecx ; sector count
   259 00009722 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   260 00009724 B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
   261 00009729 F9                  <1> 	stc
   262 0000972A 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 0000972B 8A1E                <1> 	mov	bl, [esi+LD_Name]
   281 0000972D 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   282                              <1> 
   283                              <1> 	;mov	[DirBuff_DRV], bl
   284                              <1> 	;mov	[DirBuff_FATType], bh
   285 00009730 66891D[76DB0000]    <1> 	mov	[DirBuff_DRV], bx
   286                              <1> 
   287                              <1> load_FAT32_root_dir0:
   288 00009737 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   289 0000973A 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 0000973C 8A1E                <1> 	mov	bl, [esi+LD_Name]
   311 0000973E 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   312                              <1> 
   313                              <1> 	;mov	[DirBuff_DRV], bl
   314                              <1> 	;mov	[DirBuff_FATType], bh
   315 00009741 66891D[76DB0000]    <1> 	mov	[DirBuff_DRV], bx
   316                              <1> 
   317                              <1> load_FAT_sub_dir0:
   318 00009748 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   319                              <1> 
   320 0000974C 882D[78DB0000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   321 00009752 A3[7DDB0000]        <1> 	mov	[DirBuff_Cluster], eax
   322                              <1> 
   323 00009757 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   324 0000975B F7E1                <1> 	mul	ecx
   325 0000975D C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   326 00009760 6648                <1> 	dec	ax ; last entry
   327 00009762 66A3[7BDB0000]      <1> 	mov	[DirBuff_LastEntry], ax
   328                              <1> 
   329 00009768 A1[7DDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   330 0000976D 83E802              <1> 	sub	eax, 2
   331 00009770 F7E1                <1> 	mul	ecx
   332 00009772 034668              <1> 	add	eax, [esi+LD_DATABegin]
   333                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   334 00009775 EB8E                <1> 	jmp	short read_directory
   335                              <1> 
   336                              <1> ; DRV_FS.ASM
   337                              <1> 
   338                              <1> load_current_FS_directory:
   339 00009777 C3                  <1> 	retn
   340                              <1> load_FS_root_directory:
   341 00009778 C3                  <1> 	retn
   342                              <1> load_FS_sub_directory:
   343 00009779 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 0000977A 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 0000977E 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   369 00009782 761C                <1> 	jna	short read_fs_cluster
   370                              <1> 
   371                              <1> read_fat_file_sectors: ; 18/03/2016
   372 00009784 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   373 00009787 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
   374 0000978B F7E2                <1> 	mul	edx
   375 0000978D 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 00009790 E86D260000          <1> 	call	disk_read
   384 00009795 7306                <1> 	jnc	short rclust_retn
   385                              <1> 	
   386 00009797 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
   387 0000979C C3                  <1> 	retn
   388                              <1> 
   389                              <1> rclust_retn:
   390 0000979D 29C0                <1> 	sub	eax, eax ; 0
   391 0000979F 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 000097A0 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   406 000097A5 E801000000          <1> 	call	read_fs_sectors
   407 000097AA C3                  <1> 	retn
   408                              <1> 
   409                              <1> read_fs_sectors:
   410                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   411 000097AB F9                  <1> 	stc
   412 000097AC 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 000097AD 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   430 000097B0 40                  <1> 	inc	eax ; add eax, 1
   431 000097B1 A3[00DE0000]        <1> 	mov	[gffc_last_free_cluster], eax
   432                              <1> 
   433 000097B6 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   434                              <1> 
   435 000097B8 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   436 000097BC 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 000097BE E834060000          <1> 	call	get_fat32_fsinfo_sector_parms
   441 000097C3 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 000097C5 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   453 000097C7 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   454 000097CA 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 000097CC B802000000          <1> 	mov	eax, 2
   459                              <1> 	;xor	edx, edx
   460                              <1> 
   461                              <1> loc_gffc_get_first_fat_free_cluster1:
   462 000097D1 53                  <1> 	push	ebx ; 02/03/2016 
   463                              <1> 
   464                              <1> loc_gffc_get_first_fat_free_cluster2:   
   465 000097D2 A3[FCDD0000]        <1> 	mov	[gffc_first_free_cluster], eax
   466 000097D7 A3[F8DD0000]        <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 000097DC E875FDFFFF          <1> 	call	get_next_cluster
   474 000097E1 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   475 000097E3 09C0                <1> 	or	eax, eax
   476 000097E5 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   477 000097E7 5B                  <1> 	pop	ebx ; 02/03/2016
   478 000097E8 F5                  <1> 	cmc 	; stc
   479 000097E9 C3                  <1> 	retn
   480                              <1> 
   481                              <1> loc_gffc_get_first_fat_free_cluster4:
   482 000097EA 21C0                <1> 	and	eax, eax ; next cluster value
   483 000097EC 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   484 000097EE 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   485 000097F0 EB22                <1> 	jmp	short loc_gffc_check_for_set
   486                              <1>  
   487                              <1> loc_gffc_first_free_fat_cluster_next:
   488 000097F2 A1[F8DD0000]        <1> 	mov	eax, [gffc_next_free_cluster]
   489 000097F7 3B05[00DE0000]      <1> 	cmp	eax, [gffc_last_free_cluster]
   490 000097FD 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   491                              <1> pass_gffc_last_cluster_eax_check:
   492 000097FF 40                  <1> 	inc	eax ; add eax, 1
   493 00009800 A3[F8DD0000]        <1> 	mov	[gffc_next_free_cluster], eax
   494 00009805 EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   495                              <1> 
   496                              <1> retn_stc_from_get_first_free_cluster:
   497 00009807 A1[FCDD0000]        <1> 	mov	eax, [gffc_first_free_cluster]
   498 0000980C 83F802              <1> 	cmp	eax, 2
   499 0000980F 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   500 00009811 29C0                <1> 	sub	eax, eax
   501 00009813 48                  <1> 	dec	eax ; FFFFFFFFh
   502                              <1> 
   503                              <1> loc_gffc_check_for_set:
   504                              <1> 	; 02/03/2016
   505 00009814 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 00009815 09DB                <1> 	or	ebx, ebx
   512 00009817 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 00009819 C3                  <1> 	retn
   521                              <1> 
   522                              <1> loc_gffc_check_previous_clusters:
   523 0000981A 48                  <1> 	dec	eax ; sub eax, 1
   524 0000981B A3[00DE0000]        <1> 	mov	[gffc_last_free_cluster], eax 
   525 00009820 B802000000          <1> 	mov	eax, 2
   526                              <1> 	;xor	edx, edx
   527 00009825 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 00009827 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 0000982A 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   565 00009830 7540                <1> 	jne	short loc_sffc_read_fsinfo_sector
   566 00009832 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   566 0000983B 61                  <1>
   567 0000983C 7534                <1> 	jne	short loc_sffc_read_fsinfo_sector
   568                              <1> 
   569 0000983E 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   570 00009844 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 00009846 8983EC010000        <1> 	mov	[ebx+492], eax
   576 0000984C A1[10DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   577 00009851 B901000000          <1> 	mov	ecx, 1
   578 00009856 53                  <1> 	push	ebx
   579 00009857 E897250000          <1> 	call	disk_write
   580 0000985C 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   581 0000985E 5B                  <1> 	pop	ebx
   582                              <1> 
   583 0000985F 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   584                              <1> 
   585                              <1> loc_sffc_retn:
   586 00009865 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 00009866 BB00000000          <1> 	mov	ebx, 0
   594                              <1> 	; 23/03/2016
   595 0000986B B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
   596                              <1> 
   597                              <1> loc_sffc_read_fsinfo_sector_err2:
   598 00009870 5A                  <1> 	pop	edx
   599 00009871 C3                  <1> 	retn
   600                              <1> 	
   601                              <1> loc_sffc_read_fsinfo_sector:
   602 00009872 50                  <1> 	push	eax
   603                              <1> 
   604 00009873 E87F050000          <1> 	call	get_fat32_fsinfo_sector_parms
   605 00009878 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   606                              <1> 
   607 0000987A 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 0000987B 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   612 0000987D 75C7                <1> 	jne	short loc_sffc_write_fsinfo_sector
   613                              <1> 
   614 0000987F 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 00009880 A3[62DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   648 00009885 890D[04DE0000]      <1> 	mov	[ClusterValue], ecx
   649                              <1> 
   650                              <1> loc_update_cluster_check_fat_buffer:
   651 0000988B 8A1E                <1> 	mov	bl, [esi+LD_Name]
   652 0000988D 381D[67DB0000]      <1> 	cmp	[FAT_BuffDrvName], bl
   653 00009893 741A                <1> 	je	short loc_update_cluster_check_fat_type
   654 00009895 803D[66DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   655 0000989C 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   656                              <1> 
   657                              <1> loc_uc_reset_fat_buffer_validation:
   658 000098A2 C605[66DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   659                              <1> 
   660                              <1> loc_uc_check_fat_type_reset_drvname:
   661 000098A9 881D[67DB0000]      <1> 	mov	[FAT_BuffDrvName], bl
   662                              <1> 
   663                              <1> loc_update_cluster_check_fat_type:
   664 000098AF 29D2                <1> 	sub	edx, edx ; 26/02/2016
   665 000098B1 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   666 000098B4 83F802              <1> 	cmp	eax, 2
   667 000098B7 0F82BE000000        <1>         jb      update_cluster_inv_data
   668 000098BD 80FB02              <1> 	cmp	bl, 2 
   669 000098C0 0F877A010000        <1>         ja      update_fat32_cluster
   670                              <1> 	;cmp	bl, 1
   671                              <1> 	;jb	short update_cluster_inv_data
   672 000098C6 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   673 000098C9 41                  <1> 	inc	ecx  
   674 000098CA 890D[72DB0000]      <1> 	mov	[LastCluster], ecx
   675 000098D0 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   676 000098D2 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 000098D8 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   685 000098DB 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 000098E1 BB00030000          <1> 	mov	ebx, 300h ;768
   691 000098E6 F7F3                <1> 	div	ebx
   692                              <1> 	; EAX = Count of 3 FAT sectors
   693                              <1> 	; DX = Cluster offset in FAT buffer
   694 000098E8 6689D3              <1> 	mov	bx, dx  
   695 000098EB 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   696 000098EE 66BA0300            <1> 	mov	dx, 3
   697 000098F2 F7E2                <1> 	mul	edx  
   698                              <1> 	; EAX = FAT Sector
   699                              <1> 	; EDX = 0
   700                              <1> 	; EBX = Byte offset in FAT buffer
   701 000098F4 8A0D[66DB0000]      <1> 	mov	cl, [FAT_BuffValidData]
   702 000098FA 80F902              <1> 	cmp	cl, 2
   703 000098FD 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   704                              <1> 
   705                              <1> loc_uc_check_fat16_buff_sector_save:
   706 000098FF 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   707 00009905 755D                <1> 	jne	short loc_uc_save_fat_buffer
   708 00009907 EB15                <1> 	jmp	short loc_update_fat16_cell
   709                              <1> 
   710                              <1> loc_uc_check_fat16_buff_sector_load:
   711 00009909 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   712 0000990C 0F85FB010000        <1>         jne     loc_uc_load_fat_sectors
   713 00009912 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   714 00009918 0F85EF010000        <1>         jne     loc_uc_load_fat_sectors
   715                              <1> 
   716                              <1> loc_update_fat16_cell:
   717                              <1> loc_update_fat16_buffer:
   718 0000991E 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   719                              <1> 	;movzx	eax, word [ebx]
   720 00009924 668B03              <1> 	mov	ax, [ebx]
   721                              <1> 	; 01/03/2016
   722 00009927 89C2                <1> 	mov	edx, eax ; old value of the cluster
   723 00009929 A3[62DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   724 0000992E 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   725 00009934 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   726                              <1> 
   727 00009937 C605[66DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   728                              <1> 	
   729 0000993E 6683F802            <1> 	cmp	ax, 2
   730 00009942 723A                <1> 	jb	short return_uc_fat_stc
   731 00009944 3B05[72DB0000]      <1> 	cmp	eax, [LastCluster]
   732 0000994A 7732                <1> 	ja	short return_uc_fat_stc
   733                              <1> 
   734                              <1> loc_fat_buffer_updated:
   735                              <1> 	; 01/03/2016
   736 0000994C F8                  <1> 	clc
   737                              <1> loc_fat_buffer_stc_1:
   738 0000994D 9C                  <1> 	pushf
   739 0000994E 21C9                <1> 	and	ecx, ecx
   740 00009950 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 00009952 FF05[6EDB0000]      <1> 	inc	dword [FAT_ClusterCounter]
   746                              <1> 
   747                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   748 00009958 09D2                <1> 	or	edx, edx ; 02/03/2016
   749 0000995A 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 0000995C FF0D[6EDB0000]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   753                              <1> 
   754                              <1> loc_fat_buffer_updated_2:
   755 00009962 9D                  <1> 	popf
   756 00009963 C3                  <1> 	retn
   757                              <1> 
   758                              <1> loc_uc_save_fat_buffer:
   759                              <1> 	; byte [FAT_BuffValidData] = 2 
   760 00009964 E8D4010000          <1> 	call	save_fat_buffer
   761 00009969 0F8297010000        <1>         jc      loc_fat_sectors_rw_error2
   762                              <1> 	;mov	byte [FAT_BuffValidData], 1
   763 0000996F A1[62DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
   764                              <1> 	;mov	ecx, [ClusterValue]
   765                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   766 00009974 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   767 00009976 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   768                              <1> 
   769                              <1> update_cluster_inv_data:
   770                              <1> 	;mov	eax, 0Dh
   771 0000997B B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   772 0000997D C3                  <1> 	retn 
   773                              <1> 
   774                              <1> return_uc_fat_stc:
   775                              <1> 	; 01/03/2016
   776 0000997E 31C0                <1> 	xor	eax, eax
   777 00009980 F9                  <1> 	stc
   778 00009981 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 00009983 BB00040000          <1> 	mov	ebx, 400h ;1024
   784 00009988 F7F3                <1> 	div	ebx
   785                              <1> 	; EAX = Count of 3 FAT sectors
   786                              <1> 	; DX = Cluster offset in FAT buffer
   787 0000998A 66B90300            <1> 	mov	cx, 3
   788 0000998E 6689C3              <1> 	mov	bx, ax
   789 00009991 6689C8              <1> 	mov	ax, cx ; 3
   790 00009994 66F7E2              <1> 	mul	dx     ; Multiply by 3
   791 00009997 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   792 0000999A 6693                <1> 	xchg	bx, ax
   793                              <1> 	; EAX = Count of 3 FAT sectors
   794                              <1> 	; EBX = Byte Offset in FAT buffer   
   795 0000999C 66F7E1              <1> 	mul	cx  ; 3 * AX
   796                              <1> 	; EAX = FAT Beginning Sector
   797                              <1> 	; EDX = 0
   798 0000999F 8A0D[66DB0000]      <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 000099A5 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   803 000099A8 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   804                              <1> 
   805                              <1> loc_uc_check_fat12_buff_sector_save:
   806 000099AA 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   807 000099B0 75B2                <1>         jne     short loc_uc_save_fat_buffer
   808 000099B2 EB15                <1> 	jmp	short loc_update_fat12_cell
   809                              <1> 
   810                              <1> loc_uc_check_fat12_buff_sector_load:
   811 000099B4 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   812 000099B7 0F8550010000        <1>         jne     loc_uc_load_fat_sectors
   813 000099BD 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   814 000099C3 0F8544010000        <1>         jne     loc_uc_load_fat_sectors
   815                              <1> 
   816                              <1> loc_update_fat12_cell:
   817 000099C9 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   818 000099CF 668B0D[62DB0000]    <1> 	mov	cx, [FAT_CurrentCluster]
   819 000099D6 66D1E9              <1> 	shr	cx, 1
   820 000099D9 668B03              <1> 	mov	ax, [ebx]
   821 000099DC 6689C2              <1> 	mov	dx, ax
   822 000099DF 7344                <1> 	jnc	short uc_fat12_nc_even
   823                              <1> 
   824 000099E1 6683E00F            <1> 	and	ax, 0Fh
   825 000099E5 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   826 000099EB 66C1E104            <1> 	shl	cx, 4
   827 000099EF 6609C1              <1> 	or	cx, ax
   828 000099F2 6689D0              <1> 	mov	ax, dx
   829 000099F5 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   830 000099F8 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   831                              <1> 
   832                              <1> update_fat12_buffer:
   833 000099FC A3[62DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   834 00009A01 89C2                <1> 	mov	edx, eax ; 01/03/2016
   835 00009A03 C605[66DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   836 00009A0A 6683F802            <1> 	cmp	ax, 2
   837 00009A0E 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   838 00009A14 3B05[72DB0000]      <1> 	cmp	eax, [LastCluster]
   839 00009A1A 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   840 00009A20 E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   841                              <1> 
   842                              <1> uc_fat12_nc_even:
   843 00009A25 662500F0            <1> 	and	ax, 0F000h
   844 00009A29 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   845 00009A2F 80E50F              <1> 	and	ch, 0Fh
   846 00009A32 6609C1              <1> 	or	cx, ax
   847 00009A35 6689D0              <1> 	mov	ax, dx
   848 00009A38 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   849 00009A3B 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   850 00009A3E EBBC                <1> 	jmp	short update_fat12_buffer
   851                              <1> 
   852                              <1> update_fat32_cluster:
   853 00009A40 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   854 00009A43 41                  <1> 	inc	ecx
   855 00009A44 890D[72DB0000]      <1> 	mov	[LastCluster], ecx
   856                              <1> 
   857 00009A4A 39C8                <1> 	cmp	eax, ecx
   858 00009A4C 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   859                              <1> 
   860                              <1> pass_uc_fat32_errc:
   861                              <1> 	;sub	edx, edx
   862 00009A52 BB80010000          <1> 	mov	ebx, 180h ;384
   863 00009A57 F7F3                <1> 	div	ebx
   864                              <1> 	; EAX = Count of 3 FAT sectors
   865                              <1> 	; DX = Cluster offset in FAT buffer
   866 00009A59 89D3                <1> 	mov	ebx, edx
   867 00009A5B C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   868 00009A5E BA03000000          <1> 	mov	edx, 3	
   869 00009A63 F7E2                <1> 	mul	edx
   870                              <1> 	; EBX = Cluster Offset in FAT buffer
   871                              <1> 	; EAX = FAT Sector
   872                              <1> 	; EDX = 0
   873 00009A65 8A0D[66DB0000]      <1> 	mov	cl, [FAT_BuffValidData]
   874 00009A6B 80F902              <1> 	cmp	cl, 2
   875 00009A6E 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   876                              <1> 
   877                              <1> loc_uc_check_fat32_buff_sector_save:
   878 00009A70 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   879 00009A76 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   880 00009A7C EB11                <1> 	jmp	short loc_update_fat32_cell
   881                              <1> 
   882                              <1> loc_uc_check_fat32_buff_sector_load:
   883 00009A7E 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   884 00009A81 0F8586000000        <1>         jne     loc_uc_load_fat_sectors
   885 00009A87 3B05[6ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   886 00009A8D 757E                <1>         jne     loc_uc_load_fat_sectors
   887                              <1> 
   888                              <1> loc_update_fat32_cell:
   889                              <1> loc_update_fat32_buffer:
   890 00009A8F 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   891 00009A95 8B03                <1> 	mov	eax, [ebx]
   892 00009A97 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   893                              <1> 	
   894 00009A9C 8B15[62DB0000]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   895                              <1> 
   896 00009AA2 A3[62DB0000]        <1> 	mov 	[FAT_CurrentCluster], eax
   897 00009AA7 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue]
   898 00009AAD 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   899                              <1> 
   900 00009AAF C605[66DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   901                              <1> 
   902                              <1> 	; 01/03/2016
   903 00009AB6 21C0                <1> 	and	eax, eax ; was it free cluster ?
   904 00009AB8 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 00009ABA 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   910 00009ABD 7520                <1> 	jne	short loc_upd_fat32_c3
   911                              <1> 
   912 00009ABF 3B15[72DB0000]      <1> 	cmp	edx, [LastCluster]
   913 00009AC5 7207                <1> 	jb	short loc_upd_fat32_c0
   914                              <1> 
   915 00009AC7 BA02000000          <1> 	mov	edx, 2 ; rewind !
   916 00009ACC EB0E                <1> 	jmp	short loc_upd_fat32_c2
   917                              <1> 
   918                              <1> loc_upd_fat32_c0:
   919 00009ACE FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   920 00009AD1 EB0C                <1> 	jmp	short loc_upd_fat32_c3
   921                              <1> 
   922                              <1> loc_upd_fat32_c1:
   923 00009AD3 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   924 00009AD5 7508                <1> 	jnz	short loc_upd_fat32_c3
   925                              <1> 
   926 00009AD7 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   927 00009ADA 7303                <1> 	jnb	short loc_upd_fat32_c3
   928                              <1> 
   929                              <1> loc_upd_fat32_c2:	
   930 00009ADC 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   931                              <1> 
   932                              <1> loc_upd_fat32_c3:
   933 00009ADF 89C2                <1> 	mov	edx, eax
   934                              <1> 
   935                              <1> loc_upd_fat32_c4:
   936 00009AE1 83F802              <1> 	cmp	eax, 2
   937 00009AE4 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   938                              <1> 
   939                              <1> pass_uc_fat32_c_zero_check_2:
   940 00009AEA 3B05[72DB0000]      <1> 	cmp	eax, [LastCluster]
   941 00009AF0 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   942                              <1> 	
   943 00009AF6 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 00009AFB B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   949 00009B00 8825[66DB0000]      <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 00009B06 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue]
   955 00009B0C C3                  <1> 	retn
   956                              <1> 
   957                              <1> loc_uc_load_fat_sectors:
   958 00009B0D A3[6ADB0000]        <1> 	mov	[FAT_BuffSector], eax
   959                              <1> 
   960                              <1> load_uc_fat_sectors_zero:
   961 00009B12 034660              <1> 	add	eax, [esi+LD_FATBegin]
   962 00009B15 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   963 00009B1A B903000000          <1> 	mov	ecx, 3
   964 00009B1F E8DE220000          <1> 	call	disk_read
   965 00009B24 72D5                <1> 	jc	short loc_fat_sectors_rw_error1
   966                              <1> 
   967 00009B26 C605[66DB0000]01    <1>         mov     byte [FAT_BuffValidData], 1
   968 00009B2D A1[62DB0000]        <1> 	mov 	eax, [FAT_CurrentCluster]
   969 00009B32 8B0D[04DE0000]      <1> 	mov	ecx, [ClusterValue]
   970 00009B38 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 00009B3D 31D2                <1> 	xor	edx, edx
   996 00009B3F 8A35[67DB0000]      <1> 	mov	dh, [FAT_BuffDrvName]
   997 00009B45 80FE41              <1> 	cmp	dh, 'A'
   998 00009B48 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
   999 00009B4A 80EE41              <1> 	sub	dh, 'A'
  1000 00009B4D 56                  <1> 	push	esi ; *
  1001 00009B4E BE00010900          <1>         mov     esi, Logical_DOSDisks
  1002 00009B53 01D6                <1> 	add	esi, edx
  1003                              <1> 	
  1004 00009B55 8A5603              <1> 	mov	dl, [esi+LD_FATType]
  1005 00009B58 20D2                <1> 	and	dl, dl
  1006 00009B5A 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
  1007                              <1> 
  1008 00009B5C A1[6ADB0000]        <1> 	mov	eax, [FAT_BuffSector]
  1009 00009B61 80FA02              <1> 	cmp	dl, 2
  1010 00009B64 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 00009B66 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
  1019 00009B6A 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 00009B6C 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1023 00009B6E EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1024                              <1> 
  1025                              <1> loc_save_fat32_buff:
  1026 00009B70 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1027 00009B73 29C1                <1> 	sub	ecx, eax
  1028 00009B75 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1029                              <1> 
  1030                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1031 00009B77 5E                  <1> 	pop	esi ; *
  1032                              <1> loc_save_fat_buffer_inv_data_retn:
  1033 00009B78 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1034 00009B7D C3                  <1> 	retn
  1035                              <1> 
  1036                              <1> loc_save_fat_buff_remain_sectors_3:
  1037 00009B7E B903000000          <1> 	mov	ecx, 3
  1038 00009B83 EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1039                              <1> 
  1040                              <1> loc_save_fat_buffer_check_rs3:
  1041 00009B85 83F903              <1> 	cmp	ecx, 3
  1042 00009B88 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1043                              <1> 
  1044                              <1> loc_save_fat_buff_continue:
  1045 00009B8A BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1046 00009B8F 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1047 00009B92 51                  <1> 	push	ecx
  1048 00009B93 E85B220000          <1> 	call	disk_write
  1049 00009B98 59                  <1> 	pop	ecx
  1050 00009B99 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1051                              <1> 	
  1052 00009B9B 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1053 00009B9F 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1054                              <1> 
  1055                              <1> loc_calc_2nd_fat32_addr:
  1056 00009BA1 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1057 00009BA4 EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1058                              <1> 
  1059                              <1> loc_calc_2nd_fat12_16_addr:
  1060 00009BA6 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1061                              <1> 
  1062                              <1> loc_calc_2nd_fat_addr:
  1063 00009BAA 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1064 00009BAD 0305[6ADB0000]      <1> 	add	eax, [FAT_BuffSector]
  1065 00009BB3 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1066                              <1> 	; ecx = 1 to 3
  1067 00009BB8 E836220000          <1> 	call	disk_write
  1068 00009BBD 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1069                              <1>  	; Valid  buffer (1 = valid but do not save)
  1070 00009BBF C605[66DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1071                              <1> 
  1072                              <1> loc_save_FAT_buff_write_err:
  1073 00009BC6 5E                  <1> 	pop	esi ; *
  1074 00009BC7 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1075                              <1> 	; 23/03/2016
  1076 00009BCC B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
  1077 00009BD1 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 00009BD2 66891D[0ADE0000]    <1> 	mov	[CFS_OPType], bx
  1105 00009BD9 A3[0CDE0000]        <1> 	mov	[CFS_CC], eax
  1106                              <1> 	
  1107 00009BDE 80FFFF              <1> 	cmp	bh, 0FFh
  1108 00009BE1 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1109                              <1> 
  1110                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1111 00009BE3 31C0                <1> 	xor	eax, eax
  1112 00009BE5 88FC                <1>         mov     ah, bh
  1113 00009BE7 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1114 00009BEC 01C6                <1>         add     esi, eax
  1115                              <1> 
  1116                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1117 00009BEE 08DB                <1> 	or	bl, bl
  1118 00009BF0 7435                <1> 	jz	short loc_reset_fcc
  1119                              <1> 	
  1120                              <1> loc_get_free_sectors:
  1121 00009BF2 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 00009BF5 8B4E70              <1> 	mov	ecx, [esi+LD_TotalSectors]
  1130 00009BF8 39C1                <1> 	cmp	ecx, eax ; Total sectors must be greater than Free sectors !
  1131 00009BFA 7707                <1> 	ja	short loc_get_free_sectors_check_optype
  1132                              <1> 	
  1133 00009BFC 31C0                <1> 	xor	eax, eax
  1134 00009BFE 48                  <1> 	dec	eax ; 0FFFFFFFFh  ; recalculation is needed!
  1135 00009BFF 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; reset (for recalculation)
  1136                              <1> 		
  1137                              <1> loc_get_free_sectors_retn:
  1138 00009C02 C3                  <1> 	retn
  1139                              <1> 	
  1140                              <1> loc_get_free_sectors_check_optype:
  1141 00009C03 80FB03              <1> 	cmp	bl, 3
  1142 00009C06 7203                <1> 	jb	short loc_set_fcc
  1143                              <1> 
  1144 00009C08 29C9                <1> 	sub	ecx, ecx ; 0
  1145                              <1> 
  1146 00009C0A C3                  <1> 	retn	
  1147                              <1> 
  1148                              <1> loc_set_fcc:
  1149 00009C0B 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1150 00009C0F 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1151                              <1> 
  1152                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1153 00009C15 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1154 00009C19 29D2                <1> 	sub	edx, edx
  1155 00009C1B 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 00009C1D A3[83DB0000]        <1> 	mov	[FreeClusterCount], eax
  1163 00009C22 E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1164                              <1> 
  1165                              <1> loc_reset_fcc:
  1166 00009C27 31C0                <1> 	xor	eax, eax
  1167 00009C29 A3[83DB0000]        <1> 	mov	[FreeClusterCount], eax ; 0
  1168 00009C2E 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1169 00009C31 42                  <1> 	inc	edx
  1170 00009C32 8915[72DB0000]      <1> 	mov	[LastCluster], edx
  1171                              <1> 
  1172 00009C38 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1173 00009C3C 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1174                              <1> 
  1175 00009C3E 48                  <1> 	dec	eax ; FFFFFFFFh
  1176 00009C3F A3[14DE0000]        <1> 	mov	[CFS_FAT32FC], eax
  1177                              <1> 
  1178                              <1> 	; 29/02/2016
  1179 00009C44 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1180 00009C47 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1181                              <1> 	
  1182 00009C4A B802000000          <1> 	mov 	eax, 2
  1183                              <1> 
  1184                              <1> loc_count_fc_next_cluster_0:
  1185 00009C4F 50                  <1> 	push	eax
  1186 00009C50 E801F9FFFF          <1> 	call	get_next_cluster
  1187 00009C55 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1188 00009C57 09C0                <1> 	or	eax, eax
  1189 00009C59 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1190                              <1> 
  1191                              <1> loc_put_fcc_unknown_sign:
  1192 00009C5B 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 00009C5C 8B15[14DE0000]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1200                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1201 00009C62 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1202                              <1> 	
  1203 00009C65 EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1204                              <1> 
  1205                              <1> loc_check_fat32_ff_cluster:
  1206 00009C67 09C0                <1> 	or	eax, eax
  1207 00009C69 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1208 00009C6B 58                  <1> 	pop	eax
  1209 00009C6C A3[14DE0000]        <1> 	mov	[CFS_FAT32FC], eax
  1210                              <1> 	;mov	dword [FreeClusterCount], 1
  1211 00009C71 FF05[83DB0000]      <1> 	inc	dword [FreeClusterCount]
  1212 00009C77 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1213                              <1> 
  1214                              <1> pass_inc_cfs_fcc_0:
  1215 00009C79 58                  <1> 	pop	eax
  1216                              <1> 
  1217                              <1> pass_inc_cfs_fcc_0c:
  1218 00009C7A 40                  <1> 	inc	eax ; add eax, 1
  1219 00009C7B 3B05[72DB0000]      <1> 	cmp	eax, [LastCluster]
  1220 00009C81 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1221 00009C83 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 00009C85 B002                <1> 	mov	al, 2
  1226                              <1> 
  1227                              <1> loc_count_fc_next_cluster:
  1228 00009C87 50                  <1> 	push	eax
  1229 00009C88 E8C9F8FFFF          <1> 	call	get_next_cluster
  1230 00009C8D 720C                <1> 	jc	short loc_count_fcc_stc
  1231                              <1> 
  1232                              <1> loc_count_free_clusters_1:
  1233 00009C8F 21C0                <1> 	and	eax, eax
  1234 00009C91 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1235                              <1> 
  1236 00009C93 FF05[83DB0000]      <1> 	inc	dword [FreeClusterCount]
  1237 00009C99 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1238                              <1> 
  1239                              <1> loc_count_fcc_stc:
  1240 00009C9B 09C0                <1> 	or	eax, eax
  1241 00009C9D 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1242                              <1> 
  1243                              <1> pass_inc_cfs_fcc:
  1244 00009C9F 58                  <1> 	pop	eax
  1245                              <1> 
  1246                              <1> pass_inc_cfs_fcc_1:
  1247 00009CA0 40                  <1> 	inc	eax ; add eax, 1
  1248 00009CA1 3B05[72DB0000]      <1> 	cmp	eax, [LastCluster]
  1249 00009CA7 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1250                              <1> 
  1251                              <1> loc_set_free_sectors:
  1252 00009CA9 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1253 00009CAD 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1254                              <1> 
  1255                              <1> loc_set_free_sectors_FAT12_FAT16:
  1256 00009CAF 803D[0ADE0000]00    <1> 	cmp	byte [CFS_OPType], 0
  1257 00009CB6 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1258 00009CB8 A1[0CDE0000]        <1> 	mov	eax, [CFS_CC]
  1259 00009CBD 803D[0ADE0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1260 00009CC4 7708                <1> 	ja	short pass_FAT_add_fcc
  1261 00009CC6 0105[83DB0000]      <1> 	add 	[FreeClusterCount], eax
  1262 00009CCC EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1263                              <1> 
  1264                              <1> pass_FAT_add_fcc:
  1265 00009CCE 2905[83DB0000]      <1> 	sub	[FreeClusterCount], eax
  1266                              <1> 
  1267                              <1> pass_FAT_add_sub_fcc:
  1268 00009CD4 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1269 00009CD8 8B15[83DB0000]      <1> 	mov	edx, [FreeClusterCount]
  1270 00009CDE F7E2                <1> 	mul	edx
  1271                              <1> 
  1272 00009CE0 31C9                <1> 	xor	ecx, ecx 
  1273 00009CE2 EB05                <1> 	jmp	short loc_cfs_retn_params
  1274                              <1> 
  1275                              <1> loc_put_fcc_invalid_sign:
  1276 00009CE4 29C0                <1>        	sub	eax, eax ; 0
  1277 00009CE6 48                  <1> 	dec	eax ; FFFFFFFFh
  1278                              <1> loc_fat32_ffc_recalc_needed:
  1279 00009CE7 89C1                <1> 	mov	ecx, eax
  1280                              <1> 
  1281                              <1> loc_cfs_retn_params:
  1282 00009CE9 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1283 00009CEC 0FB71D[0ADE0000]    <1> 	movzx	ebx, word [CFS_OPType]
  1284 00009CF3 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 00009CF4 803D[0ADE0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1292 00009CFB 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1293 00009CFD 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1294                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1295 00009CFF F71D[0CDE0000]      <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 00009D05 31D2                <1> 	xor	edx, edx ; 0
  1299 00009D07 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1300 00009D08 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1301 00009D0B 39D0                <1> 	cmp	eax, edx
  1302 00009D0D 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1303 00009D0F 0305[0CDE0000]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1304 00009D15 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1305                              <1> 	
  1306 00009D17 A3[83DB0000]        <1> 	mov	[FreeClusterCount], eax
  1307 00009D1C EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1308                              <1> 
  1309                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1310 00009D1E 8B15[14DE0000]      <1> 	mov	edx, [CFS_FAT32FC]
  1311 00009D24 A1[83DB0000]        <1> 	mov	eax, [FreeClusterCount]
  1312 00009D29 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1313                              <1> loc_cfs_write_FSINFO_sector:
  1314 00009D2C 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1315                              <1> 	; 01/03/2016
  1316 00009D2F E89A000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1317 00009D34 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 00009D36 8B0D[83DB0000]      <1> 	mov	ecx, [FreeClusterCount]
  1327 00009D3C 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1328 00009D40 F7E1                <1> 	mul	ecx
  1329                              <1> 	; 29/02/2016
  1330 00009D42 31C9                <1> 	xor	ecx, ecx ; 0
  1331 00009D44 09D2                <1> 	or	edx, edx ; 0 ?
  1332 00009D46 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1333 00009D48 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1334 00009D4B 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1335                              <1> 	;
  1336                              <1> loc_set_FAT32_free_sectors_ok:
  1337 00009D4D 31D2                <1> 	xor	edx, edx ; 0
  1338 00009D4F 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 00009D51 89C1                <1> 	mov	ecx, eax	
  1357                              <1> 
  1358                              <1> loc_glc_get_next_cluster_1:
  1359 00009D53 890D[18DE0000]      <1> 	mov	[glc_prevcluster], ecx
  1360                              <1> 
  1361                              <1> loc_glc_get_next_cluster_2:
  1362 00009D59 E8F8F7FFFF          <1> 	call	get_next_cluster
  1363                              <1> 	; ecx = current/previous cluster 
  1364                              <1> 	; eax = next/last cluster
  1365 00009D5E 73F3                <1> 	jnc	short loc_glc_get_next_cluster_1
  1366                              <1> 
  1367 00009D60 09C0                <1> 	or	eax, eax
  1368 00009D62 7509                <1> 	jnz	short loc_glc_stc_retn
  1369                              <1> 
  1370                              <1> 	; ecx = previous cluster
  1371 00009D64 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 00009D66 8B0D[18DE0000]      <1> 	mov	ecx, [glc_prevcluster] 
  1378 00009D6C C3                  <1> 	retn
  1379                              <1> 
  1380                              <1> loc_glc_stc_retn:
  1381 00009D6D F5                  <1> 	cmc	;stc
  1382 00009D6E 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 00009D70 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1402                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1403 00009D72 890D[6EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1404                              <1> 
  1405                              <1> loc_tcc_unlink_clusters:
  1406 00009D78 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 00009D7D 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1413                              <1> 
  1414                              <1> pass_tcc_unlink_clusters:
  1415 00009D7F A2[1FDE0000]        <1> 	mov	byte [TCC_FATErr], al
  1416 00009D84 803D[66DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1417 00009D8B 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1418 00009D8D E8ABFDFFFF          <1> 	call	save_fat_buffer
  1419 00009D92 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1420 00009D94 A2[1FDE0000]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1421                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1422                              <1> 
  1423                              <1> 	; 01/03/2016
  1424 00009D99 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1425                              <1> 
  1426                              <1> loc_tcc_calculate_FAT_freespace:
  1427 00009D9B A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1428 00009DA0 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1429                              <1> 			   ; BL = 1 -> add cluster
  1430 00009DA4 E829FEFFFF          <1> 	call	calculate_fat_freespace
  1431 00009DA9 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1432 00009DAB 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1433                              <1> 
  1434                              <1> loc_tcc_recalculate_FAT_freespace:
  1435 00009DAD 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1436 00009DB1 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 00009DB6 8B0D[6EDB0000]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1441                              <1> 
  1442 00009DBC 803D[1FDE0000]00    <1> 	cmp	byte [TCC_FATErr], 0
  1443 00009DC3 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1444                              <1> 
  1445                              <1> loc_tcc_unlink_clusters_error:
  1446 00009DC5 0FB605[1FDE0000]    <1> 	movzx	eax, byte [TCC_FATErr]
  1447 00009DCC F9                  <1> 	stc
  1448                              <1> loc_tcc_unlink_clusters_retn:
  1449 00009DCD 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 00009DCE E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1466 00009DD3 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1467                              <1> 
  1468 00009DD5 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1469 00009DD8 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1470                              <1> 
  1471                              <1>         ;mov	ebx, DOSBootSectorBuff
  1472 00009DDB 8983E8010000        <1> 	mov	[ebx+488], eax
  1473 00009DE1 8993EC010000        <1> 	mov	[ebx+492], edx	
  1474                              <1> 
  1475 00009DE7 A1[10DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1476 00009DEC B901000000          <1> 	mov	ecx, 1
  1477 00009DF1 E8FD1F0000          <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 00009DF6 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 00009DF7 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1507 00009DFB 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1508 00009DFE A3[10DE0000]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1509                              <1> 	
  1510 00009E03 BB[62D90000]        <1>         mov     ebx, DOSBootSectorBuff
  1511 00009E08 B901000000          <1> 	mov	ecx, 1
  1512 00009E0D E8F01F0000          <1> 	call	disk_read
  1513 00009E12 7232                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1514                              <1> 
  1515 00009E14 BB[62D90000]        <1> 	mov	ebx, DOSBootSectorBuff
  1516                              <1> 
  1517 00009E19 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1518 00009E1F 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1519                              <1> 
  1520 00009E21 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1520 00009E2A 61                  <1>
  1521 00009E2B 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1522                              <1> 
  1523 00009E2D A1[10DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1524 00009E32 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1525 00009E38 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1526                              <1> 
  1527 00009E3E C3                  <1> 	retn
  1528                              <1> 
  1529                              <1> loc_read_FAT32_fsinfo_sec_stc:
  1530 00009E3F B80B000000          <1> 	mov	eax, 0Bh ; Invalid format!
  1531 00009E44 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 00009E46 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
  1536                              <1> 
  1537                              <1> loc_read_FAT32_fsinfo_sec_stc_retn:
  1538 00009E4B 29DB                <1> 	sub	ebx, ebx ; 0
  1539 00009E4D F9                  <1> 	stc
  1540 00009E4E C3                  <1> 	retn
  1541                              <1> 
  1542                              <1> add_new_cluster:
  1543                              <1> 	; 16/05/2016
  1544                              <1> 	; 24/03/2016
  1545                              <1> 	; 18/03/2016
  1546                              <1> 	; 11/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1547                              <1> 	; 30/07/2011 (DRV_FAT.ASM)
  1548                              <1> 	; 11/09/2010
  1549                              <1> 	; INPUT ->
  1550                              <1> 	;	ESI = Logical dos drv desc. table address
  1551                              <1> 	;	EAX = Last cluster
  1552                              <1> 	; OUTPUT ->
  1553                              <1> 	;	ESI = Logical dos drv desc. table address
  1554                              <1> 	;	EAX = New Last cluster (next cluster)
  1555                              <1> 	;	cf = 1 -> error code in EAX (AL)
  1556                              <1> 	;	cf = 1 -> DX = sectors per cluster
  1557                              <1> 	;	ECX = Free sectors
  1558                              <1> 	; NOTE:
  1559                              <1> 	; This procedure does not update lm date&time !
  1560                              <1> 	;
  1561                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, EDI)
  1562                              <1> 	;
  1563                              <1> 
  1564 00009E4F A3[3CDF0000]        <1> 	mov	[FAT_anc_LCluster], eax
  1565                              <1> 	
  1566 00009E54 E854F9FFFF          <1> 	call	get_first_free_cluster
  1567 00009E59 720B                <1> 	jc	short loc_add_new_cluster_retn
  1568                              <1> 	; EAX >= 2 and EAX < FFFFFFFFh is valid
  1569                              <1> 
  1570 00009E5B 89C2                <1> 	mov	edx, eax
  1571                              <1> 
  1572 00009E5D 42                  <1> 	inc	edx
  1573                              <1> 	;jnz	short loc_add_new_cluster_check_ffc_eax
  1574 00009E5E 7516                <1> 	jnz	short loc_add_new_cluster_save_fcc
  1575                              <1> 
  1576                              <1> loc_add_new_cluster_no_disk_space_retn:
  1577 00009E60 B827000000          <1> 	mov	eax, 27h ; MSDOS err => insufficient disk space
  1578                              <1> loc_add_new_cluster_stc_retn:
  1579 00009E65 F9                  <1> 	stc
  1580                              <1> loc_add_new_cluster_retn:
  1581 00009E66 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1582 00009E6A 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1583                              <1> 	;xor	edx, edx
  1584                              <1> 	;stc
  1585 00009E6D C3                  <1> 	retn
  1586                              <1> 
  1587                              <1> loc_anc_invalid_format_stc_retn:
  1588 00009E6E F9                  <1> 	stc
  1589                              <1> loc_add_new_cluster_invalid_format_retn:
  1590 00009E6F B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  1591 00009E74 EBF0                <1> 	jmp	short loc_add_new_cluster_retn 
  1592                              <1> 
  1593                              <1> ;loc_add_new_cluster_check_ffc_eax:
  1594                              <1> ;	cmp	eax, 2
  1595                              <1> ;	jb	short loc_add_new_cluster_invalid_format_retn
  1596                              <1> 
  1597                              <1> loc_add_new_cluster_save_fcc:  
  1598 00009E76 A3[40DF0000]        <1> 	mov	[FAT_anc_FFCluster], eax
  1599                              <1> 
  1600 00009E7B 83E802              <1> 	sub	eax, 2
  1601 00009E7E 0FB65E13            <1>         movzx   ebx, byte [esi+LD_BPB+SecPerClust]
  1602 00009E82 F7E3                <1> 	mul	ebx
  1603 00009E84 09D2                <1> 	or	edx, edx
  1604 00009E86 75E6                <1> 	jnz	short loc_anc_invalid_format_stc_retn
  1605                              <1> 
  1606                              <1> loc_add_new_cluster_allocate_cluster:
  1607                              <1> 	; 18/03/2016
  1608 00009E88 92                  <1> 	xchg	edx, eax ; eax = 0
  1609                              <1> 	; 16/05/2016
  1610                              <1> 	;cmp	[ClusterBuffer_Valid], al ; 0
  1611                              <1> 	;jna	short loc_anc_clear_cluster_buffer
  1612                              <1> 	;; 'copy' command, 
  1613                              <1> 	;; writing destination file clust after reading source file clust
  1614                              <1> 	;mov	[ClusterBuffer_Valid], al ; 0 ; reset
  1615                              <1> 	;jmp	short loc_add_new_cluster_write_nc_to_disk
  1616                              <1> 
  1617                              <1> loc_anc_clear_cluster_buffer:
  1618                              <1> 	; 11/03/2016
  1619                              <1> 	; Clear buffer
  1620 00009E89 BF00000700          <1> 	mov	edi, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  1621 00009E8E 89D9                <1> 	mov	ecx, ebx ; sector count
  1622 00009E90 C1E107              <1> 	shl	ecx, 7 ; 1 sector = 512 bytes -> 128 double words
  1623                              <1> 	;xor	eax, eax ; 0
  1624 00009E93 F3AB                <1> 	rep	stosd
  1625                              <1> 
  1626                              <1> loc_add_new_cluster_write_nc_to_disk:
  1627                              <1> 	; 11/03/2016
  1628                              <1> 	;xchg	eax, edx ; edx = 0, eax = sector offset
  1629 00009E95 89D0                <1> 	mov	eax, edx
  1630 00009E97 034668              <1>         add     eax, [esi+LD_DATABegin]
  1631 00009E9A 72D3                <1> 	jc	short loc_add_new_cluster_invalid_format_retn 
  1632                              <1> 		
  1633 00009E9C 89D9                <1> 	mov	ecx, ebx ; ECX = sectors per cluster (<256)
  1634 00009E9E BB00000700          <1> 	mov	ebx, Cluster_Buffer
  1635 00009EA3 E84B1F0000          <1> 	call	disk_write
  1636 00009EA8 7307                <1> 	jnc	short loc_add_new_cluster_update_fat_nlc
  1637                              <1> 	
  1638 00009EAA B81D000000          <1> 	mov	eax, 1Dh ; Write Error
  1639 00009EAF EBB4                <1> 	jmp	short loc_add_new_cluster_stc_retn
  1640                              <1> 
  1641                              <1> loc_add_new_cluster_update_fat_nlc:
  1642 00009EB1 A1[40DF0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1643 00009EB6 31C9                <1> 	xor	ecx, ecx
  1644 00009EB8 890D[6EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1645 00009EBE 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1646 00009EBF E8BCF9FFFF          <1> 	call	update_cluster
  1647 00009EC4 7304                <1> 	jnc	short loc_add_new_cluster_update_fat_plc
  1648 00009EC6 09C0                <1> 	or	eax, eax ;EAX = 0 -> cluster value is 0 or eocc
  1649 00009EC8 759B                <1> 	jnz	short loc_add_new_cluster_stc_retn
  1650                              <1> 
  1651                              <1> loc_add_new_cluster_update_fat_plc:
  1652 00009ECA A1[3CDF0000]        <1> 	mov	eax, [FAT_anc_LCluster]
  1653 00009ECF 8B0D[40DF0000]      <1> 	mov	ecx, [FAT_anc_FFCluster]
  1654 00009ED5 E8A6F9FFFF          <1> 	call	update_cluster
  1655 00009EDA 7314                <1> 	jnc	short loc_add_new_cluster_save_fat_buffer
  1656 00009EDC 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1657 00009EDE 7410                <1> 	jz	short loc_add_new_cluster_save_fat_buffer
  1658                              <1> 
  1659                              <1> loc_anc_save_fat_buffer_err_retn:
  1660                              <1> 	;cmp	byte [FAT_ClusterCounter], 1
  1661                              <1> 	;jb	short loc_add_new_cluster_retn
  1662                              <1> 
  1663 00009EE0 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1664                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1665 00009EE4 50                  <1> 	push	eax
  1666 00009EE5 E8E8FCFFFF          <1> 	call	calculate_fat_freespace
  1667 00009EEA 58                  <1> 	pop	eax
  1668 00009EEB E975FFFFFF          <1>         jmp     loc_add_new_cluster_stc_retn
  1669                              <1> 
  1670                              <1> loc_add_new_cluster_save_fat_buffer:
  1671                              <1> 	;cmp	byte [FAT_BuffValidData], 2
  1672                              <1> 	;jne	short loc_add_new_cluster_calc_FAT_freespace 
  1673                              <1> 	;Byte [FAT_BuffValidData] =  2 
  1674 00009EF0 E848FCFFFF          <1> 	call	save_fat_buffer
  1675 00009EF5 72E9                <1> 	jc	short loc_anc_save_fat_buffer_err_retn
  1676                              <1> 
  1677                              <1> loc_add_new_cluster_calc_FAT_freespace:
  1678                              <1> 	;mov	eax, 1 ; Only one Cluster
  1679 00009EF7 A1[6EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1680 00009EFC 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI -> Dos drv desc. table
  1681                              <1> 		; BL = 1 -> add cluster
  1682 00009F00 B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  1683                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  1684                              <1> 	; (Free Cluster Count is decreased when EAX value is negative)
  1685 00009F02 E8CBFCFFFF          <1>         call    calculate_fat_freespace
  1686                              <1> 	;ECX = 0 -> no error, ECX > 0 -> error or invalid return
  1687 00009F07 21C9                <1> 	and	ecx, ecx ; ECX = 0 -> valid free sector count
  1688 00009F09 7409                <1> 	jz	short loc_add_new_cluster_return_cluster_number
  1689                              <1> 
  1690                              <1> loc_add_new_cluster_recalc_FAT_freespace:
  1691 00009F0B 66BB00FF            <1> 	mov	bx, 0FF00h  ; recalculate free space
  1692 00009F0F E8BEFCFFFF          <1>         call    calculate_fat_freespace
  1693                              <1> 	; cf = 0
  1694                              <1> loc_add_new_cluster_return_cluster_number:
  1695 00009F14 89C1                <1> 	mov	ecx, eax ; Free sector count
  1696 00009F16 A1[40DF0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1697 00009F1B 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1698                              <1> 	;mov	edi, Cluster_Buffer
  1699 00009F1F 31D2                <1> 	xor	edx, edx
  1700 00009F21 C3                  <1>         retn
  1701                              <1> 
  1702                              <1> write_cluster:
  1703                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1704                              <1> 	;
  1705                              <1> 	; INPUT ->
  1706                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
  1707                              <1> 	;	ESI = Logical DOS Drive Description Table address
  1708                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
  1709                              <1> 	;	Only for SINGLIX FS:
  1710                              <1> 	;	EDX = File Number (The 1st FDT address) 
  1711                              <1> 	; OUTPUT ->
  1712                              <1> 	;	cf = 1 -> Cluster can not be written onto disk
  1713                              <1> 	;	    EAX > 0 -> Error number
  1714                              <1> 	;	cf = 0 -> Cluster has been written successfully
  1715                              <1> 	;
  1716                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1717                              <1> 	
  1718 00009F22 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
  1719                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  1720                              <1> 
  1721                              <1> write_file_sectors: ; 16/03/2016
  1722 00009F26 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  1723 00009F2A 761C                <1> 	jna	short write_fs_cluster
  1724                              <1> 
  1725                              <1> write_fat_file_sectors: 
  1726 00009F2C 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
  1727 00009F2F 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
  1728 00009F33 F7E2                <1> 	mul	edx
  1729 00009F35 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
  1730                              <1> 
  1731                              <1> 	; EAX = Disk sector address
  1732                              <1> 	; ECX = Sector count
  1733                              <1> 	; EBX = Buffer address
  1734                              <1> 	; (EDX = 0)
  1735                              <1> 	; ESI = Logical DOS drive description table address	
  1736                              <1> 
  1737 00009F38 E8B61E0000          <1> 	call	disk_write
  1738 00009F3D 7306                <1> 	jnc	short wclust_retn
  1739                              <1> 	
  1740 00009F3F B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  1741 00009F44 C3                  <1> 	retn
  1742                              <1> 
  1743                              <1> wclust_retn:
  1744 00009F45 29C0                <1> 	sub	eax, eax ; 0
  1745 00009F47 C3                  <1> 	retn
  1746                              <1> 
  1747                              <1> write_fs_cluster:
  1748                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1749                              <1> 	; Singlix FS
  1750                              <1> 	
  1751                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
  1752                              <1> 	
  1753                              <1> 	; EDX = File number is the first File Descriptor Table address 
  1754                              <1> 	;	of the file. (Absolute address of the FDT).
  1755                              <1> 	
  1756                              <1> 	; eax = sector index (0 for the first sector)
  1757                              <1> 	; edx = FDT0 address
  1758                              <1> 		; 64 KB buffer = 128 sectors (limit) 
  1759 00009F48 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
  1760 00009F4D E801000000          <1> 	call	write_fs_sectors
  1761 00009F52 C3                  <1> 	retn
  1762                              <1> 
  1763                              <1> write_fs_sectors:
  1764                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1765 00009F53 F9                  <1> 	stc
  1766 00009F54 C3                  <1> 	retn
  1767                              <1> 
  1768                              <1> get_cluster_by_index:
  1769                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1770                              <1> 	; INPUT ->
  1771                              <1> 	; 	EAX = Beginning cluster
  1772                              <1> 	; 	EDX = Sector index in disk/file section
  1773                              <1> 	;	      (Only for SINGLIX file system!)
  1774                              <1> 	; 	ECX = Cluster sequence number after the beginning cluster
  1775                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1776                              <1> 	; OUTPUT ->
  1777                              <1> 	;	EAX = Cluster number 
  1778                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1779                              <1> 	;
  1780                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1781                              <1> 	;	
  1782 00009F55 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1783 00009F59 721E                <1>         jb      get_fs_section_by_index 
  1784                              <1> 
  1785 00009F5B 3B4E78              <1> 	cmp	ecx, [esi+LD_Clusters]
  1786 00009F5E 7207                <1> 	jb	short gcbi_1
  1787                              <1> gcbi_0:
  1788 00009F60 F9                  <1> 	stc
  1789 00009F61 B823000000          <1> 	mov	eax, 23h ; Cluster not available ! 
  1790                              <1> 			 ; MSDOS error code: FCB unavailable
  1791 00009F66 C3                  <1> 	retn
  1792                              <1> gcbi_1:
  1793 00009F67 51                  <1> 	push	ecx
  1794 00009F68 E8E9F5FFFF          <1> 	call	get_next_cluster
  1795 00009F6D 59                  <1> 	pop	ecx
  1796 00009F6E 7203                <1> 	jc	short gcbi_3
  1797 00009F70 E2F5                <1> 	loop	gcbi_1
  1798                              <1> gcbi_2:
  1799 00009F72 C3                  <1> 	retn
  1800                              <1> gcbi_3:
  1801 00009F73 09C0                <1> 	or	eax, eax
  1802 00009F75 74E9                <1> 	jz	short gcbi_0
  1803 00009F77 F5                  <1> 	cmc 	; stc
  1804 00009F78 C3                  <1> 	retn
  1805                              <1> 
  1806                              <1> get_fs_section_by_index:
  1807                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1808                              <1> 	; INPUT ->
  1809                              <1> 	; 	EAX = Beginning FDT number/address
  1810                              <1> 	; 	EDX = Sector index in disk/file section
  1811                              <1> 	; 	ECX = Sector sequence number after the beginning FDT
  1812                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1813                              <1> 	; OUTPUT ->
  1814                              <1> 	; 	EAX = FDT number/address
  1815                              <1> 	; 	EDX = Sector index from FDT sector (0,1,2,3,4...)
  1816                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1817                              <1> 	;
  1818                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1819                              <1> 	;
  1820 00009F79 B8FFFFFFFF          <1> 	mov	eax, 0FFFFFFFFh
  1821 00009F7E C3                  <1> 	retn
  1882                                  %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: 27/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 00009F7F 368925[40E30000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    45                              <1> 	; save user registers
    46 00009F86 1E                  <1> 	push	ds
    47 00009F87 06                  <1> 	push	es
    48 00009F88 0FA0                <1> 	push	fs
    49 00009F8A 0FA8                <1> 	push	gs
    50 00009F8C 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 00009F8D 50                  <1> 	push	eax ; 01/07/2015
    57 00009F8E 66B81000            <1> 	mov     ax, KDATA
    58 00009F92 8ED8                <1>         mov     ds, ax
    59 00009F94 8EC0                <1>         mov     es, ax
    60 00009F96 8EE0                <1>         mov     fs, ax
    61 00009F98 8EE8                <1>         mov     gs, ax
    62 00009F9A A1[88D20000]        <1> 	mov	eax, [k_page_dir]
    63 00009F9F 0F22D8              <1> 	mov	cr3, eax
    64 00009FA2 58                  <1> 	pop	eax ; 01/07/2015
    65                              <1> 	; 19/10/2015
    66 00009FA3 FC                  <1> 	cld
    67                              <1> 	;
    68 00009FA4 FE05[3FE30000]      <1> 	inc	byte [sysflg]
    69                              <1> 		; incb sysflg / indicate a system routine is in progress
    70 00009FAA FB                  <1>         sti 	; 18/01/2014
    71 00009FAB 0F8557A0FFFF        <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 00009FB1 A3[48E30000]        <1> 	mov	[u.r0], eax
    77 00009FB6 8925[44E30000]      <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 00009FBC C1E002              <1> 	shl	eax, 2
    99                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   100 00009FBF 3DA0000000          <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 00009FC4 F5                  <1> 	cmc
   105 00009FC5 9C                  <1> 	pushf	
   106 00009FC6 50                  <1> 	push	eax
   107 00009FC7 8B2D[40E30000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   108 00009FCD B0FE                <1> 	mov	al, 0FEh ; 11111110b
   109 00009FCF 1400                <1> 	adc	al, 0 ; al = al + cf
   110 00009FD1 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 00009FD4 5D                  <1> 	pop	ebp ; eax
   114 00009FD5 9D                  <1> 	popf
   115 00009FD6 0F8254010000        <1>         jc      badsys
   116 00009FDC A1[48E30000]        <1> 	mov	eax, [u.r0]
   117                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   118 00009FE1 FFA5[E79F0000]      <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> 	; 20/05/2016
   123                              <1> 	; 19/05/2016
   124                              <1> 	; 16/05/2016
   125                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   126                              <1> 	; 21/09/2015
   127                              <1> 	; 01/07/2015
   128                              <1> 	; 16/04/2015 (32 bit address modification) 
   129                              <1> 	;dd sysrele	; / 0
   130 00009FE7 [8FBC0000]          <1> 	dd sysver	; 0 ; Get TRDOS 386 version number (v2.0)	
   131 00009FEB [90A10000]          <1> 	dd sysexit 	; / 1
   132 00009FEF [1CA30000]          <1> 	dd sysfork 	; / 2
   133 00009FF3 [2FA40000]          <1> 	dd sysread 	; / 3
   134 00009FF7 [4AA40000]          <1> 	dd syswrite 	; / 4
   135 00009FFB [B4A40000]          <1> 	dd sysopen 	; / 5
   136 00009FFF [EEA50000]          <1> 	dd sysclose 	; / 6
   137 0000A003 [9EA20000]          <1> 	dd syswait 	; / 7
   138 0000A007 [64A50000]          <1> 	dd syscreat 	; / 8
   139 0000A00B [63AA0000]          <1> 	dd syslink 	; / 9
   140 0000A00F [25AB0000]          <1> 	dd sysunlink 	; / 10
   141 0000A013 [F8AB0000]          <1> 	dd sysexec 	; / 11
   142 0000A017 [52B00000]          <1> 	dd syschdir 	; / 12
   143 0000A01B [36B10000]          <1> 	dd systime 	; / 13
   144 0000A01F [A5A50000]          <1> 	dd sysmkdir 	; / 14
   145 0000A023 [A4B00000]          <1> 	dd syschmod 	; / 15
   146 0000A027 [06B10000]          <1> 	dd syschown 	; / 16
   147 0000A02B [69B10000]          <1> 	dd sysbreak 	; / 17
   148 0000A02F [C3AD0000]          <1> 	dd sysstat 	; / 18
   149 0000A033 [2EB20000]          <1> 	dd sysseek 	; / 19
   150 0000A037 [40B20000]          <1> 	dd systell 	; / 20
   151 0000A03B [41B30000]          <1> 	dd sysmount 	; / 21
   152 0000A03F [F3B30000]          <1> 	dd sysumount 	; / 22
   153 0000A043 [BEB20000]          <1> 	dd syssetuid 	; / 23
   154 0000A047 [EFB20000]          <1> 	dd sysgetuid 	; / 24
   155 0000A04B [45B10000]          <1> 	dd sysstime 	; / 25
   156 0000A04F [B2B20000]          <1> 	dd sysquit 	; / 26
   157 0000A053 [A6B20000]          <1> 	dd sysintr 	; / 27
   158 0000A057 [9FAD0000]          <1> 	dd sysfstat 	; / 28
   159 0000A05B [0AA60000]          <1> 	dd sysemt 	; / 29
   160 0000A05F [7AA70000]          <1> 	dd sysmdate 	; / 30
   161                              <1> 	;dd sysstty	; / 31
   162 0000A063 [C5A70000]          <1> 	dd sysvideo 	; 31 ; TRDOS 386 Video Functions (16/05/2016)
   163                              <1> 	;dd sysgtty	; / 32
   164 0000A067 [51AA0000]          <1> 	dd sysaudio 	; 32 ; TRDOS 386 Audio Functions (16/05/2016)
   165                              <1> 	;dd sysilgins	; / 33
   166 0000A06B [23A60000]          <1> 	dd systimer 	; 33 ; TRDOS 386 Timer Functions (18/05/2016)
   167 0000A06F [4EB40000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   168                              <1> 			     ; 11/06/2014
   169 0000A073 [7DB40000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   170                              <1> 			     ; 01/07/2015
   171 0000A077 [53B50000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   172                              <1> 			     ; 21/09/2015 - get last error number
   173 0000A07B [9EBC0000]          <1> 	dd sysreserved1 ; 37 ;; TRDOS 386 (19/05/2016)
   174 0000A07F [ADBC0000]          <1> 	dd syspri 	; 38 ; change priority - TRDOS 386 (20/05/2016)
   175 0000A083 [FAA00000]          <1> 	dd sysrele	; 39 ; TRDOS 386 (19/05/2016) (0 -> 39)
   176                              <1> 
   177                              <1> end_of_syscalls:
   178                              <1> 
   179                              <1> error:
   180                              <1> 	; 18/05/2016
   181                              <1> 	; 13/05/2016
   182                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   183                              <1> 	; 16/04/2015 - 17/09/2015 (Retro UNIX 386 v1)
   184                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
   185                              <1> 	;
   186                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
   187                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
   188                              <1> 	;
   189                              <1> 	; INPUTS -> none
   190                              <1> 	; OUTPUTS ->
   191                              <1> 	;	processor status - carry (c) bit is set (means error)
   192                              <1> 	;
   193                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
   194                              <1> 	; 	      Because, jumps to error procedure
   195                              <1> 	;	      disrupts push-pop nesting balance)
   196                              <1> 	;
   197 0000A087 8B2D[40E30000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   198 0000A08D 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
   199                              <1> 				 ; (system call will return with cf = 1)
   200                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
   201                              <1> 		               ; / users stack
   202                              <1> 	; 17/09/2015
   203 0000A091 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
   204                              <1> 				 ; for saving/restoring user registers	
   205                              <1> 	;cmp	ebp, [u.usp]
   206                              <1> 	;je	short err0	
   207 0000A094 892D[44E30000]      <1> 	mov	[u.usp], ebp
   208                              <1> ;err0:
   209                              <1> 	; 01/09/2015
   210 0000A09A 8B25[44E30000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
   211                              <1> 				    ; 10/04/2013
   212                              <1> 				    ; (If an I/O error occurs during disk I/O,
   213                              <1> 				    ; related procedures will jump to 'error'
   214                              <1> 				    ; procedure directly without returning to 
   215                              <1> 				    ; the caller procedure. So, stack pointer
   216                              <1>                                     ; must be restored here.)
   217                              <1> 	; 13/05/2016
   218                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
   219                              <1> 	;	'get last error' system call later. 	
   220                              <1> 
   221                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
   222 0000A0A0 C605[AFE30000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
   223                              <1> 
   224                              <1> sysret: ; < return from system call>
   225                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   226                              <1> 	; 16/04/2015 - 10/09/2015 (Retro UNIX 386 v1)
   227                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
   228                              <1> 	;
   229                              <1> 	; 'sysret' first checks to see if process is about to be 
   230                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
   231                              <1> 	; If not, following happens:	 
   232                              <1> 	; 	1) The user's stack pointer is restored.
   233                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
   234                              <1> 	;	   i-node has been modified. If it has, it is written out
   235                              <1> 	;	   via 'ppoke'.
   236                              <1> 	;	3) If the super block has been modified, it is written out
   237                              <1> 	;	   via 'ppoke'.				
   238                              <1> 	;	4) If the dismountable file system's super block has been
   239                              <1> 	;	   modified, it is written out to the specified device
   240                              <1> 	;	   via 'ppoke'.
   241                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
   242                              <1> 	;	   during his execution. If so, 'tswap' is called to give
   243                              <1> 	;	   another user a chance to run.
   244                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
   245                              <1> 	;	    (See 'sysrele' for conclusion.)		
   246                              <1> 	;
   247                              <1> 	; Calling sequence:
   248                              <1> 	;	jump table or 'br sysret'
   249                              <1> 	; Arguments: 
   250                              <1> 	;	-	
   251                              <1> 	; ...............................................................
   252                              <1> 	;	
   253                              <1> 	; ((AX=r1 for 'iget' input))
   254                              <1> 	;	
   255 0000A0A7 6631C0              <1> 	xor	ax, ax ; 04/05/2013
   256                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   257 0000A0AA FEC0                <1> 	inc	al ; 04/05/2013
   258 0000A0AC 3805[96E30000]      <1> 	cmp	[u.bsys], al ; 1
   259                              <1> 		; tstb u.bsys / is a process about to be terminated because
   260 0000A0B2 0F83D8000000        <1>         jnb     sysexit ; 04/05/2013
   261                              <1> 		; bne sysexit / of an error? yes, go to sysexit
   262                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
   263                              <1> 		; mov u.sp,sp / no point stack to users stack
   264 0000A0B8 FEC8                <1> 	dec 	al ; mov ax, 0
   265                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   266 0000A0BA E8211D0000          <1> 	call	iget
   267                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   268                              <1> 		            ; / it is written out
   269 0000A0BF 6631C0              <1> 	xor 	ax, ax ; 0
   270 0000A0C2 3805[3DE30000]      <1> 	cmp	[smod], al ; 0
   271                              <1> 		; tstb	smod / has the super block been modified
   272 0000A0C8 7614                <1> 	jna	short sysret1
   273                              <1> 		; beq	1f / no, 1f
   274 0000A0CA A2[3DE30000]        <1> 	mov	[smod], al ; 0
   275                              <1> 		; clrb smod / yes, clear smod
   276 0000A0CF BB[F5EB0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
   277 0000A0D4 66810B0002          <1>    	or	word [ebx], 200h ;;
   278                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
   279                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
   280                              <1> 		      	      ; / output
   281                              <1> 	; AX = 0
   282 0000A0D9 E8031D0000          <1> 	call 	poke ; 07/08/2013
   283                              <1> 	; call	ppoke
   284                              <1> 	; AX = 0
   285                              <1> 		; jsr r0,ppoke / write out modified super block to disk
   286                              <1> sysret1: ;1:
   287 0000A0DE 3805[3EE30000]      <1> 	cmp	[mmod], al ; 0
   288                              <1> 		; tstb	mmod / has the super block for the dismountable file
   289                              <1> 		           ; / system
   290 0000A0E4 7614                <1> 	jna	short sysrel0
   291                              <1> 		; beq 1f / been modified?  no, 1f
   292 0000A0E6 A2[3EE30000]        <1> 	mov	[mmod], al ; 0	
   293                              <1> 		; clrb	mmod / yes, clear mmod
   294                              <1>         ;mov    ax, [mntd]
   295                              <1>         ;;mov   al, [mdev] ; 26/04/2013
   296 0000A0EB BB[FDED0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
   297                              <1>         ;;mov	[ebx], al
   298                              <1> 	;mov    [sb1], al
   299                              <1> 		; movb	mntd,sb1 / set the I/O queue
   300 0000A0F0 66810B0002          <1> 	or	word [ebx], 200h
   301                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
   302                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
   303 0000A0F5 E8E71C0000          <1> 	call	poke ; 07/08/2013
   304                              <1> 	;call	ppoke 
   305                              <1> 		; jsr r0,ppoke / write it out to its device
   306                              <1>         ;xor    al, al ; 26/04/2013       
   307                              <1> ;1:
   308                              <1> 		; tstb uquant / is the time quantum 0?
   309                              <1> 		; bne 1f / no, don't swap it out
   310                              <1> 
   311                              <1> sysrele: ; < release >
   312                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   313                              <1> 	; 16/04/2015 - 14/10/2015 (Retro UNIX 386 v1)
   314                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
   315                              <1> 	;
   316                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
   317                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
   318                              <1> 	; turns off the system flag. It then checked to see if there is
   319                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
   320                              <1> 	; the output gets flashed (see isintr) and interrupt action is
   321                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
   322                              <1> 	; the user, a rti is made.
   323                              <1> 	;
   324                              <1> 	; Calling sequence:
   325                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
   326                              <1> 	; Arguments:
   327                              <1> 	;	-	
   328                              <1> 	; ...............................................................
   329                              <1> 	;	
   330                              <1> 	; 23/02/2014 (swapret)
   331                              <1> 	; 22/09/2013
   332                              <1> sysrel0: ;1:
   333 0000A0FA 803D[8AE30000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   334                              <1> 		; tstb uquant / is the time quantum 0?
   335 0000A101 7705                <1>         ja      short swapret
   336                              <1> 		; bne 1f / no, don't swap it out
   337                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
   338 0000A103 E8541A0000          <1> 	call	tswap
   339                              <1> 		; jsr r0,tswap / yes, swap it out
   340                              <1> 	
   341                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
   342                              <1> swapret: ;1:
   343                              <1> 	; 10/09/2015
   344                              <1> 	; 01/09/2015
   345                              <1> 	; 14/05/2015
   346                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
   347                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
   348                              <1> 	; cli
   349                              <1> 	; 24/07/2015
   350                              <1> 	;
   351                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
   352                              <1> 	;; mov	esp, [u.usp]
   353                              <1> 
   354                              <1> 	; 22/09/2013
   355 0000A108 E8D51C0000          <1> 	call	isintr
   356                              <1> 	; 20/10/2013
   357 0000A10D 7405                <1> 	jz	short sysrel1
   358 0000A10F E865000000          <1> 	call	intract
   359                              <1> 		; jsr r0,isintr / is there an interrupt from the user
   360                              <1> 		;     br intract / yes, output gets flushed, take interrupt
   361                              <1> 		               ; / action
   362                              <1> sysrel1:
   363 0000A114 FA                  <1> 	cli ; 14/10/2015
   364 0000A115 FE0D[3FE30000]      <1> 	dec	byte [sysflg]
   365                              <1> 		; decb sysflg / turn system flag off
   366 0000A11B A1[A1E30000]        <1> 	mov     eax, [u.pgdir]
   367 0000A120 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
   368                              <1> 			  ; (others are different than kernel page tables) 
   369                              <1> 	; 10/09/2015
   370 0000A123 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   371                              <1> 		; mov (sp)+,sc / restore user registers
   372                              <1> 		; mov (sp)+,mq
   373                              <1> 		; mov (sp)+,ac
   374                              <1> 		; mov (sp)+,r5
   375                              <1> 		; mov (sp)+,r4
   376                              <1> 		; mov (sp)+,r3
   377                              <1> 		; mov (sp)+,r2
   378                              <1> 	;
   379 0000A124 A1[48E30000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   380 0000A129 0FA9                <1> 	pop	gs
   381 0000A12B 0FA1                <1> 	pop	fs
   382 0000A12D 07                  <1> 	pop	es
   383 0000A12E 1F                  <1> 	pop	ds
   384 0000A12F CF                  <1> 	iretd	
   385                              <1> 		; rti / no, return from interrupt
   386                              <1> 
   387                              <1> badsys:
   388                              <1> 	; 18/04/2016 (TRDOS 386 = TRDOS v2.0)
   389                              <1> 	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
   390                              <1> 	; 03/02/2011 ('trdos_ifc_routine')
   391                              <1> 	;
   392                              <1> 	; 16/04/2015 (Retro UNIX 386 v1, 'badsys')
   393                              <1> 	; (EIP, EAX values will be shown on screen with error message)
   394                              <1> 	; (EIP = 'CD 40h' instruction address -INT 40h-)
   395                              <1> 	; (EAX = Function number)  
   396                              <1> 	;
   397 0000A130 FE05[96E30000]      <1> 	inc	byte [u.bsys]
   398                              <1> 	;
   399 0000A136 8B1D[40E30000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   400 0000A13C 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   401 0000A13E 83E802              <1> 	sub	eax, 2 ; CDh, ##h
   402 0000A141 E8C877FFFF          <1> 	call	dwordtohex
   403 0000A146 8915[F7C80000]      <1> 	mov	[eip_str], edx
   404 0000A14C A3[FBC80000]        <1> 	mov	[eip_str+4], eax
   405 0000A151 A1[48E30000]        <1> 	mov	eax, [u.r0]
   406 0000A156 E8B377FFFF          <1> 	call	dwordtohex
   407 0000A15B 8915[E6C80000]      <1> 	mov	[eax_str], edx
   408 0000A161 A3[EAC80000]        <1> 	mov	[eax_str+4], eax
   409                              <1> 
   410 0000A166 C605[DBC80000]40    <1> 	mov	byte [int_num_str], 40h
   411                              <1> 
   412 0000A16D BE[ADC80000]        <1> 	mov	esi, ifc_msg ; "invalid funtion call !" msg (trdosk9.s)
   413 0000A172 E83D9EFFFF          <1> 	call	print_msg
   414                              <1> 
   415 0000A177 EB17                <1> 	jmp	sysexit
   416                              <1> 
   417                              <1> intract: ; / interrupt action
   418                              <1> 	; 14/10/2015
   419                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   420                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
   421                              <1> 	;
   422                              <1> 	; Retro UNIX 8086 v1 modification !
   423                              <1> 	; (Process/task switching and quit routine by using
   424                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
   425                              <1> 	;
   426                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
   427                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
   428                              <1> 	;		'intract' will jump to 'sysexit'.
   429                              <1> 	;	    Intract will return to the caller 
   430                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
   431                              <1> 	; 14/10/2015
   432 0000A179 FB                  <1> 	sti
   433                              <1> 	; 07/12/2013	
   434 0000A17A 66FF05[8EE30000]    <1> 	inc 	word [u.quit]
   435 0000A181 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   436 0000A183 66FF0D[8EE30000]    <1> 	dec	word [u.quit]
   437                              <1> 	; 16/04/2015
   438 0000A18A C3                  <1> 	retn
   439                              <1> intrct0:	
   440 0000A18B 58                  <1> 	pop	eax ; call intract -> retn
   441                              <1> 	;
   442 0000A18C 31C0                <1> 	xor 	eax, eax
   443 0000A18E FEC0                <1> 	inc	al  ; mov ax, 1
   444                              <1> ;;;
   445                              <1> 	; UNIX v1 original 'intract' routine... 
   446                              <1> 	; / interrupt action
   447                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
   448                              <1> 		; bne 1f / no, 1f
   449                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
   450                              <1> 	; 1: / now in user area
   451                              <1> 		; mov r1,-(sp) / save r1
   452                              <1> 		; mov u.ttyp,r1 
   453                              <1> 			; / pointer to tty buffer in control-to r1
   454                              <1> 		; cmpb 6(r1),$177
   455                              <1> 			; / is the interrupt char equal to "del"
   456                              <1> 		; beq 1f / yes, 1f
   457                              <1> 		; clrb 6(r1) 
   458                              <1> 		        ; / no, clear the byte 
   459                              <1> 			; / (must be a quit character)
   460                              <1> 		; mov (sp)+,r1 / restore r1
   461                              <1> 		; clr u.quit / clear quit flag
   462                              <1> 		; bis $20,2(sp) 
   463                              <1> 		    	; / set trace for quit (sets t bit of 
   464                              <1> 			; / ps-trace trap)
   465                              <1> 		; rti   ;  / return from interrupt
   466                              <1> 	; 1: / interrupt char = del
   467                              <1> 		; clrb 6(r1) / clear the interrupt byte 
   468                              <1> 			   ; / in the buffer
   469                              <1> 		; mov (sp)+,r1 / restore r1
   470                              <1> 		; cmp u.intr,$core / should control be 
   471                              <1> 				; / transferred to loc core?
   472                              <1> 		; blo 1f
   473                              <1> 		; jmp *u.intr / user to do rti yes, 
   474                              <1> 				; / transfer to loc core
   475                              <1> 	; 1:
   476                              <1> 		; sys 1 / exit
   477                              <1> 
   478                              <1> sysexit: ; <terminate process>
   479                              <1> 	; 23/05/2016
   480                              <1> 	; 19/05/2016
   481                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   482                              <1> 	; 16/04/2015 - 01/09/2015 (Retro UNIX 386 v1)
   483                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   484                              <1> 	;
   485                              <1> 	; 'sysexit' terminates a process. First each file that
   486                              <1> 	; the process has opened is closed by 'flose'. The process
   487                              <1> 	; status is then set to unused. The 'p.pid' table is then
   488                              <1> 	; searched to find children of the dying process. If any of
   489                              <1> 	; children are zombies (died by not waited for), they are
   490                              <1> 	; set free. The 'p.pid' table is then searched to find the
   491                              <1> 	; dying process's parent. When the parent is found, it is
   492                              <1> 	; checked to see if it is free or it is a zombie. If it is
   493                              <1> 	; one of these, the dying process just dies. If it is waiting
   494                              <1> 	; for a child process to die, it notified that it doesn't 
   495                              <1> 	; have to wait anymore by setting it's status from 2 to 1
   496                              <1> 	; (waiting to active). It is awakened and put on runq by
   497                              <1> 	; 'putlu'. The dying process enters a zombie state in which
   498                              <1> 	; it will never be run again but stays around until a 'wait'
   499                              <1> 	; is completed by it's parent process. If the parent is not
   500                              <1> 	; found, process just dies. This means 'swap' is called with
   501                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
   502                              <1> 	; to write out the process and 'rswap' reads the new process
   503                              <1> 	; over the one that dies..i.e., the dying process is 
   504                              <1> 	; overwritten and destroyed.	
   505                              <1>  	;
   506                              <1> 	; Calling sequence:
   507                              <1> 	;	sysexit or conditional branch.
   508                              <1> 	; Arguments:
   509                              <1> 	;	-	
   510                              <1> 	; ...............................................................
   511                              <1> 	;	
   512                              <1> 	; Retro UNIX 8086 v1 modification: 
   513                              <1> 	;       System call number (=1) is in EAX register.
   514                              <1> 	;
   515                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
   516                              <1> 	;       registers depending of function details.
   517                              <1> 	;
   518                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
   519                              <1> 	;
   520                              <1> ; / terminate process
   521                              <1> 	; AX = 1
   522 0000A190 6648                <1> 	dec 	ax ; 0
   523 0000A192 66A3[8CE30000]      <1> 	mov	[u.intr], ax ; 0
   524                              <1> 		; clr u.intr / clear interrupt control word
   525                              <1> 		; clr r1 / clear r1
   526                              <1> 	; AX = 0
   527                              <1> sysexit_1: ; 1:
   528                              <1> 	; AX = File descriptor
   529                              <1> 		; / r1 has file descriptor (index to u.fp list)
   530                              <1> 		; / Search the whole list
   531 0000A198 E8BC0C0000          <1> 	call	fclose
   532                              <1> 		; jsr r0,fclose / close all files the process opened
   533                              <1> 	;; ignore error return
   534                              <1> 		; br .+2 / ignore error return
   535                              <1> 	;inc	ax
   536 0000A19D FEC0                <1> 	inc	al
   537                              <1> 		; inc r1 / increment file descriptor
   538                              <1> 	;cmp	ax, 10
   539 0000A19F 3C0A                <1> 	cmp	al, 10
   540                              <1> 		; cmp r1,$10. / end of u.fp list?
   541 0000A1A1 72F5                <1> 	jb	short sysexit_1
   542                              <1> 		; blt 1b / no, go back
   543 0000A1A3 0FB61D[97E30000]    <1> 	movzx	ebx, byte [u.uno]
   544                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   545 0000A1AA 88A3[BBE00000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   546                              <1> 		; clrb p.stat-1(r1) / free the process
   547                              <1> 	;shl	bx, 1
   548 0000A1B0 D0E3                <1> 	shl	bl, 1
   549                              <1> 		; asl r1 / use r1 for index into the below tables
   550 0000A1B2 668B8B[2AE00000]    <1> 	mov	cx, [ebx+p.pid-2]
   551                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   552 0000A1B9 668B93[4AE00000]    <1> 	mov	dx, [ebx+p.ppid-2]
   553                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
   554                              <1> 	; xor 	bx, bx ; 0
   555 0000A1C0 30DB                <1> 	xor	bl, bl ; 0
   556                              <1> 		; clr r2
   557 0000A1C2 31F6                <1> 	xor	esi, esi ; 0
   558                              <1> 		; clr r5 / initialize reg
   559                              <1> sysexit_2: ; 1:
   560                              <1> 	        ; / find children of this dying process, 
   561                              <1> 		; / if they are zombies, free them
   562                              <1> 	;add	bx, 2
   563 0000A1C4 80C302              <1> 	add	bl, 2
   564                              <1> 		; add $2,r2 / search parent process table 
   565                              <1> 		          ; / for dying process's name
   566 0000A1C7 66398B[4AE00000]    <1> 	cmp	[ebx+p.ppid-2], cx
   567                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   568 0000A1CE 7513                <1> 	jne	short sysexit_4
   569                              <1> 		; bne 3f / no
   570                              <1> 	;shr	bx, 1
   571 0000A1D0 D0EB                <1> 	shr	bl, 1
   572                              <1> 		; asr r2 / yes, it is a parent
   573 0000A1D2 80BB[BBE00000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB
   574                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
   575                              <1> 				     ; / dying process a zombie
   576 0000A1D9 7506                <1> 	jne	short sysexit_3 
   577                              <1> 		; bne 2f / no
   578 0000A1DB 88A3[BBE00000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   579                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
   580                              <1> sysexit_3: ; 2:
   581                              <1> 	;shr	bx, 1
   582 0000A1E1 D0E3                <1> 	shl	bl, 1
   583                              <1> 		; asl r2
   584                              <1> sysexit_4: ; 3:
   585                              <1> 		; / search the process name table 
   586                              <1> 		; / for the dying process's parent
   587 0000A1E3 663993[2AE00000]    <1> 	cmp	[ebx+p.pid-2], dx
   588                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   589 0000A1EA 7502                <1> 	jne	short sysexit_5
   590                              <1> 		; bne 3f / no
   591 0000A1EC 89DE                <1> 	mov	esi, ebx
   592                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
   593                              <1> 		          ; / process # x2) in r5
   594                              <1> sysexit_5: ; 3:
   595                              <1> 	;cmp	bx, nproc + nproc
   596 0000A1EE 80FB20              <1> 	cmp	bl, nproc + nproc
   597                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   598 0000A1F1 72D1                <1> 	jb	short sysexit_2
   599                              <1> 		; blt 1b / no, go back
   600                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
   601 0000A1F3 21F6                <1> 	and	esi, esi ; r5=r1
   602 0000A1F5 7431                <1> 	jz	short sysexit_6
   603                              <1> 		; beq 2f / no parent has been found. 
   604                              <1> 		       ; / The process just dies
   605 0000A1F7 66D1EE              <1> 	shr	si, 1
   606                              <1> 		; asr r1 / set up index to p.stat
   607 0000A1FA 8A86[BBE00000]      <1> 	mov	al, [esi+p.stat-1]
   608                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   609 0000A200 20C0                <1> 	and	al, al
   610 0000A202 7424                <1> 	jz	short sysexit_6
   611                              <1> 		; beq 2f / if its been freed, 2f
   612 0000A204 3C03                <1> 	cmp	al, 3
   613                              <1> 		; cmp r2,$3 / is parent a zombie?
   614 0000A206 7420                <1> 	je	short sysexit_6
   615                              <1> 		; beq 2f / yes, 2f
   616                              <1> 	; BH = 0
   617 0000A208 8A1D[97E30000]      <1> 	mov	bl, [u.uno]
   618                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   619 0000A20E C683[BBE00000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB
   620                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   621 0000A215 3C01                <1> 	cmp	al, 1 ; SRUN
   622 0000A217 740F                <1> 	je	short sysexit_6
   623                              <1> 	;cmp	al, 2
   624                              <1> 		; cmp r2,$2 / is the parent waiting for 
   625                              <1> 			  ; / this child to die
   626                              <1> 	;jne	short sysexit_6	
   627                              <1> 		; bne 2f / yes, notify parent not to wait any more
   628                              <1> 	; p.stat = 2 --> waiting
   629                              <1> 	; p.stat = 4 --> sleeping
   630 0000A219 C686[BBE00000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN
   631                              <1> 	;dec	byte [esi+p.stat-1]
   632                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
   633 0000A220 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
   634                              <1> 	; 
   635                              <1> 	;mov	ebx, runq + 4
   636                              <1> 		; mov $runq+4,r2 / on the runq
   637 0000A223 E8471A0000          <1> 	call	putlu
   638                              <1> 		; jsr r0, putlu
   639                              <1> sysexit_6: 
   640                              <1> 	; 23/05/2016
   641                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   642                              <1> 	; Check and stop/clear timer event(s) of this (dying) process
   643                              <1> 	; if there is. 
   644 0000A228 0FB635[97E30000]    <1> 	movzx	esi, byte [u.uno]
   645 0000A22F 8A86[0BE10000]      <1> 	mov 	al, [esi+p.timer-1]
   646 0000A235 20C0                <1> 	and	al, al
   647 0000A237 7457                <1> 	jz	short sysexit_12 ; no timer event for this process
   648 0000A239 FA                  <1> 	cli	; disable interrupts 
   649 0000A23A C686[0BE10000]00    <1> 	mov	byte [esi+p.timer-1], 0 ; reset
   650 0000A241 B310                <1> 	mov	bl, 16
   651 0000A243 668B8E[2AE00000]    <1> 	mov	cx, [esi+p.pid-2] ; process ID
   652 0000A24A BE[0CF00000]        <1> 	mov	esi, timer_set ; beginning address of timer events
   653                              <1> sysexit_7:
   654 0000A24F 668B06              <1> 	mov	ax, [esi] ; Owner ID (of timer event)
   655 0000A252 6621C0              <1> 	and	ax, ax
   656 0000A255 7439                <1> 	jz	short sysexit_12
   657 0000A257 89F7                <1> 	mov	edi, esi
   658 0000A259 83C610              <1> 	add	esi, 16
   659 0000A25C 6639C8              <1> 	cmp	ax, cx ; process ID comparison
   660 0000A25F 7408                <1> 	je	short sysexit_8
   661 0000A261 FECB                <1> 	dec	bl
   662 0000A263 75EA                <1> 	jnz	short sysexit_7
   663 0000A265 28C0                <1> 	sub	al, al ; 0
   664 0000A267 EB27                <1> 	jmp	short sysexit_12
   665                              <1> sysexit_8:
   666 0000A269 80FB01              <1> 	cmp	bl, 1
   667 0000A26C 761B                <1> 	jna	short sysexit_11 ; clear only, do not move back
   668                              <1> sysexit_9:
   669 0000A26E 89FA                <1> 	mov	edx, edi
   670                              <1> sysexit_10:
   671                              <1> 	; move next event to back (instead of stopped event)
   672 0000A270 A5                  <1> 	movsd
   673 0000A271 A5                  <1> 	movsd
   674 0000A272 A5                  <1> 	movsd
   675 0000A273 A5                  <1> 	movsd
   676 0000A274 FECB                <1> 	dec	bl
   677 0000A276 7418                <1> 	jz	short sysexit_12
   678 0000A278 668B06              <1> 	mov	ax, [esi] ; Owner ID (of timer event)
   679 0000A27B 6621C0              <1> 	and	ax, ax
   680 0000A27E 7409                <1> 	jz	short sysexit_11
   681 0000A280 6639C8              <1> 	cmp	ax, cx
   682 0000A283 75E9                <1> 	jne	short sysexit_9
   683                              <1> 	; same process ID, remove this event too
   684 0000A285 89D7                <1> 	mov	edi, edx
   685 0000A287 EBE7                <1> 	jmp	short sysexit_10
   686                              <1> 
   687                              <1> sysexit_11:
   688                              <1> 	; clear timer event area (belong to current process)
   689                              <1> 	; (this timer event will be stopped/finished)
   690 0000A289 6631C0              <1> 	xor	ax, ax ; eax = 0
   691 0000A28C AB                  <1> 	stosd
   692 0000A28D AB                  <1> 	stosd	
   693 0000A28E AB                  <1> 	stosd
   694 0000A28F AB                  <1> 	stosd
   695                              <1> 	;
   696                              <1> sysexit_12: ; 2:
   697 0000A290 FB                  <1> 	sti	; enable interrupts 
   698                              <1> 	;
   699 0000A291 A2[97E30000]        <1> 	mov	[u.uno], al ; 0
   700                              <1> 		; / the process dies
   701                              <1> 	;mov	byte [u.uno], 0
   702                              <1> 		; clrb u.uno / put zero as the process number, 
   703                              <1> 	           ; / so "swap" will
   704 0000A296 E8E4180000          <1> 	call	swap
   705                              <1> 		; jsr r0,swap / overwrite process with another process
   706                              <1> hlt_sys:
   707                              <1> 	;sti
   708                              <1> hlts0:
   709 0000A29B F4                  <1> 	hlt
   710 0000A29C EBFD                <1> 	jmp	short hlts0
   711                              <1> 		; 0 / and thereby kill it; halt?
   712                              <1> 
   713                              <1> syswait: ; < wait for a processs to die >
   714                              <1> 	; 17/09/2015
   715                              <1> 	; 02/09/2015
   716                              <1> 	; 01/09/2015
   717                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   718                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
   719                              <1> 	;
   720                              <1> 	; 'syswait' waits for a process die. 
   721                              <1> 	; It works in following way:
   722                              <1> 	;    1) From the parent process number, the parent's 
   723                              <1> 	; 	process name is found. The p.ppid table of parent
   724                              <1> 	;	names is then searched for this process name.
   725                              <1> 	;	If a match occurs, r2 contains child's process
   726                              <1> 	;	number. The child status is checked to see if it is
   727                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
   728                              <1> 	;	If it is, the child process is freed and it's name
   729                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
   730                              <1> 	;	If the child is not a zombie, nothing happens and
   731                              <1> 	;	the search goes on through the p.ppid table until
   732                              <1> 	;	all processes are checked or a zombie is found.
   733                              <1> 	;    2) If no zombies are found, a check is made to see if
   734                              <1> 	;	there are any children at all. If there are none,
   735                              <1> 	;	an error return is made. If there are, the parent's
   736                              <1> 	;	status is set to 2 (waiting for child to die),
   737                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
   738                              <1> 	;	is made to wait on the next process.
   739                              <1> 	;
   740                              <1> 	; Calling sequence:
   741                              <1> 	;	?
   742                              <1> 	; Arguments:
   743                              <1> 	;	-
   744                              <1> 	; Inputs: - 
   745                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
   746                              <1> 	; ...............................................................
   747                              <1> 	;				
   748                              <1> 	
   749                              <1> ; / wait for a process to die
   750                              <1> 
   751                              <1> syswait_0:
   752 0000A29E 0FB61D[97E30000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   753                              <1> 		; movb u.uno,r1 / put parents process number in r1
   754 0000A2A5 D0E3                <1> 	shl	bl, 1
   755                              <1> 	;shl	bx, 1
   756                              <1> 		; asl r1 / x2 to get index into p.pid table
   757 0000A2A7 668B83[2AE00000]    <1> 	mov	ax, [ebx+p.pid-2]
   758                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   759 0000A2AE 31F6                <1> 	xor	esi, esi
   760                              <1> 		; clr r2
   761 0000A2B0 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
   762                              <1> 	;xor 	cl, cl
   763                              <1> 		; clr r3 / initialize reg 3
   764                              <1> syswait_1: ; 1:
   765 0000A2B2 6683C602            <1> 	add	si, 2
   766                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
   767                              <1> 			  ; / search table of parent processes 
   768                              <1> 			  ; / for this process name
   769 0000A2B6 663B86[4AE00000]    <1> 	cmp	ax, [esi+p.ppid-2]
   770                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
   771                              <1> 			            ; / process number
   772 0000A2BD 7535                <1> 	jne	short syswait_3
   773                              <1> 		;bne 3f / branch if no match of parent process name
   774                              <1> 	;inc	cx
   775 0000A2BF FEC1                <1> 	inc	cl
   776                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   777 0000A2C1 66D1EE              <1> 	shr	si, 1
   778                              <1> 		; asr r2 / r2/2 to get index to p.stat table
   779                              <1> 	; The possible states ('p.stat' values) of a process are:
   780                              <1> 	;	0 = free or unused
   781                              <1> 	;	1 = active
   782                              <1> 	;	2 = waiting for a child process to die
   783                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
   784 0000A2C4 80BE[BBE00000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
   785                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
   786 0000A2CB 7524                <1> 	jne	short syswait_2
   787                              <1> 		; bne 2f / no, skip it
   788 0000A2CD 88BE[BBE00000]      <1> 	mov	[esi+p.stat-1], bh ; 0
   789                              <1> 		; clrb p.stat-1(r2) / yes, free it
   790 0000A2D3 66D1E6              <1> 	shl	si, 1
   791                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   792 0000A2D6 0FB786[2AE00000]    <1> 	movzx	eax, word [esi+p.pid-2]
   793 0000A2DD A3[48E30000]        <1> 	mov	[u.r0], eax
   794                              <1> 		; mov p.pid-2(r2),*u.r0 
   795                              <1> 			      ; / put childs process name in (u.r0)
   796                              <1> 	;
   797                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
   798                              <1> 	;
   799                              <1> 	; Parent process ID -p.ppid- field (of the child process)
   800                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
   801                              <1> 	; system call loop from the application/program if it calls
   802                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
   803                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
   804                              <1> 	;
   805                              <1> 	; Note: syswait will return with error if there is not a
   806                              <1> 	;       zombie or running process to wait.	
   807                              <1> 	;
   808 0000A2E2 6629C0              <1> 	sub	ax, ax
   809 0000A2E5 668986[4AE00000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   810 0000A2EC E9B9FDFFFF          <1> 	jmp	sysret0 ; ax = 0
   811                              <1> 	;
   812                              <1> 	;jmp	sysret
   813                              <1> 		; br sysret1 / return cause child is dead
   814                              <1> syswait_2: ; 2:
   815 0000A2F1 66D1E6              <1> 	shl	si, 1
   816                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   817                              <1> syswait_3: ; 3:
   818 0000A2F4 6683FE20            <1> 	cmp	si, nproc+nproc
   819                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   820 0000A2F8 72B8                <1> 	jb	short syswait_1
   821                              <1> 		; blt 1b / no, continue search
   822                              <1> 	;and	cx, cx
   823 0000A2FA 20C9                <1> 	and	cl, cl
   824                              <1> 		; tst r3 / one gets here if there are no children 
   825                              <1> 		       ; / or children that are still active
   826                              <1> 	; 30/10/2013
   827 0000A2FC 750B                <1> 	jnz	short syswait_4
   828                              <1> 	;jz	error
   829                              <1> 		; beq error1 / there are no children, error
   830 0000A2FE 890D[48E30000]      <1> 	mov	[u.r0], ecx ; 0
   831 0000A304 E97EFDFFFF          <1> 	jmp	error
   832                              <1> syswait_4:
   833 0000A309 8A1D[97E30000]      <1> 	mov	bl, [u.uno]
   834                              <1> 		; movb u.uno,r1 / there are children so put 
   835                              <1> 			      ; / parent process number in r1
   836 0000A30F FE83[BBE00000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
   837                              <1> 		; incb p.stat-1(r1) / it is waiting for 
   838                              <1> 				  ; / other children to die
   839                              <1> 	; 04/11/2013
   840 0000A315 E865180000          <1> 	call	swap
   841                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   842 0000A31A EB82                <1> 	jmp	syswait_0
   843                              <1> 		; br syswait / wait on next process
   844                              <1> 
   845                              <1> sysfork: ; < create a new process >
   846                              <1> 	; 18/09/2015
   847                              <1> 	; 04/09/2015
   848                              <1> 	; 02/09/2015
   849                              <1> 	; 01/09/2015
   850                              <1> 	; 28/08/2015
   851                              <1> 	; 14/05/2015
   852                              <1> 	; 10/05/2015
   853                              <1> 	; 09/05/2015
   854                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
   855                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   856                              <1> 	;
   857                              <1> 	; 'sysfork' creates a new process. This process is referred
   858                              <1> 	; to as the child process. This new process core image is
   859                              <1> 	; a copy of that of the caller of 'sysfork'. The only
   860                              <1> 	; distinction is the return location and the fact that (u.r0)
   861                              <1> 	; in the old process (parent) contains the process id (p.pid)
   862                              <1> 	; of the new process (child). This id is used by 'syswait'.
   863                              <1> 	; 'sysfork' works in the following manner: 	
   864                              <1> 	;    1) The process status table (p.stat) is searched to find
   865                              <1> 	;	a process number that is unused. If none are found
   866                              <1> 	;	an error occurs.
   867                              <1> 	;    2) when one is found, it becomes the child process number
   868                              <1> 	;	and it's status (p.stat) is set to active.
   869                              <1> 	;    3) If the parent had a control tty, the interrupt 
   870                              <1> 	;	character in that tty buffer is cleared.
   871                              <1> 	;    4) The child process is put on the lowest priority run 
   872                              <1> 	;	queue via 'putlu'.
   873                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
   874                              <1> 	;	it is a unique number) and is put in the child's unique
   875                              <1> 	;	identifier; process id (p.pid).
   876                              <1> 	;    6) The process name of the parent is then obtained and
   877                              <1> 	;	placed in the unique identifier of the parent process
   878                              <1> 	;	name is then put in 'u.r0'.	
   879                              <1> 	;    7) The child process is then written out on disk by
   880                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
   881                              <1> 	;	and the child is born. (The child process is written 
   882                              <1> 	;	out on disk/drum with 'u.uno' being the child process
   883                              <1> 	;	number.)
   884                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
   885                              <1> 	;    9) The child process name is put in 'u.r0'.
   886                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
   887                              <1> 	;	create the return address for the parent process.
   888                              <1> 	;   11) The 'u.fp' list as then searched to see what files
   889                              <1> 	;	the parent has opened. For each file the parent has
   890                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
   891                              <1> 	;	to indicate that the child process also has opened
   892                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
   893                              <1> 	;
   894                              <1> 	; Calling sequence:
   895                              <1> 	;	from shell ?
   896                              <1> 	; Arguments:
   897                              <1> 	;	-
   898                              <1> 	; Inputs: -
   899                              <1> 	; Outputs: *u.r0 - child process name
   900                              <1> 	; ...............................................................
   901                              <1> 	;	
   902                              <1> 	; Retro UNIX 8086 v1 modification: 
   903                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
   904                              <1> 	;	= process id of child a parent process returns
   905                              <1> 	;	= process id of parent when a child process returns
   906                              <1> 	;
   907                              <1> 	;       In original UNIX v1, sysfork is called and returns as
   908                              <1> 	;	in following manner: (with an example: c library, fork)
   909                              <1> 	;	
   910                              <1> 	;	1:
   911                              <1> 	;		sys	fork
   912                              <1> 	;			br 1f  / child process returns here
   913                              <1> 	;		bes	2f     / parent process returns here
   914                              <1> 	;		/ pid of new process in r0
   915                              <1> 	;		rts	pc
   916                              <1> 	;	2: / parent process condionally branches here
   917                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
   918                              <1> 	;		rts	pc
   919                              <1> 	;
   920                              <1> 	;	1: / child process brances here
   921                              <1> 	;		clr	r0   / pid = 0 in child process
   922                              <1> 	;		rts	pc
   923                              <1> 	;
   924                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
   925                              <1> 	;		// pid = fork();
   926                              <1> 	;		//
   927                              <1> 	;		// pid == 0 in child process; 
   928                              <1> 	;		// pid == -1 means error return
   929                              <1> 	;		// in child, 
   930                              <1> 	;		//	parents id is in par_uid if needed
   931                              <1> 	;		
   932                              <1> 	;		_fork:
   933                              <1> 	;			mov	$.fork,eax
   934                              <1> 	;			int	$0x30
   935                              <1> 	;			jmp	1f
   936                              <1> 	;			jnc	2f
   937                              <1> 	;			jmp	cerror
   938                              <1> 	;		1:
   939                              <1> 	;			mov	eax,_par_uid
   940                              <1> 	;			xor	eax,eax
   941                              <1> 	;		2:
   942                              <1> 	;			ret
   943                              <1> 	;
   944                              <1> 	;	In Retro UNIX 8086 v1,
   945                              <1> 	;	'sysfork' returns in following manner:
   946                              <1> 	;	
   947                              <1> 	;		mov	ax, sys_fork
   948                              <1> 	;		mov	bx, offset @f ; routine for child
   949                              <1> 	;		int	20h
   950                              <1> 	;		jc	error
   951                              <1> 	;		
   952                              <1> 	;	; Routine for parent process here (just after 'jc')
   953                              <1> 	;		mov	word ptr [pid_of_child], ax
   954                              <1> 	;		jmp	next_routine_for_parent	
   955                              <1> 	;
   956                              <1> 	;	@@: ; routine for child process here				
   957                              <1> 	;		....	
   958                              <1> 	;	NOTE: 'sysfork' returns to specified offset
   959                              <1> 	;	       for child process by using BX input.
   960                              <1> 	;	      (at first, parent process will return then 
   961                              <1> 	;	      child process will return -after swapped in-
   962                              <1> 	;	      'syswait' is needed in parent process
   963                              <1> 	;	      if return from child process will be waited for.)
   964                              <1> 	;	  				
   965                              <1> 	
   966                              <1> ; / create a new process
   967                              <1> 	; EBX = return address for child process 
   968                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
   969 0000A31C 31F6                <1> 	xor 	esi, esi
   970                              <1> 		; clr r1
   971                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
   972 0000A31E 46                  <1> 	inc	esi
   973                              <1> 		; inc r1
   974 0000A31F 80BE[BBE00000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
   975                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
   976 0000A326 760B                <1> 	jna	short sysfork_2	
   977                              <1> 		; beq 1f / it's unused so branch
   978 0000A328 6683FE10            <1> 	cmp	si, nproc
   979                              <1> 		; cmp r1,$nproc / all processes checked
   980 0000A32C 72F0                <1> 	jb	short sysfork_1
   981                              <1> 		; blt 1b / no, branch back
   982                              <1> 	;
   983                              <1> 	; Retro UNIX 8086 v1. modification:
   984                              <1> 	;	Parent process returns from 'sysfork' to address 
   985                              <1> 	;	which is just after 'sysfork' system call in parent
   986                              <1> 	;	process. Child process returns to address which is put
   987                              <1> 	;	in BX register by parent process for 'sysfork'. 
   988                              <1> 	;
   989                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
   990                              <1> 		             ; / to old process return
   991                              <1> 		; br error1 / no room for a new process
   992 0000A32E E954FDFFFF          <1> 	jmp	error
   993                              <1> sysfork_2: ; 1:
   994 0000A333 E8298EFFFF          <1> 	call	allocate_page
   995 0000A338 0F8249FDFFFF        <1> 	jc	error
   996 0000A33E 50                  <1> 	push	eax   ; UPAGE (user structure page) address
   997                              <1> 	; Retro UNIX 386 v1 modification!
   998 0000A33F E82690FFFF          <1> 	call	duplicate_page_dir
   999                              <1> 		; EAX = New page directory 
  1000 0000A344 730B                <1> 	jnc	short sysfork_3
  1001 0000A346 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1002 0000A347 E8ED8FFFFF          <1> 	call 	deallocate_page
  1003 0000A34C E936FDFFFF          <1> 	jmp	error
  1004                              <1> sysfork_3:
  1005                              <1> 	; Retro UNIX 386 v1 modification !
  1006 0000A351 56                  <1> 	push	esi
  1007 0000A352 E8B6180000          <1> 	call	wswap ; save current user (u) structure, user registers
  1008                              <1> 		      ; and interrupt return components (for IRET)
  1009 0000A357 8705[A1E30000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
  1010 0000A35D A3[A5E30000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
  1011 0000A362 5E                  <1> 	pop	esi
  1012 0000A363 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1013                              <1> 		; [u.usp] = esp
  1014 0000A364 89F7                <1> 	mov	edi, esi
  1015 0000A366 66C1E702            <1> 	shl	di, 2
  1016 0000A36A 8987[C8E00000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  1017 0000A370 A3[98E30000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  1018                              <1> 	; 28/08/2015
  1019 0000A375 0FB605[97E30000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  1020                              <1> 		; movb u.uno,-(sp) / save parent process number
  1021 0000A37C 89C7                <1> 	mov	edi, eax
  1022 0000A37E 50                  <1>         push	eax ; ** 
  1023 0000A37F 8A87[8BE00000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
  1024                              <1> 	; 18/09/2015
  1025                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
  1026                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
  1027 0000A385 668986[8BE00000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  1028                              <1> 				   ; ah - reset child's wait channel	
  1029 0000A38C 89F0                <1> 	mov	eax, esi
  1030 0000A38E A2[97E30000]        <1> 	mov	[u.uno], al ; child process number
  1031                              <1> 		;movb r1,u.uno / set child process number to r1
  1032 0000A393 FE86[BBE00000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
  1033                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
  1034                              <1> 				; / process to active status
  1035                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
  1036                              <1> 			      ; / control tty buffer in r2
  1037                              <1>                 ; beq 2f / branch, if no such tty assigned
  1038                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
  1039                              <1> 	; 2:
  1040 0000A399 53                  <1> 	push	ebx  ; * return address for the child process
  1041                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1042                              <1> 	; (Retro UNIX 8086 v1 modification!)
  1043                              <1> 		; mov $runq+4,r2
  1044 0000A39A E8D0180000          <1> 	call	putlu 
  1045                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  1046                              <1> 			   ; / run queue
  1047 0000A39F 66D1E6              <1> 	shl	si, 1
  1048                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  1049                              <1> 		       ; / into p.pid table
  1050 0000A3A2 66FF05[32E30000]    <1> 	inc	word [mpid]
  1051                              <1> 		; inc mpid / increment m.pid; get a new process name
  1052 0000A3A9 66A1[32E30000]      <1> 	mov	ax, [mpid]
  1053 0000A3AF 668986[2AE00000]    <1> 	mov	[esi+p.pid-2], ax
  1054                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
  1055                              <1> 				    ; / in child process' name slot
  1056 0000A3B6 5A                  <1> 	pop	edx  ; * return address for the child process
  1057                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1058 0000A3B7 5B                  <1>   	pop	ebx  ; **
  1059                              <1> 	;mov	ebx, [esp] ; ** parent process number
  1060                              <1> 		; movb (sp),r2 / put parent process number in r2
  1061 0000A3B8 66D1E3              <1> 	shl 	bx, 1
  1062                              <1> 		;asl r2 / multiply by 2 to get index into below tables
  1063                              <1> 	;movzx eax, word [ebx+p.pid-2]
  1064 0000A3BB 668B83[2AE00000]    <1> 	mov	ax, [ebx+p.pid-2]
  1065                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  1066                              <1> 				   ; / process
  1067 0000A3C2 668986[4AE00000]    <1> 	mov	[esi+p.ppid-2], ax
  1068                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  1069                              <1> 			  ; / in parent process slot for child
  1070 0000A3C9 A3[48E30000]        <1> 	mov	[u.r0], eax	
  1071                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  1072                              <1> 			     ; / at location where r0 was saved
  1073 0000A3CE 8B2D[40E30000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1074 0000A3D4 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  1075                              <1> 			   ; * return address for the child process
  1076                              <1> 		; mov $sysret1,-(sp) /
  1077                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  1078                              <1> 			      ; / user is swapped out
  1079                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  1080                              <1> 	; 04/09/2015 - 01/09/2015
  1081                              <1> 	; [u.usp] = esp
  1082 0000A3D7 68[A7A00000]        <1> 	push	sysret ; ***
  1083 0000A3DC 8925[44E30000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1084                              <1> 			     ; (for child process)	
  1085 0000A3E2 31C0                <1> 	xor 	eax, eax
  1086 0000A3E4 66A3[78E30000]      <1> 	mov 	[u.ttyp], ax ; 0
  1087                              <1> 	;
  1088 0000A3EA E81E180000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  1089                              <1> 		;jsr r0,wswap / put child process out on drum
  1090                              <1> 		;jsr r0,unpack / unpack user stack
  1091                              <1> 		;mov u.usp,sp / restore user stack pointer
  1092                              <1> 		; tst (sp)+ / bump stack pointer
  1093                              <1> 	; Retro UNIX 386 v1 modification !
  1094 0000A3EF 58                  <1> 	pop	eax ; ***
  1095 0000A3F0 66D1E3              <1> 	shl	bx, 1
  1096 0000A3F3 8B83[C8E00000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1097 0000A3F9 E838180000          <1> 	call	rswap ; restore parent process 'u' structure, 
  1098                              <1> 		      ; registers and return address (for IRET)
  1099                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  1100 0000A3FE 0FB705[32E30000]    <1>         movzx   eax, word [mpid]
  1101 0000A405 A3[48E30000]        <1> 	mov	[u.r0], eax
  1102                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  1103                              <1> 			       ; / where r0 was saved
  1104                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  1105                              <1> 			          ; / process return
  1106                              <1> 	;xor	ebx, ebx
  1107 0000A40A 31F6                <1> 	xor     esi, esi
  1108                              <1> 		;clr r1
  1109                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  1110                              <1> 	      ; / opened by the parent process
  1111                              <1> 	; 01/09/2015
  1112                              <1> 	;xor	bh, bh
  1113                              <1> 	;mov 	bl, [esi+u.fp]
  1114 0000A40C 8A86[4EE30000]      <1> 	mov 	al, [esi+u.fp]
  1115                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  1116                              <1>         ;or      bl, bl
  1117 0000A412 08C0                <1> 	or	al, al
  1118 0000A414 740D                <1> 	jz	short sysfork_5	
  1119                              <1> 		; beq 2f / file has not been opened by parent, 
  1120                              <1> 		       ; / so branch
  1121 0000A416 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1122 0000A418 F6E4                <1> 	mul	ah
  1123                              <1> 	;movzx	ebx, ax
  1124 0000A41A 6689C3              <1> 	mov	bx, ax
  1125                              <1> 	;shl     bx, 3
  1126                              <1> 		; asl r2 / multiply by 8
  1127                              <1>        		; asl r2 / to get index into fsp table
  1128                              <1>        		; asl r2
  1129 0000A41D FE83[1AE10000]      <1>   	inc     byte [ebx+fsp-2]
  1130                              <1> 		; incb fsp-2(r2) / increment number of processes
  1131                              <1> 			     ; / using file, because child will now be
  1132                              <1> 			     ; / using this file
  1133                              <1> sysfork_5: ; 2:
  1134 0000A423 46                  <1>         inc     esi
  1135                              <1> 		; inc r1 / get next open file
  1136 0000A424 6683FE0A            <1>         cmp     si, 10
  1137                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1138                              <1> 			  ; / can be opened
  1139 0000A428 72E2                <1> 	jb	short sysfork_4	
  1140                              <1> 		; blt 1b / check next entry
  1141 0000A42A E978FCFFFF          <1> 	jmp	sysret
  1142                              <1> 		; br sysret1
  1143                              <1> 
  1144                              <1> sysread: ; < read from file >
  1145                              <1> 	; 13/05/2015
  1146                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1147                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1148                              <1> 	;
  1149                              <1> 	; 'sysread' is given a buffer to read into and the number of
  1150                              <1> 	; characters to be read. If finds the file from the file
  1151                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  1152                              <1> 	; is returned from a successful open call (sysopen).
  1153                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  1154                              <1> 	; is read into core via 'readi'.
  1155                              <1> 	;
  1156                              <1> 	; Calling sequence:
  1157                              <1> 	;	sysread; buffer; nchars
  1158                              <1> 	; Arguments:
  1159                              <1> 	;	buffer - location of contiguous bytes where 
  1160                              <1> 	;		 input will be placed.
  1161                              <1> 	;	nchars - number of bytes or characters to be read.
  1162                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1163                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  1164                              <1> 	; ...............................................................
  1165                              <1> 	;				
  1166                              <1> 	; Retro UNIX 8086 v1 modification: 
  1167                              <1> 	;       'sysread' system call has three arguments; so,
  1168                              <1> 	;	* 1st argument, file descriptor is in BX register
  1169                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1170                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1171                              <1> 	;
  1172                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1173                              <1> 	;	to the user with number of bytes read. 
  1174                              <1> 	;
  1175 0000A42F E83D000000          <1> 	call	rw1
  1176 0000A434 0F824DFCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1177                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
  1178 0000A43A F6C480              <1> 	test	ah, 80h
  1179                              <1> 		; tst r1 / negative i-number?
  1180 0000A43D 0F8544FCFFFF        <1> 	jnz	error
  1181                              <1> 		; ble error1 / yes, error 1 to read
  1182                              <1> 			   ; / it should be positive
  1183 0000A443 E842140000          <1> 	call	readi
  1184                              <1> 		; jsr r0,readi / read data into core
  1185 0000A448 EB18                <1> 	jmp	short rw0
  1186                              <1> 		; br 1f
  1187                              <1> syswrite: ; < write to file >
  1188                              <1> 	; 13/05/2015
  1189                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1190                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1191                              <1> 	;
  1192                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  1193                              <1> 	; and the number of characters to write. If finds the file
  1194                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  1195                              <1> 	; descriptor is returned from a successful open or create call
  1196                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  1197                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  1198                              <1> 	;
  1199                              <1> 	; Calling sequence:
  1200                              <1> 	;	syswrite; buffer; nchars
  1201                              <1> 	; Arguments:
  1202                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  1203                              <1> 	;	nchars - number of characters to be written.
  1204                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1205                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  1206                              <1> 	; ...............................................................
  1207                              <1> 	;				
  1208                              <1> 	; Retro UNIX 8086 v1 modification: 
  1209                              <1> 	;       'syswrite' system call has three arguments; so,
  1210                              <1> 	;	* 1st argument, file descriptor is in BX register
  1211                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1212                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1213                              <1> 	;
  1214                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1215                              <1> 	;	to the user with number of bytes written. 
  1216                              <1> 	;
  1217 0000A44A E822000000          <1> 	call	rw1
  1218 0000A44F 0F8232FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1219                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
  1220 0000A455 F6C480              <1>         test	ah, 80h
  1221                              <1> 		; tst r1 / positive i-number ?
  1222 0000A458 744E                <1>         jz	short rw3 ; 13/05/2015
  1223                              <1> 	;jz	error
  1224                              <1> 		; bge error1 / yes, error 1 
  1225                              <1> 			   ; / negative i-number means write
  1226 0000A45A 66F7D8              <1>         neg	ax
  1227                              <1> 		; neg r1 / make it positive
  1228 0000A45D E881190000          <1> 	call	writei
  1229                              <1>         	; jsr r0,writei / write data
  1230                              <1> rw0: ; 1:
  1231 0000A462 A1[70E30000]        <1>         mov	eax, [u.nread]
  1232 0000A467 A3[48E30000]        <1> 	mov	[u.r0], eax
  1233                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  1234                              <1> 				  ; / into (u.r0)
  1235 0000A46C E936FCFFFF          <1> 	jmp	sysret
  1236                              <1>         	; br sysret1
  1237                              <1> rw1:	
  1238                              <1> 	; 14/05/2015
  1239                              <1> 	; 13/05/2015
  1240                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1241                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  1242                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
  1243                              <1> 	;
  1244                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
  1245                              <1> 				;(in the user's virtual memory space)
  1246                              <1> 	;mov	[u.count], edx 
  1247                              <1> 		; jsr r0,arg; u.base / get buffer pointer
  1248                              <1>         	; jsr r0,arg; u.count / get no. of characters
  1249                              <1> 	;;mov	eax, ebx ; file descriptor
  1250                              <1> 		; mov *u.r0,r1 / put file descriptor 
  1251                              <1> 		             ; / (index to u.fp table) in r1
  1252                              <1> 	; 13/05/2015
  1253 0000A471 C705[48E30000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  1253 0000A479 0000                <1>
  1254                              <1> 	;
  1255                              <1> 	;; call	getf
  1256                              <1>         ; eBX = File descriptor
  1257 0000A47B E8240A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
  1258                              <1> 		; jsr r0,getf / get i-number of the file in r1
  1259                              <1> 	; AX = I-number of the file ; negative i-number means write
  1260                              <1> 	; 13/05/2015
  1261 0000A480 6683F801            <1> 	cmp 	ax, 1
  1262 0000A484 7217                <1> 	jb	short rw2
  1263                              <1> 	;
  1264 0000A486 890D[68E30000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  1265                              <1> 				;(in the user's virtual memory space)
  1266 0000A48C 8915[6CE30000]      <1> 	mov	[u.count], edx 
  1267                              <1> 	; 14/05/2015
  1268 0000A492 C705[9DE30000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  1268 0000A49A 0000                <1>
  1269 0000A49C C3                  <1> 	retn
  1270                              <1>         	; rts r0
  1271                              <1> rw2:
  1272                              <1> 	; 13/05/2015
  1273 0000A49D C705[9DE30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1273 0000A4A5 0000                <1>
  1274 0000A4A7 C3                  <1> 	retn
  1275                              <1> rw3: 
  1276                              <1> 	; 13/05/2015
  1277 0000A4A8 C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1277 0000A4B0 0000                <1>
  1278 0000A4B2 F9                  <1> 	stc
  1279 0000A4B3 C3                  <1> 	retn
  1280                              <1> 
  1281                              <1> sysopen: ;<open file>
  1282                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1283                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  1284                              <1> 	;
  1285                              <1> 	; 'sysopen' opens a file in following manner:
  1286                              <1> 	;    1) The second argument in a sysopen says whether to
  1287                              <1> 	;	open the file ro read (0) or write (>0).
  1288                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  1289                              <1> 	;    3) The file is opened by 'iopen'.
  1290                              <1> 	;    4) Next housekeeping is performed on the fsp table
  1291                              <1> 	;	and the user's open file list - u.fp.
  1292                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  1293                              <1> 	;	b) An entry for the file is created in the fsp table.
  1294                              <1> 	;	c) The number of this entry is put on u.fp list.
  1295                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  1296                              <1> 	;	   to by u.r0.
  1297                              <1> 	;
  1298                              <1> 	; Calling sequence:
  1299                              <1> 	;	sysopen; name; mode
  1300                              <1> 	; Arguments:
  1301                              <1> 	;	name - file name or path name
  1302                              <1> 	;	mode - 0 to open for reading
  1303                              <1> 	;	       1 to open for writing
  1304                              <1> 	; Inputs: (arguments)
  1305                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  1306                              <1> 	;		  is put into r0's location on the stack.	
  1307                              <1> 	; ...............................................................
  1308                              <1> 	;				
  1309                              <1> 	; Retro UNIX 8086 v1 modification: 
  1310                              <1> 	;       'sysopen' system call has two arguments; so,
  1311                              <1> 	;	* 1st argument, name is pointed to by BX register
  1312                              <1> 	;	* 2nd argument, mode is in CX register
  1313                              <1> 	;
  1314                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1315                              <1> 	;	to the user with the file descriptor/number 
  1316                              <1> 	;	(index to u.fp list).
  1317                              <1> 	;
  1318                              <1> 	;call	arg2
  1319                              <1> 	; * name - 'u.namep' points to address of file/path name
  1320                              <1> 	;          in the user's program segment ('u.segmnt')
  1321                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1322                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1323                              <1> 	;          which is on top of stack.
  1324                              <1> 	;
  1325                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  1326                              <1> 	;
  1327                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  1328                              <1> 
  1329 0000A4B4 891D[60E30000]      <1> 	mov	[u.namep], ebx
  1330 0000A4BA 6651                <1> 	push	cx
  1331 0000A4BC E81A0A0000          <1> 	call	namei
  1332                              <1> 		; jsr r0,namei / i-number of file in r1
  1333                              <1>      	;and	ax, ax
  1334                              <1> 	;jz	error ; File not found
  1335 0000A4C1 723B                <1> 	jc	short fnotfound ; 14/05/2015
  1336                              <1> 	;jc	error ; 27/05/2013
  1337                              <1> 		; br  error2 / file not found
  1338 0000A4C3 665A                <1>    	pop	dx ; mode
  1339 0000A4C5 6652                <1> 	push	dx
  1340                              <1> 	;or	dx, dx
  1341 0000A4C7 08D2                <1> 	or	dl, dl
  1342                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
  1343                              <1> 		         ; / 0 means, open for read)
  1344 0000A4C9 7403                <1> 	jz	short sysopen_0
  1345                              <1> 		; beq 1f / yes, leave i-number positive
  1346                              <1> syscreat_0: ; 27/12/2015
  1347 0000A4CB 66F7D8              <1> 	neg	ax
  1348                              <1>         	; neg r1 / open for writing so make i-number negative
  1349                              <1> sysopen_0: ;1:
  1350 0000A4CE E811190000          <1> 	call	iopen
  1351                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
  1352 0000A4D3 665A                <1> 	pop	dx
  1353                              <1> 	;and	dx, dx
  1354 0000A4D5 20D2                <1> 	and	dl, dl
  1355                              <1>         	; tst (sp)+ / pop the stack and test the mode
  1356 0000A4D7 7403                <1> 	jz	short sysopen_2
  1357                              <1>         	; beq op1 / is open for read op1
  1358                              <1> sysopen_1: ;op0:
  1359 0000A4D9 66F7D8              <1> 	neg	ax
  1360                              <1>         	; neg r1 
  1361                              <1> 		     ;/ make i-number positive if open for writing [???]
  1362                              <1> 	;; NOTE: iopen always make i-number positive.
  1363                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
  1364                              <1> sysopen_2: ;op1:
  1365 0000A4DC 31F6                <1>         xor     esi, esi
  1366                              <1>         	; clr r2 / clear registers
  1367 0000A4DE 31DB                <1>         xor     ebx, ebx
  1368                              <1> 		; clr r3
  1369                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  1370 0000A4E0 389E[4EE30000]      <1>         cmp     [esi+u.fp], bl ; 0
  1371                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  1372 0000A4E6 7625                <1>         jna      short sysopen_4
  1373                              <1> 		; beq 1f / if byte in list is 0 branch
  1374 0000A4E8 46                  <1>         inc     esi
  1375                              <1> 		; inc r2 / bump r2 so next byte can be checked
  1376 0000A4E9 6683FE0A            <1>         cmp     si, 10
  1377                              <1> 		; cmp r2,$10. / reached end of list?
  1378 0000A4ED 72F1                <1> 	jb	short sysopen_3
  1379                              <1> 		; blt 1b / no, go back
  1380                              <1> toomanyf:
  1381                              <1> 	; 14/05/2015
  1382 0000A4EF C705[9DE30000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  1382 0000A4F7 0000                <1>
  1383 0000A4F9 E989FBFFFF          <1> 	jmp	error
  1384                              <1>         	; br error2 / yes, error (no files open)
  1385                              <1> fnotfound: 
  1386                              <1> 	; 14/05/2015
  1387 0000A4FE C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  1387 0000A506 0000                <1>
  1388 0000A508 E97AFBFFFF          <1> 	jmp	error
  1389                              <1> 
  1390                              <1> sysopen_4: ; 1:
  1391 0000A50D 6683BB[1CE10000]00  <1>         cmp     word [ebx+fsp], 0
  1392                              <1> 		; tst fsp(r3) / scan fsp entries
  1393 0000A515 7610                <1>         jna     short sysopen_5
  1394                              <1> 		; beq 1f / if 0 branch
  1395                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
  1396 0000A517 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
  1397                              <1> 		; add $8.,r3 / add 8 to r3 
  1398                              <1> 			; / to bump it to next entry mfsp table
  1399 0000A51B 6681FBF401          <1>         cmp     bx, nfiles*10
  1400                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  1401 0000A520 72EB                <1> 	jb	short sysopen_4
  1402                              <1>        		; blt 1b / no, back
  1403 0000A522 E960FBFFFF          <1> 	jmp	error
  1404                              <1>         	; br error2 / yes, error
  1405                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
  1406 0000A527 668983[1CE10000]    <1>         mov     [ebx+fsp], ax
  1407                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
  1408                              <1> 			; / into next available entry in fsp table,
  1409 0000A52E 668B3D[2AE30000]    <1> 	mov	di, [cdev] ; word ? byte ?
  1410 0000A535 6689BB[1EE10000]    <1>         mov     [ebx+fsp+2], di ; device number
  1411                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
  1412 0000A53C 31FF                <1>         xor	edi, edi
  1413 0000A53E 89BB[20E10000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
  1414                              <1> 		; clr fsp+4(r3)
  1415 0000A544 6689BB[24E10000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
  1416                              <1>        		; clr fsp+6(r3) / clear the next two words
  1417 0000A54B 89D8                <1>   	mov	eax, ebx
  1418 0000A54D B30A                <1> 	mov	bl, 10
  1419 0000A54F F6F3                <1> 	div	bl 
  1420                              <1> 		; asr r3
  1421                              <1> 		; asr r3 / divide by 8 
  1422                              <1> 		; asr r3 ; / to get number of the fsp entry-1
  1423 0000A551 FEC0                <1> 	inc	al
  1424                              <1>         	; inc r3 / add 1 to get fsp entry number
  1425 0000A553 8886[4EE30000]      <1>         mov     [esi+u.fp], al
  1426                              <1> 		; movb r3,u.fp(r2) / move entry number into 
  1427                              <1> 			; / next available slot in u.fp list
  1428 0000A559 8935[48E30000]      <1>         mov     [u.r0], esi
  1429                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
  1430                              <1> 			     ; / into r0 loc on stack
  1431 0000A55F E943FBFFFF          <1>         jmp	sysret
  1432                              <1> 		; br sysret2
  1433                              <1> 
  1434                              <1> 	;
  1435                              <1> 	; 'fsp' table (10 bytes/entry)
  1436                              <1> 	; bit 15				   bit 0
  1437                              <1> 	; ---|-------------------------------------------
  1438                              <1> 	; r/w|		i-number of open file
  1439                              <1> 	; ---|-------------------------------------------
  1440                              <1> 	;		   device number
  1441                              <1> 	; -----------------------------------------------
  1442                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  1443                              <1> 	; -----------------------------------------------
  1444                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  1445                              <1> 	; ----------------------|------------------------
  1446                              <1> 	;  flag that says file 	| number of processes
  1447                              <1> 	;   has been deleted	| that have file open 
  1448                              <1> 	; ----------------------|------------------------
  1449                              <1> 	;
  1450                              <1> 
  1451                              <1> syscreat: ; < create file >
  1452                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  1453                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1454                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  1455                              <1> 	;
  1456                              <1> 	; 'syscreat' called with two arguments; name and mode.
  1457                              <1> 	; u.namep points to name of the file and mode is put
  1458                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  1459                              <1> 	; If the file aready exists, it's mode and owner remain 
  1460                              <1> 	; unchanged, but it is truncated to zero length. If the file
  1461                              <1> 	; did not exist, an i-node is created with the new mode via
  1462                              <1> 	; 'maknod' whether or not the file already existed, it is
  1463                              <1> 	; open for writing. The fsp table is then searched for a free
  1464                              <1> 	; entry. When a free entry is found, proper data is placed
  1465                              <1> 	; in it and the number of this entry is put in the u.fp list.
  1466                              <1> 	; The index to the u.fp (also know as the file descriptor)
  1467                              <1> 	; is put in the user's r0. 			
  1468                              <1> 	;
  1469                              <1> 	; Calling sequence:
  1470                              <1> 	;	syscreate; name; mode
  1471                              <1> 	; Arguments:
  1472                              <1> 	;	name - name of the file to be created
  1473                              <1> 	;	mode - mode of the file to be created
  1474                              <1> 	; Inputs: (arguments)
  1475                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  1476                              <1> 	;		   (the file descriptor of new file)
  1477                              <1> 	; ...............................................................
  1478                              <1> 	;				
  1479                              <1> 	; Retro UNIX 8086 v1 modification: 
  1480                              <1> 	;       'syscreate' system call has two arguments; so,
  1481                              <1> 	;	* 1st argument, name is pointed to by BX register
  1482                              <1> 	;	* 2nd argument, mode is in CX register
  1483                              <1> 	;
  1484                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1485                              <1> 	;	to the user with the file descriptor/number 
  1486                              <1> 	;	(index to u.fp list).
  1487                              <1> 	;
  1488                              <1> 	;call	arg2
  1489                              <1> 	; * name - 'u.namep' points to address of file/path name
  1490                              <1> 	;          in the user's program segment ('u.segmnt')
  1491                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1492                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1493                              <1> 	;          which is on top of stack.
  1494                              <1> 	;
  1495                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
  1496                              <1> 			    ; / on stack
  1497 0000A564 891D[60E30000]      <1> 	mov	[u.namep], ebx ; file name address
  1498 0000A56A 6651                <1> 	push	cx ; mode
  1499 0000A56C E86A090000          <1> 	call 	namei        	
  1500                              <1> 		; jsr r0,namei / get the i-number
  1501                              <1>         ;and	ax, ax
  1502                              <1> 	;jz	short syscreat_1	       	
  1503 0000A571 721E                <1> 	jc	short syscreat_1
  1504                              <1> 		; br  2f / if file doesn't exist 2f
  1505                              <1> 	; 27/12/2015
  1506 0000A573 6683F829            <1> 	cmp	ax, 41 ; device inode ?
  1507 0000A577 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
  1508                              <1> 	;
  1509 0000A57D 66F7D8              <1> 	neg 	ax
  1510                              <1>         	; neg r1 / if file already exists make i-number 
  1511                              <1> 		       ; / negative (open for writing)
  1512 0000A580 E85F180000          <1> 	call	iopen
  1513                              <1>         	; jsr r0,iopen /
  1514 0000A585 E85C180000          <1> 	call	itrunc
  1515                              <1>         	; jsr r0,itrunc / truncate to 0 length
  1516 0000A58A 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
  1517 0000A58C E948FFFFFF          <1>         jmp     sysopen_1
  1518                              <1>         	; br op0
  1519                              <1> syscreat_1: ; 2: / file doesn't exist
  1520 0000A591 6658                <1> 	pop	ax
  1521                              <1>         	; mov (sp)+,r1 / put the mode in r1
  1522 0000A593 30E4                <1> 	xor	ah, ah	
  1523                              <1>         	; bic $!377,r1 / clear upper byte
  1524 0000A595 E8140C0000          <1> 	call 	maknod
  1525                              <1>         	; jsr r0,maknod / make an i-node for this file
  1526 0000A59A 66A1[7AE30000]      <1> 	mov	ax, [u.dirbuf]
  1527                              <1>         	; mov u.dirbuf,r1 / put i-number 
  1528                              <1> 			        ; / for this new file in r1
  1529 0000A5A0 E934FFFFFF          <1>         jmp     sysopen_1
  1530                              <1>         	; br op0 / open the file
  1531                              <1> 
  1532                              <1> sysmkdir: ; < make directory >
  1533                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1534                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1535                              <1> 	;
  1536                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  1537                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  1538                              <1> 	; The special entries '.' and '..' are not present.
  1539                              <1> 	; Errors are indicated if the directory already exists or		
  1540                              <1> 	; user is not the super user. 
  1541                              <1> 	;
  1542                              <1> 	; Calling sequence:
  1543                              <1> 	;	sysmkdir; name; mode
  1544                              <1> 	; Arguments:
  1545                              <1> 	;	name - points to the name of the directory
  1546                              <1> 	;	mode - mode of the directory
  1547                              <1> 	; Inputs: (arguments)
  1548                              <1> 	; Outputs: -
  1549                              <1> 	;    (sets 'directory' flag to 1; 
  1550                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  1551                              <1> 	; ...............................................................
  1552                              <1> 	;				
  1553                              <1> 	; Retro UNIX 8086 v1 modification: 
  1554                              <1> 	;       'sysmkdir' system call has two arguments; so,
  1555                              <1> 	;	* 1st argument, name is pointed to by BX register
  1556                              <1> 	;	* 2nd argument, mode is in CX register
  1557                              <1> 	;
  1558                              <1> 		
  1559                              <1> ; / make a directory
  1560                              <1> 
  1561                              <1> 	;call	arg2
  1562                              <1> 	; * name - 'u.namep' points to address of file/path name
  1563                              <1> 	;          in the user's program segment ('u.segmnt')
  1564                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1565                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1566                              <1> 	;          which is on top of stack.
  1567                              <1> 
  1568                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
  1569                              <1> 			    ; / on stack
  1570 0000A5A5 891D[60E30000]      <1> 	mov	[u.namep], ebx
  1571 0000A5AB 6651                <1> 	push	cx ; mode
  1572 0000A5AD E829090000          <1> 	call	namei
  1573                              <1>         	; jsr r0,namei / get the i-number
  1574                              <1>         	;     br .+4 / if file not found branch around error
  1575                              <1>         ;xor 	ax, ax
  1576                              <1> 	;jnz	error
  1577 0000A5B2 731C                <1> 	jnc	short dir_exists ; 14/05/2015
  1578                              <1> 	;jnc	error	
  1579                              <1> 		; br  error2 / directory already exists (error)
  1580 0000A5B4 803D[94E30000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  1581                              <1>         	;tstb u.uid / is user the super user
  1582 0000A5BB 7622                <1> 	jna	short dir_access_err ; 14/05/2015
  1583                              <1> 	;jna	error
  1584                              <1>         	;bne error2 / no, not allowed
  1585 0000A5BD 6658                <1> 	pop	ax
  1586                              <1>         	;mov (sp)+,r1 / put the mode in r1
  1587 0000A5BF 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
  1588                              <1>         	;bic $!317,r1 / all but su and ex
  1589                              <1> 	;or	ax , 4000h ; 1011111111111111b
  1590 0000A5C3 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
  1591                              <1>         	;bis $40000,r1 / directory flag
  1592 0000A5C6 E8E30B0000          <1> 	call	maknod
  1593                              <1>         	;jsr r0,maknod / make the i-node for the directory
  1594 0000A5CB E9D7FAFFFF          <1> 	jmp	sysret
  1595                              <1>         	;br sysret2 /
  1596                              <1> dir_exists:
  1597                              <1> 	; 14/05/2015
  1598 0000A5D0 C705[9DE30000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
  1598 0000A5D8 0000                <1>
  1599 0000A5DA E9A8FAFFFF          <1> 	jmp	error
  1600                              <1> dir_access_err:
  1601                              <1> 	; 14/05/2015
  1602 0000A5DF C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  1602 0000A5E7 0000                <1>
  1603 0000A5E9 E999FAFFFF          <1> 	jmp	error
  1604                              <1> 
  1605                              <1> sysclose: ;<close file>
  1606                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1607                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  1608                              <1> 	;
  1609                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  1610                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  1611                              <1> 	; is put in r1 and 'fclose' is called.
  1612                              <1> 	;
  1613                              <1> 	; Calling sequence:
  1614                              <1> 	;	sysclose
  1615                              <1> 	; Arguments:
  1616                              <1> 	;	-  
  1617                              <1> 	; Inputs: *u.r0 - file descriptor
  1618                              <1> 	; Outputs: -
  1619                              <1> 	; ...............................................................
  1620                              <1> 	;				
  1621                              <1> 	; Retro UNIX 8086 v1 modification:
  1622                              <1> 	;	 The user/application program puts file descriptor
  1623                              <1> 	;        in BX register as 'sysclose' system call argument.
  1624                              <1> 	; 	 (argument transfer method 1)
  1625                              <1> 
  1626                              <1> 	; / close the file
  1627                              <1> 	
  1628 0000A5EE 89D8                <1> 	mov 	eax, ebx
  1629 0000A5F0 E864080000          <1> 	call 	fclose
  1630                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
  1631                              <1> 		; jsr r0,fclose / close the file
  1632                              <1>                	; br error2 / unknown file descriptor
  1633                              <1> 		; br sysret2
  1634                              <1> 	; 14/05/2015
  1635 0000A5F5 0F83ACFAFFFF        <1> 	jnc	sysret
  1636 0000A5FB C705[9DE30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1636 0000A603 0000                <1>
  1637 0000A605 E97DFAFFFF          <1> 	jmp	error
  1638                              <1> 
  1639                              <1> sysemt: ; enable (or disable) multi tasking -time sharing-
  1640                              <1> 	;
  1641                              <1> 	; 23/05/2016 - TRDOS 386 (TRDOS v2.0)
  1642                              <1> 	; 14/05/2015 (Retro UNIX 386 v1)
  1643                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  1644                              <1> 	;
  1645                              <1> 	; Retro UNIX 8086 v1 modification: 
  1646                              <1> 	;	'Enable Multi Tasking'  system call instead 
  1647                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  1648                              <1> 	;
  1649                              <1> 	; Retro UNIX 8086 v1 feature only!
  1650                              <1> 	;	Using purpose: Kernel will start without time-out
  1651                              <1> 	;	(internal clock/timer) functionality.
  1652                              <1> 	;	Then etc/init will enable clock/timer for
  1653                              <1> 	;	multi tasking. 
  1654                              <1> 	;
  1655                              <1> 	; INPUT ->
  1656                              <1> 	;	BL = 0 -> disable multi tasking
  1657                              <1> 	;	BL > 1 -> enable multi tasking (time sharing) 
  1658                              <1> 	; OUTPUT ->
  1659                              <1> 	;	none	
  1660                              <1> 	;
  1661                              <1> 	;  Note: Multi tasking is disabled during system
  1662                              <1> 	;	 initialization, it must be enabled by using
  1663                              <1> 	;	 this system call. (Otherwise, running proces 
  1664                              <1> 	;	 will not be changed by another process within
  1665                              <1> 	;	 run time sequence/schedule, if running process
  1666                              <1> 	;	 will not 'release' itself. Only 'wakeup' procedure
  1667                              <1> 	;	 for waiting processes and programmed timer events
  1668                              <1> 	;	 for other processes can change running process 
  1669                              <1> 	;	 while multi tasking is disabled.) ** 23/05/2016 **
  1670                              <1> 
  1671 0000A60A 803D[94E30000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  1672                              <1> 	;ja	error
  1673 0000A611 0F8719FBFFFF        <1> 	ja	badsys ; 14/05/2015
  1674                              <1> 	;
  1675 0000A617 FA                  <1> 	cli
  1676 0000A618 881D[0AE00000]      <1> 	mov	[multi_tasking], bl ; 0 to disable, >0 to enable
  1677 0000A61E E984FAFFFF          <1> 	jmp	sysret
  1678                              <1> 
  1679                              <1> systimer:
  1680                              <1> 	; 21/05/2016
  1681                              <1> 	; 19/05/2016
  1682                              <1> 	; 18/05/2016 - TRDOS 386 (TRDOS v2.0)
  1683                              <1> 	; (TRDOS 386 feature only!)
  1684                              <1> 	;
  1685                              <1> 	; (start or stop timer event(s))	
  1686                              <1> 	;
  1687                              <1> 	; INPUT ->
  1688                              <1> 	;	BL = Signal return byte (response byte)
  1689                              <1> 	;	     (Any requested value between 0 and 255)
  1690                              <1> 	;	     (Kernel will put it at the requested address)    	
  1691                              <1> 	;	BH = Time count unit
  1692                              <1> 	;	     0 = Stop timer event
  1693                              <1> 	;	     1 = 18.2 ticks per second
  1694                              <1> 	;	     2 = 10 milliseconds  		
  1695                              <1> 	;	     3 = 1 second (for real time clock interrupt) 	 
  1696                              <1> 	;	     4 to 255 = undefined
  1697                              <1> 	;	BH = 0 -> Stop timer event
  1698                              <1> 	;	BL = Timer event number (1 to 255) if BH = 0     	
  1699                              <1> 	;	     If BL = 0, all timer events (which are belongs
  1700                              <1> 	;	      to running process) will be stopped 		    
  1701                              <1> 	;	ECX = Time/Tick count (depending on time count unit)
  1702                              <1> 	;	EDX = Signal return (Response) byte address
  1703                              <1> 	;	      (virtual address in user's memory space)
  1704                              <1> 	; OUTPUT ->
  1705                              <1> 	;	AL = Timer event number	(1 to 255) (max. value = 16)
  1706                              <1> 	;	IF BH Input = 0 & CF = 0 & AL = 0 -> 
  1707                              <1> 	;	     timer event(s) has/have been stopped/finished 
  1708                              <1> 	;	CF = 1 & AL = 0 -> no timer setting space to set
  1709                              <1> 	;	CF = 1 & AL > 0 -> timer count unit is not usable
  1710                              <1> 	;
  1711                              <1> 	;	NOTE: To modify a time count for a user function,
  1712                              <1> 	;	      at first, current timer event must be stopped
  1713                              <1> 	;	      then a new timer event (which is related with
  1714                              <1> 	;	      same user function) must be started.
  1715                              <1> 	;		
  1716                              <1> 	;	      Signal return (response) byte may be used for 
  1717                              <1> 	;	      several purposes. Kernel will put this value 
  1718                              <1> 	;	      to requested address during timer interrupt,
  1719                              <1> 	;	      program/user can check this value to understand
  1720                              <1> 	;	      which event has been occurred and what is changed.
  1721                              <1> 	;	      (Multi timer events can share same signal address)
  1722                              <1> 	;	
  1723                              <1> 	;	NOTE: If the process is running while the time count
  1724                              <1> 	;	      is reached, kernel will put signal return (response)
  1725                              <1> 	;	      byte value at requested address during timer
  1726                              <1> 	;	      interrupt and the process will continue to run.
  1727                              <1> 	;	      Program/process must call (jump to) it's timer event
  1728                              <1> 	;	      function as required, for checking the timer event
  1729                              <1> 	;	      status via signal return (response) byte address. 
  1730                              <1> 	;
  1731                              <1> 	;	      If the process is not running (waiting or sleeping
  1732                              <1> 	;	      or released) while the time count is reached,
  1733                              <1> 	;	      it is restarted from where it left, to ensure
  1734                              <1> 	;	      proper multi media (video, audio, clock, timer)
  1735                              <1> 	;	      functionality.
  1736                              <1> 	;
  1737                              <1> 	;	      (It is better to use 'syswait' or 'syssleep',
  1738                              <1> 	;	      or 'sysrele' system call just after the timer
  1739                              <1> 	;	      function. Otherwise, timer events may block other
  1740                              <1> 	;	      processes which are not using timer events.)  	 		 			 		 	
  1741                              <1> 	;	     	      		 			
  1742                              <1> 	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  1743                              <1> 	;       Owner:	        resw 1 ; 0 = free
  1744                              <1> 	;		  	       ;>0 = process ID (p.pid)
  1745                              <1> 	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  1746                              <1> 	;		   	       ; 1 = Real Time Clock interrupt 
  1747                              <1> 	;	Response:       resb 1 ; 0 to 255, signal return value
  1748                              <1> 	;	Count Limit:	resd 1 ; count of ticks (total/set)
  1749                              <1> 	;	Current Count: 	resd 1 ; count of ticks (current)
  1750                              <1> 	;	Response Addr:  resd 1 ; response byte (pointer) address
  1751                              <1> 	;
  1752                              <1> 
  1753 0000A623 80FF02              <1> 	cmp	bh, 2
  1754 0000A626 0F8419010000        <1>         je      systimer_15       ; only 18.2 ticks per second is usable
  1755                              <1> 				  ; 10 milliseconds (100 Hertz) timer 
  1756                              <1> 				  ; will be set later (18/05/2016)
  1757 0000A62C 7740                <1> 	ja	short systimer_2 
  1758                              <1> 
  1759 0000A62E 20FF                <1> 	and	bh, bh
  1760 0000A630 7449                <1> 	jz	short systimer_3 ; stop timer event(s)
  1761                              <1> 
  1762                              <1> 	; bh = 1 (timer interrupt, 18.2 Hz, IBM PC/AT ROMBIOS default)
  1763                              <1> 
  1764 0000A632 B00A                <1> 	mov	al, 10 ; (*)
  1765                              <1> systimer_1:
  1766 0000A634 50                  <1> 	push	eax ; (*)
  1767 0000A635 B710                <1> 	mov	bh, 16
  1768 0000A637 E81F010000          <1> 	call	systimer_18 ; search for free timer space
  1769 0000A63C 0F8209010000        <1>         jc      systimer_16
  1770                              <1> 	; edi = address of empty timer event area
  1771 0000A642 A0[97E30000]        <1> 	mov	al, [u.uno]
  1772 0000A647 D0E0                <1> 	shl	al, 1
  1773 0000A649 89C6                <1> 	mov	esi, eax
  1774                              <1> 	; esi = process id offset + 2
  1775 0000A64B 668B86[2AE00000]    <1> 	mov	ax, [esi+p.pid-2] ; process ID
  1776 0000A652 FA                  <1> 	cli 	; disable interrupts 
  1777 0000A653 66AB                <1> 	stosw
  1778 0000A655 B001                <1> 	mov	al, 1 ; this is for real time clock interrupt
  1779 0000A657 AA                  <1> 	stosb
  1780 0000A658 88D8                <1> 	mov	al, bl ; Signal return (Response) value
  1781 0000A65A AA                  <1> 	stosb
  1782 0000A65B 58                  <1> 	pop	eax ; (*) ; 10 or 182
  1783 0000A65C 89D3                <1> 	mov	ebx, edx ; virtual address for response/signal byte
  1784 0000A65E F7E1                <1> 	mul	ecx
  1785                              <1> 	; (eax = 10 * count of 18.2 Hz timer ticks)
  1786                              <1> 	; (count down step = 10)
  1787 0000A660 AB                  <1> 	stosd  ; count limit (reset value)
  1788 0000A661 AB                  <1> 	stosd  ; current count value
  1789                              <1> 	; ebx = virtual address
  1790                              <1> 	; [u.pgdir] = page directory's physical address
  1791 0000A662 E8C591FFFF          <1> 	call	get_physical_addr
  1792                              <1> 	; eax = physical address of the virtual address in user's space
  1793 0000A667 AB                  <1> 	stosd
  1794 0000A668 FB                  <1> 	sti 	; enable interrupts
  1795 0000A669 E939FAFFFF          <1> 	jmp	sysret
  1796                              <1> 	
  1797                              <1> systimer_2:
  1798 0000A66E 80FF03              <1> 	cmp	bh, 3
  1799 0000A671 0F87CE000000        <1>         ja      systimer_15     ; undefined time count unit
  1800                              <1> 
  1801                              <1> 	; bh = 3
  1802                              <1> 	; timer event via real time clock interrupt
  1803                              <1> 	; interrupt/update frequency: 1 Hz (1 tick per second)
  1804                              <1> 	
  1805 0000A677 B0B6                <1> 	mov	al, 182 ; (*) ; 18.2 * 10
  1806 0000A679 EBB9                <1> 	jmp	short systimer_1
  1807                              <1> 
  1808                              <1> systimer_3:
  1809                              <1> 	; Note: ecx and edx are undefined here
  1810                              <1> 	;	(for stop timer function)
  1811                              <1> 
  1812 0000A67B BE[0CF00000]        <1> 	mov	esi, timer_set  ; beginning address of timer events
  1813                              <1> 				; setting space	 
  1814 0000A680 A0[97E30000]        <1> 	mov	al, [u.uno]
  1815 0000A685 D0E0                <1> 	shl	al, 1
  1816 0000A687 89C7                <1> 	mov	edi, eax
  1817 0000A689 668B8F[2AE00000]    <1> 	mov	cx, [edi+p.pid-2]
  1818                              <1> 
  1819 0000A690 08DB                <1> 	or	bl, bl
  1820 0000A692 756B                <1> 	jnz	short systimer_12
  1821                              <1> 
  1822                              <1> 	; clear timer event areas belong to current process
  1823                              <1> 	; (for stopping all timer events belong to current process) 
  1824 0000A694 B710                <1> 	mov	bh, 16
  1825 0000A696 881D[48E30000]      <1> 	mov	[u.r0], bl ; 0
  1826 0000A69C FA                  <1> 	cli 	; disable interrupts
  1827                              <1> systimer_4:
  1828 0000A69D 668B06              <1> 	mov	ax, [esi]
  1829 0000A6A0 6609C0              <1> 	or	ax, ax ; 0 ?
  1830 0000A6A3 7437                <1> 	jz	short systimer_10  ; the last timer event area 	
  1831 0000A6A5 89F7                <1> 	mov	edi, esi
  1832 0000A6A7 83C610              <1> 	add	esi, 16
  1833 0000A6AA 6639C8              <1> 	cmp	ax, cx ; is the process ID (owner) same ?
  1834 0000A6AD 7406                <1> 	je	short systimer_5 ; yes
  1835 0000A6AF FECF                <1> 	dec	bh
  1836 0000A6B1 75EA                <1> 	jnz	short systimer_4
  1837 0000A6B3 EB27                <1> 	jmp	short systimer_10 
  1838                              <1> 
  1839                              <1> systimer_5:
  1840 0000A6B5 80FF01              <1> 	cmp	bh, 1
  1841 0000A6B8 761B                <1> 	jna	short systimer_8 ; clear only, do not move back
  1842                              <1> systimer_6:
  1843 0000A6BA 89FA                <1> 	mov	edx, edi
  1844                              <1> systimer_7:
  1845                              <1> 	; move next event to back (instead of stopped event)
  1846 0000A6BC A5                  <1> 	movsd
  1847 0000A6BD A5                  <1> 	movsd
  1848 0000A6BE A5                  <1> 	movsd
  1849 0000A6BF A5                  <1> 	movsd
  1850 0000A6C0 FECF                <1> 	dec	bh
  1851 0000A6C2 7418                <1> 	jz	short systimer_10
  1852 0000A6C4 668B06              <1> 	mov	ax, [esi] ; Owner ID (of timer event)
  1853 0000A6C7 6621C0              <1> 	and	ax, ax
  1854 0000A6CA 7409                <1> 	jz	short systimer_8
  1855 0000A6CC 6639C8              <1> 	cmp	ax, cx
  1856 0000A6CF 75E9                <1> 	jne	short systimer_6
  1857                              <1> 	; same process ID, remove this event too
  1858 0000A6D1 89D7                <1> 	mov	edi, edx
  1859 0000A6D3 EBE7                <1> 	jmp	short systimer_7
  1860                              <1> 
  1861                              <1> systimer_8:
  1862                              <1> 	; clear timer event area (belong to current process)
  1863                              <1> 	; (this timer event will be stopped/finished)
  1864 0000A6D5 6631C0              <1> 	xor	ax, ax ; eax = 0
  1865                              <1> systimer_9:
  1866 0000A6D8 AB                  <1> 	stosd
  1867 0000A6D9 AB                  <1> 	stosd	
  1868 0000A6DA AB                  <1> 	stosd
  1869 0000A6DB AB                  <1> 	stosd
  1870                              <1> 
  1871                              <1> systimer_10:
  1872 0000A6DC 0FB635[97E30000]    <1> 	movzx	esi, byte [u.uno]
  1873 0000A6E3 08DB                <1> 	or	bl, bl ; all timer events or one timer event ?
  1874 0000A6E5 740C                <1> 	jz	short systimer_11
  1875 0000A6E7 8A9E[0BE10000]      <1> 	mov	bl, [esi+p.timer-1]
  1876 0000A6ED 20DB                <1> 	and	bl, bl	; previous number of timer events for the process
  1877 0000A6EF 7402                <1> 	jz	short systimer_11
  1878 0000A6F1 FECB                <1> 	dec	bl   ; previous number of timer event for the process - 1
  1879                              <1> systimer_11:
  1880 0000A6F3 889E[0BE10000]      <1> 	mov	[esi+p.timer-1], bl ; 0 ; no timer events for process
  1881 0000A6F9 FB                  <1> 	sti	; enable interrupts
  1882 0000A6FA E9A8F9FFFF          <1> 	jmp	sysret
  1883                              <1> 
  1884                              <1> systimer_12:
  1885 0000A6FF 80FB10              <1> 	cmp	bl, 16
  1886 0000A702 7738                <1> 	ja	short systimer_14 ; max. 16 timer events !
  1887                              <1> 	;
  1888 0000A704 88DA                <1> 	mov	dl, bl
  1889 0000A706 FECA                <1> 	dec	dl  ; 16 -> 15 ... 1 -> 0 
  1890 0000A708 C0E204              <1> 	shl	dl, 4 ; * 16
  1891 0000A70B 0FB6FA              <1> 	movzx	edi, dl
  1892 0000A70E 01F7                <1> 	add	edi, esi ; timer_set 
  1893                              <1> 	
  1894 0000A710 663B0F              <1> 	cmp	cx, [edi] ; process ID
  1895 0000A713 7527                <1> 	jne 	short systimer_14
  1896                              <1> 	
  1897                              <1> 	; same process ID
  1898 0000A715 FA                  <1> 	cli	; disable interrupts
  1899 0000A716 B711                <1> 	mov	bh, 17
  1900 0000A718 28DF                <1> 	sub	bh, bl ; remain count of timer event areas + 1
  1901 0000A71A 881D[48E30000]      <1> 	mov	[u.r0], bl ; timer event number which is stopped/cleared
  1902 0000A720 80FF01              <1> 	cmp	bh, 1
  1903 0000A723 76B0                <1> 	jna	short systimer_8
  1904 0000A725 89FE                <1> 	mov	esi, edi
  1905 0000A727 83C610              <1> 	add	esi, 16
  1906                              <1> 	; move next event to back (instead of stopped event)
  1907                              <1> systimer_13:
  1908 0000A72A A5                  <1> 	movsd
  1909 0000A72B A5                  <1> 	movsd
  1910 0000A72C A5                  <1> 	movsd
  1911 0000A72D A5                  <1> 	movsd
  1912 0000A72E FECF                <1> 	dec	bh
  1913 0000A730 74AA                <1> 	jz	short systimer_10
  1914 0000A732 668B06              <1> 	mov	ax, [esi] ; Owner ID (of timer event)
  1915 0000A735 6621C0              <1> 	and	ax, ax
  1916 0000A738 749E                <1> 	jz	short systimer_9
  1917 0000A73A EBEE                <1> 	jmp	short systimer_13
  1918                              <1> 
  1919                              <1> systimer_14:	
  1920 0000A73C C605[48E30000]00    <1> 	mov	byte [u.r0], 0
  1921 0000A743 EB07                <1>         jmp     short systimer_17 
  1922                              <1> 	
  1923                              <1> systimer_15:
  1924 0000A745 883D[48E30000]      <1> 	mov	[u.r0], bh ; Time count unit (=2 or >3)
  1925                              <1> systimer_16:
  1926 0000A74B 58                  <1> 	pop	eax ; (*) discard
  1927                              <1> systimer_17:
  1928 0000A74C C705[9DE30000]1A00- <1>         mov     dword [u.error], ERR_MISC
  1928 0000A754 0000                <1>
  1929                              <1>                                 ; one of miscellaneous/other errors
  1930 0000A756 E92CF9FFFF          <1> 	jmp	error
  1931                              <1> 
  1932                              <1> systimer_18:
  1933 0000A75B BF[0CF00000]        <1> 	mov	edi, timer_set  ; beginning address of timer events
  1934                              <1> 				; setting space
  1935 0000A760 30C0                <1> 	xor	al, al ; 0
  1936                              <1> systimer_19:
  1937 0000A762 FEC0                <1> 	inc	al
  1938 0000A764 66833F00            <1> 	cmp	word [edi], 0 ; is it free space ?
  1939 0000A768 760A                <1> 	jna	short systimer_20 ; yes
  1940 0000A76A 83C710              <1> 	add	edi, 16
  1941 0000A76D FECF                <1> 	dec	bh
  1942 0000A76F 75F1                <1> 	jnz	short systimer_19 ; next event space
  1943                              <1> 	; no timer event setting space !
  1944 0000A771 28C0                <1> 	sub	al, al ; 0
  1945 0000A773 F9                  <1> 	stc
  1946                              <1> systimer_20:
  1947 0000A774 A2[48E30000]        <1> 	mov	[u.r0], al ; timer event number
  1948 0000A779 C3                  <1> 	retn
  1949                              <1> 
  1950                              <1> sysmdate: ; < change the modification time of a file >
  1951                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  1952                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1953                              <1> 	;
  1954                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
  1955                              <1> 	; file into core. The user is checked if he is the owner 
  1956                              <1> 	; or super user. If he is neither an error occurs.
  1957                              <1> 	; 'setimod' is then called to set the i-node modification
  1958                              <1> 	; byte and the modification time, but the modification time
  1959                              <1> 	; is overwritten by whatever get put on the stack during
  1960                              <1> 	; a 'systime' system call. This calls are restricted to
  1961                              <1> 	; the super user.		
  1962                              <1> 	;
  1963                              <1> 	; Calling sequence:
  1964                              <1> 	;	sysmdate; name
  1965                              <1> 	; Arguments:
  1966                              <1> 	;	name - points to the name of file
  1967                              <1> 	; Inputs: (arguments)
  1968                              <1> 	; Outputs: -
  1969                              <1> 	; ...............................................................
  1970                              <1> 	;				
  1971                              <1> 	; Retro UNIX 8086 v1 modification: 
  1972                              <1> 	;	 The user/application program puts address 
  1973                              <1> 	;	 of the file name in BX register 
  1974                              <1> 	;	 as 'sysmdate' system call argument.
  1975                              <1> 	;
  1976                              <1> ; / change the modification time of a file
  1977                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
  1978 0000A77A 891D[60E30000]      <1>         mov	[u.namep], ebx
  1979 0000A780 E856070000          <1> 	call	namei
  1980                              <1> 		; jsr r0,namei / get its i-number
  1981 0000A785 0F8273FDFFFF        <1>         jc	fnotfound ; file not found !
  1982                              <1> 	;jc	error       
  1983                              <1> 		; br error2 / no, such file
  1984 0000A78B E850160000          <1> 	call	iget
  1985                              <1> 		; jsr r0,iget / get i-node into core
  1986 0000A790 A0[94E30000]        <1> 	mov	al, [u.uid]
  1987 0000A795 3A05[0FE00000]      <1> 	cmp	al, [i.uid]
  1988                              <1>         	; cmpb u.uid,i.uid / is user same as owner
  1989 0000A79B 7413                <1> 	je	short mdate_1
  1990                              <1>         	; beq 1f / yes
  1991 0000A79D 20C0                <1> 	and	al, al
  1992                              <1> 		; tstb u.uid / no, is user the super user
  1993                              <1> 	;jnz	error
  1994                              <1> 		; bne error2 / no, error
  1995 0000A79F 740F                <1> 	jz	short mdate_1
  1996 0000A7A1 C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1996 0000A7A9 0000                <1>
  1997 0000A7AB E9D7F8FFFF          <1> 	jmp	error
  1998                              <1> mdate_1: ;1:
  1999 0000A7B0 E832160000          <1> 	call	setimod
  2000                              <1>         	; jsr r0,setimod / fill in modification data,
  2001                              <1> 		               ; / time etc.
  2002 0000A7B5 BE[CED20000]        <1> 	mov	esi, p_time
  2003 0000A7BA BF[26E00000]        <1> 	mov	edi, i.mtim
  2004 0000A7BF A5                  <1> 	movsd
  2005                              <1> 		; mov 4(sp),i.mtim / move present time to
  2006                              <1>         	; mov 2(sp),i.mtim+2 / modification time
  2007 0000A7C0 E9E2F8FFFF          <1>         jmp	sysret
  2008                              <1> 		; br sysret2
  2009                              <1> 
  2010                              <1> sysvideo: ; VIDEO DATA TRANSFER FUNCTIONS
  2011                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  2012                              <1> 	;
  2013                              <1> 	; Inputs:
  2014                              <1> 	;	BH = Video mode (0 = VIDEO BIOS Mode 3, tty/text mode)
  2015                              <1> 	;	     BL = 
  2016                              <1> 	;		Bits 0&1, Transfer direction
  2017                              <1> 	;	     	 	0 - System to system
  2018                              <1> 	;			1 - User to system
  2019                              <1> 	;			2 - System to user
  2020                              <1> 	;			3 - User to user
  2021                              <1> 	;		Bits 2&3, Transfer Type
  2022                              <1> 	;			0 - Display page transfer	
  2023                              <1> 	;	     		1 - Display page window transfer
  2024                              <1> 	;	     		2 - Frame/Viewport/Window address transfer
  2025                              <1> 	;			3 - Window handle transfer		
  2026                              <1> 	;
  2027                              <1> 	;	     /// BL = 0 -> System to system (display page) transfer
  2028                              <1> 	;		 CL = Source page 
  2029                              <1> 	;		 DL = Destination page
  2030                              <1> 	;	     /// BL = 1&2 -> user to system & system to user transfer
  2031                              <1> 	;		 ECX = User buffer
  2032                              <1> 	;		 DL = Video page
  2033                              <1> 	;	     /// BL = 5&6 -> user to system, system to user transfer 
  2034                              <1> 	;		(window in current display page and in current mode)	 	 		
  2035                              <1> 	;		 ESI = User's buffer address
  2036                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2037                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2038                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2039                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2040                              <1>         ;                If BL = 5 ->
  2041                              <1> 	;		 EDI = Swap address (in user's memory space)
  2042                              <1> 	;		 (If swap address > 0, previous content of the window
  2043                              <1> 	;		 will be saved into swap area in user's memory space)		
  2044                              <1> 	;	     /// BL = 4 -> system to system transfer 
  2045                              <1> 	;		 ESI = System's source buffer (video page) address
  2046                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2047                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2048                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2049                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2050                              <1> 	;		 EDI = System's destination buffer (video page) address
  2051                              <1> 	;	
  2052                              <1> 	; Outputs:
  2053                              <1> 	;	EAX = transfer/byte count
  2054                              <1> 	;
  2055                              <1> 	;	NOTE: If the source or destination address passes out of
  2056                              <1> 	;	video pages (B8000h to B8000h+32000), data will not be transferred
  2057                              <1> 	;	and EAX will return as 0.
  2058                              <1> 	;	      	 	
  2059                              <1> 
  2060                              <1> 	; 16/05/2016
  2061 0000A7C5 31C0                <1> 	xor	eax, eax
  2062 0000A7C7 A3[48E30000]        <1> 	mov	[u.r0], eax
  2063                              <1> 
  2064 0000A7CC 20FF                <1> 	and	bh, bh
  2065 0000A7CE 0F85D3F8FFFF        <1> 	jnz	sysret
  2066                              <1> 	; Video mode 0, 80*25 text mode, CGA 16 colors  ; [CRT_MODE] = 3
  2067 0000A7D4 88DF                <1> 	mov	bh, bl
  2068 0000A7D6 C0EF02              <1> 	shr	bh, 2
  2069 0000A7D9 20FF                <1> 	and	bh, bh
  2070 0000A7DB 0F8598000000        <1>         jnz     sysvideo_4
  2071 0000A7E1 BF00800B00          <1> 	mov	edi, 0B8000h
  2072 0000A7E6 20D2                <1> 	and	dl, dl
  2073 0000A7E8 7413                <1> 	jz	short sysvideo_1
  2074 0000A7EA 80FA07              <1> 	cmp	dl, 7
  2075 0000A7ED 0F87B4F8FFFF        <1> 	ja	sysret
  2076                              <1> sysvideo_0:
  2077 0000A7F3 81C7A00F0000        <1> 	add	edi, 80*25*2
  2078 0000A7F9 FECA                <1> 	dec	dl
  2079 0000A7FB 75F6                <1> 	jnz	short sysvideo_0	
  2080                              <1> sysvideo_1:	
  2081 0000A7FD 80E303              <1> 	and	bl, 3
  2082 0000A800 7530                <1> 	jnz	short sysvideo_2
  2083 0000A802 80F907              <1> 	cmp	cl, 7
  2084 0000A805 0F879CF8FFFF        <1> 	ja	sysret
  2085                              <1> 	; system to system video/display page transfer (mode 0)
  2086 0000A80B BE00800B00          <1> 	mov	esi, 0B8000h
  2087 0000A810 0FB6C1              <1> 	movzx	eax, cl
  2088 0000A813 BAA00F0000          <1> 	mov	edx, 80*25*2
  2089 0000A818 F7E2                <1> 	mul	edx
  2090 0000A81A 01C6                <1> 	add	esi, eax
  2091 0000A81C B9A00F0000          <1> 	mov	ecx, (80*25*2)
  2092 0000A821 890D[48E30000]      <1> 	mov	[u.r0], ecx
  2093 0000A827 66C1E902            <1> 	shr	cx, 2 ; /4
  2094 0000A82B F3A5                <1> 	rep	movsd
  2095 0000A82D E975F8FFFF          <1> 	jmp	sysret	
  2096                              <1> sysvideo_2:  
  2097 0000A832 80FB02              <1> 	cmp	bl, 2
  2098 0000A835 0F876CF8FFFF        <1>         ja      sysret
  2099 0000A83B 721F                <1> 	jb	short sysvideo_3
  2100                              <1> 	; system to user video/display page transfer (mode 0)
  2101 0000A83D 89FE                <1> 	mov	esi, edi
  2102 0000A83F 89CF                <1> 	mov	edi, ecx ; user buffer
  2103 0000A841 B9A00F0000          <1> 	mov	ecx, 80*25*2
  2104 0000A846 E80F150000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2105 0000A84B 0F8256F8FFFF        <1> 	jc	sysret
  2106 0000A851 890D[48E30000]      <1> 	mov	[u.r0], ecx
  2107 0000A857 E94BF8FFFF          <1> 	jmp	sysret 	
  2108                              <1> sysvideo_3: 
  2109                              <1> 	; user to system video/display page transfer (mode 0)	
  2110 0000A85C 89CE                <1> 	mov	esi, ecx ; user buffer
  2111                              <1> 	; edi = video page address
  2112 0000A85E B9A00F0000          <1> 	mov	ecx, 80*25*2
  2113 0000A863 E83C150000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2114 0000A868 0F8239F8FFFF        <1> 	jc	sysret
  2115 0000A86E 890D[48E30000]      <1> 	mov	[u.r0], ecx		
  2116 0000A874 E92EF8FFFF          <1> 	jmp	sysret
  2117                              <1> sysvideo_4:
  2118 0000A879 80E303              <1> 	and	bl, 3
  2119 0000A87C 0F85F6000000        <1>         jnz     sysvideo_9
  2120 0000A882 80F907              <1> 	cmp	cl, 7
  2121 0000A885 0F871CF8FFFF        <1> 	ja	sysret
  2122                              <1> 	; system to system video/display page window transfer (mode 0)
  2123 0000A88B 81FE00800B00        <1> 	cmp	esi, 0B8000h
  2124 0000A891 0F8210F8FFFF        <1> 	jb	sysret
  2125 0000A897 81FE00FD0B00        <1> 	cmp	esi, 0B8000h+(80*25*2*8)
  2126 0000A89D 0F8304F8FFFF        <1> 	jnb	sysret
  2127 0000A8A3 81FF00800B00        <1> 	cmp	edi, 0B8000h
  2128 0000A8A9 0F82F8F7FFFF        <1> 	jb	sysret
  2129 0000A8AF 81FF00FD0B00        <1>         cmp     edi, 0B8000h+(80*25*2*8)
  2130 0000A8B5 0F83ECF7FFFF        <1> 	jnb	sysret
  2131                              <1> 	;
  2132 0000A8BB 51                  <1> 	push	ecx
  2133 0000A8BC 52                  <1> 	push	edx
  2134 0000A8BD 0FB7C1              <1> 	movzx	eax, cx ; top left column
  2135 0000A8C0 50                  <1> 	push	eax
  2136 0000A8C1 C1E910              <1> 	shr	ecx, 16 ; top row
  2137 0000A8C4 66B8A000            <1> 	mov	ax, 80*2 ; 80 colums, 160 bytes per row
  2138 0000A8C8 F7E1                <1> 	mul	ecx
  2139 0000A8CA 01C6                <1> 	add	esi, eax
  2140 0000A8CC 01C7                <1> 	add	edi, eax
  2141 0000A8CE 58                  <1> 	pop	eax
  2142 0000A8CF 66D1E0              <1> 	shl	ax, 1 ; *2 	
  2143 0000A8D2 01C6                <1> 	add	esi, eax
  2144 0000A8D4 01C7                <1> 	add	edi, eax
  2145 0000A8D6 5A                  <1> 	pop	edx
  2146 0000A8D7 59                  <1> 	pop	ecx
  2147 0000A8D8 B800FD0B00          <1> 	mov	eax, 0B8000h+(80*25*2*8)
  2148 0000A8DD 39C6                <1> 	cmp	esi, eax
  2149 0000A8DF 0F83C2F7FFFF        <1> 	jnb	sysret
  2150 0000A8E5 39C6                <1> 	cmp	esi, eax
  2151 0000A8E7 0F83BAF7FFFF        <1> 	jnb	sysret	
  2152                              <1> 
  2153 0000A8ED 56                  <1> 	push	esi ; ****
  2154 0000A8EE 57                  <1> 	push	edi ; ***
  2155 0000A8EF 52                  <1> 	push	edx ; **
  2156 0000A8F0 51                  <1> 	push	ecx ; *
  2157 0000A8F1 C1E910              <1> 	shr	ecx, 16 ; top row
  2158 0000A8F4 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2159 0000A8F7 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2160 0000A8FA 7773                <1> 	ja	short sysvideo_6
  2161 0000A8FC 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2162 0000A8FF 776E                <1> 	ja	short sysvideo_6		
  2163 0000A901 28CA                <1> 	sub	dl, cl
  2164 0000A903 726A                <1> 	jc	short sysvideo_6
  2165 0000A905 50                  <1> 	push	eax ; *****
  2166 0000A906 89D3                <1> 	mov	ebx, edx ; row count - 1
  2167 0000A908 B8A0000000          <1> 	mov	eax, 80*2
  2168 0000A90D F7E0                <1> 	mul	eax
  2169 0000A90F 01C6                <1> 	add	esi, eax
  2170 0000A911 01C7                <1> 	add	edi, eax
  2171 0000A913 58                  <1> 	pop	eax ; *****
  2172 0000A914 39C6                <1> 	cmp	esi, eax
  2173 0000A916 7757                <1> 	ja	short sysvideo_6
  2174 0000A918 39C7                <1> 	cmp	edi, eax
  2175 0000A91A 7753                <1> 	ja	short sysvideo_6
  2176 0000A91C 59                  <1> 	pop	ecx ; *
  2177 0000A91D 5A                  <1> 	pop	edx ; **
  2178 0000A91E 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2179 0000A924 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2180 0000A92A 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2181 0000A92D 7742                <1> 	ja	short sysvideo_7
  2182 0000A92F 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2183 0000A932 773D                <1> 	ja	short sysvideo_7
  2184 0000A934 28CA                <1> 	sub	dl, cl
  2185 0000A936 7639                <1> 	jna	short sysvideo_7
  2186                              <1> 	; edx = column count (width) - 1
  2187 0000A938 D0E2                <1> 	shl	dl, 1
  2188 0000A93A 01D6                <1> 	add	esi, edx
  2189 0000A93C 01D7                <1> 	add	edi, edx
  2190 0000A93E 39C6                <1> 	cmp	esi, eax
  2191 0000A940 772F                <1> 	ja	short sysvideo_7
  2192 0000A942 39C7                <1> 	cmp	edi, eax
  2193 0000A944 772B                <1> 	ja	short sysvideo_7
  2194 0000A946 5F                  <1> 	pop	edi ; ***
  2195 0000A947 5E                  <1> 	pop	esi ; ****
  2196 0000A948 FEC3                <1> 	inc	bl
  2197 0000A94A FEC2                <1> 	inc	dl ; column count
  2198 0000A94C 88D7                <1> 	mov	bh, dl
  2199 0000A94E D0E2                <1> 	shl	dl, 1
  2200 0000A950 B8A0000000          <1> 	mov	eax, 80*2
  2201 0000A955 28D0                <1> 	sub	al, dl ; (80 - columns) * 2
  2202                              <1> sysvideo_5:	
  2203 0000A957 88F9                <1> 	mov	cl, bh
  2204 0000A959 0115[48E30000]      <1> 	add	[u.r0], edx
  2205 0000A95F F366A5              <1> 	rep	movsw
  2206 0000A962 01C6                <1> 	add	esi, eax ; next row
  2207 0000A964 01C7                <1> 	add	edi, eax ; next row
  2208 0000A966 FECB                <1> 	dec	bl
  2209 0000A968 75ED                <1> 	jnz	short sysvideo_5
  2210 0000A96A E938F7FFFF          <1> 	jmp	sysret
  2211                              <1> 
  2212                              <1> sysvideo_6:
  2213 0000A96F 59                  <1> 	pop	ecx ; *
  2214 0000A970 5A                  <1> 	pop	edx ; **
  2215                              <1> sysvideo_7:	
  2216 0000A971 5F                  <1> 	pop	edi ; ***
  2217 0000A972 5E                  <1> 	pop	esi ; ****
  2218 0000A973 E92FF7FFFF          <1> 	jmp	sysret
  2219                              <1> 
  2220                              <1> sysvideo_9:  
  2221 0000A978 80FB02              <1> 	cmp	bl, 2
  2222 0000A97B 0F8726F7FFFF        <1>         ja      sysret
  2223                              <1> 
  2224 0000A981 52                  <1> 	push	edx ; *****
  2225 0000A982 0FB605[B8D20000]    <1> 	movzx	eax, byte [ACTIVE_PAGE]
  2226 0000A989 BAA00F0000          <1> 	mov	edx, 80*25*2
  2227 0000A98E F7E2                <1> 	mul	edx
  2228 0000A990 5A                  <1> 	pop	edx ; *****	
  2229 0000A991 89C7                <1> 	mov	edi, eax
  2230 0000A993 81C700800B00        <1> 	add	edi, 0B8000h
  2231                              <1> 
  2232 0000A999 56                  <1> 	push	esi ; ****
  2233 0000A99A 57                  <1> 	push	edi ; ***
  2234 0000A99B 52                  <1> 	push	edx ; **
  2235 0000A99C 51                  <1> 	push	ecx ; *
  2236 0000A99D C1E910              <1> 	shr	ecx, 16 ; top row
  2237 0000A9A0 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2238 0000A9A3 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2239 0000A9A6 77C7                <1> 	ja	short sysvideo_6
  2240 0000A9A8 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2241 0000A9AB 77C2                <1> 	ja	short sysvideo_6		
  2242 0000A9AD 28CA                <1> 	sub	dl, cl
  2243 0000A9AF 72BE                <1> 	jc	short sysvideo_6
  2244 0000A9B1 50                  <1> 	push	eax ; *****
  2245 0000A9B2 88D7                <1> 	mov	bh, dl ; row count - 1
  2246 0000A9B4 B8A0000000          <1> 	mov	eax, 80*2
  2247 0000A9B9 F7E0                <1> 	mul	eax
  2248 0000A9BB 01C7                <1> 	add	edi, eax
  2249 0000A9BD 58                  <1> 	pop	eax ; *****
  2250 0000A9BE 39C7                <1> 	cmp	edi, eax
  2251 0000A9C0 77AD                <1> 	ja	short sysvideo_6
  2252 0000A9C2 59                  <1> 	pop	ecx ; *
  2253 0000A9C3 5A                  <1> 	pop	edx ; **
  2254 0000A9C4 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2255 0000A9CA 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2256 0000A9D0 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2257 0000A9D3 779C                <1> 	ja	short sysvideo_7
  2258 0000A9D5 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2259 0000A9D8 7797                <1> 	ja	short sysvideo_7
  2260 0000A9DA 28CA                <1> 	sub	dl, cl
  2261 0000A9DC 7693                <1> 	jna	short sysvideo_7
  2262                              <1> 	; edx = column count (width) - 1
  2263 0000A9DE D0E2                <1> 	shl	dl, 1
  2264 0000A9E0 29D0                <1> 	sub	eax, edx
  2265 0000A9E2 39C7                <1> 	cmp	edi, eax
  2266 0000A9E4 778B                <1> 	ja	short sysvideo_7
  2267 0000A9E6 58                  <1> 	pop	eax ; *** (swap address)
  2268 0000A9E7 5E                  <1> 	pop	esi ; ****
  2269 0000A9E8 FEC7                <1> 	inc	bh
  2270 0000A9EA FEC2                <1> 	inc	dl ; column count
  2271 0000A9EC D0E2                <1> 	shl	dl, 1
  2272 0000A9EE 88D1                <1> 	mov	cl, dl
  2273 0000A9F0 BAA0000000          <1> 	mov	edx, 80*2
  2274 0000A9F5 28CA                <1> 	sub	dl, cl ; (80 - columns) * 2
  2275                              <1> 	;
  2276 0000A9F7 80FB01              <1> 	cmp	bl, 1
  2277 0000A9FA 7735                <1> 	ja	short sysvideo_11
  2278                              <1> 
  2279                              <1> 	; user to system video/display page window transfer (mode 0)	
  2280 0000A9FC 21C0                <1> 	and	eax, eax ; swap address
  2281 0000A9FE 7413                <1> 	jz	short sysvideo_10 ; no window swap
  2282                              <1> 	; save previous window content in user's buffer (swap address)
  2283 0000AA00 56                  <1> 	push	esi ; user buffer
  2284 0000AA01 57                  <1> 	push	edi ; beginning address of the window
  2285 0000AA02 89FE                <1> 	mov	esi, edi
  2286 0000AA04 89C7                <1> 	mov	edi, eax
  2287 0000AA06 E84F130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2288 0000AA0B 5F                  <1> 	pop	edi
  2289 0000AA0C 5E                  <1> 	pop	esi
  2290 0000AA0D 0F8294F6FFFF        <1> 	jc	sysret
  2291                              <1> sysvideo_10: 
  2292                              <1> 	; user to system video/display page window transfer (mode 0)	
  2293                              <1> 	; esi =	user buffer	
  2294 0000AA13 E88C130000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2295 0000AA18 0F8289F6FFFF        <1> 	jc	sysret
  2296 0000AA1E 010D[48E30000]      <1> 	add	[u.r0], ecx
  2297 0000AA24 01D7                <1> 	add	edi, edx ; next row
  2298 0000AA26 01CE                <1> 	add	esi, ecx
  2299 0000AA28 FECF                <1> 	dec	bh
  2300 0000AA2A 75E7                <1> 	jnz	short sysvideo_10
  2301 0000AA2C E976F6FFFF          <1> 	jmp	sysret
  2302                              <1> 	
  2303                              <1> sysvideo_11:
  2304                              <1> 	; system to user video/display page window transfer (mode 0)
  2305 0000AA31 87FE                <1> 	xchg	edi, esi
  2306                              <1> sysvideo_12:
  2307                              <1> 	; esi = beginning address of the window
  2308                              <1> 	; edi =	user buffer	
  2309 0000AA33 E822130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2310 0000AA38 0F8269F6FFFF        <1> 	jc	sysret
  2311 0000AA3E 010D[48E30000]      <1> 	add	[u.r0], ecx
  2312 0000AA44 01D6                <1> 	add	esi, edx ; next row
  2313 0000AA46 01CF                <1> 	add	edi, ecx
  2314 0000AA48 FECF                <1> 	dec	bh
  2315 0000AA4A 75E7                <1> 	jnz	short sysvideo_12
  2316 0000AA4C E956F6FFFF          <1> 	jmp	sysret
  2317                              <1> 
  2318                              <1> 
  2319                              <1> sysaudio: ; AUDIO FUNCTIONS
  2320                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  2321                              <1> 	;
  2322                              <1> 	; Inputs:
  2323                              <1> 	;	BH = 0 -> Beep (PC Speaker)
  2324                              <1> 	;	     BL = Duration Counter (1 for 1/64 second)
  2325                              <1> 	;	     CX = Frequency Divisor (1193180/Frequency)
  2326                              <1> 	;		 (1331 for 886 Hz)			
  2327                              <1> 	;
  2328                              <1> 	; Outputs:
  2329                              <1> 	;	none
  2330                              <1> 	;
  2331 0000AA51 20FF                <1> 	and	bh, bh
  2332 0000AA53 0F854EF6FFFF        <1> 	jnz	sysret
  2333 0000AA59 E86E6DFFFF          <1> 	call	beep
  2334 0000AA5E E944F6FFFF          <1> 	jmp	sysret
  2335                              <1> 
  2336                              <1> syslink:
  2337                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2338                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2339                              <1> 	;
  2340                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
  2341                              <1> 	; name 1 is a file that already exists. name 2 is the name
  2342                              <1> 	; given to the entry that will go in the current directory.
  2343                              <1> 	; name2 will then be a link to the name 1 file. The i-number
  2344                              <1> 	; in the name 2 entry of current directory is the same
  2345                              <1> 	; i-number for the name 1 file.
  2346                              <1> 	;
  2347                              <1> 	; Calling sequence:
  2348                              <1> 	;	syslink; name 1; name 2
  2349                              <1> 	; Arguments:
  2350                              <1> 	;	name 1 - file name to which link will be created.
  2351                              <1> 	;	name 2 - name of entry in current directory that
  2352                              <1> 	;		 links to name 1.
  2353                              <1> 	; Inputs: -
  2354                              <1> 	; Outputs: -
  2355                              <1> 	; ...............................................................
  2356                              <1> 	;	
  2357                              <1> 	; Retro UNIX 8086 v1 modification: 
  2358                              <1> 	;       'syslink' system call has two arguments; so,
  2359                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
  2360                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
  2361                              <1> 	;
  2362                              <1> 		; / name1, name2
  2363                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
  2364 0000AA63 891D[60E30000]      <1> 	mov	[u.namep], ebx
  2365 0000AA69 51                  <1> 	push	ecx
  2366 0000AA6A E86C040000          <1> 	call	namei
  2367                              <1> 		; jsr r0,namei / find the i-number associated with
  2368                              <1> 			     ; / the 1st path name
  2369                              <1>      	;;and	ax, ax
  2370                              <1> 	;;jz	error ; File not found
  2371                              <1> 	;jc	error 
  2372                              <1> 		; br error9 / cannot be found
  2373 0000AA6F 730F                <1> 	jnc	short syslink0
  2374                              <1> 	;pop 	ecx
  2375                              <1> 	; 'file not found !' error
  2376 0000AA71 C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2376 0000AA79 0000                <1>
  2377 0000AA7B E907F6FFFF          <1> 	jmp	error
  2378                              <1> syslink0:
  2379 0000AA80 E85B130000          <1> 	call	iget
  2380                              <1> 		; jsr r0,iget / get the i-node into core
  2381 0000AA85 8F05[60E30000]      <1> 	pop	dword [u.namep] ; ecx
  2382                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2383 0000AA8B 6650                <1> 	push	ax
  2384                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
  2385                              <1> 			    ; / (a link to this file is to be created)
  2386 0000AA8D 66FF35[2AE30000]    <1> 	push	word [cdev]
  2387                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2388 0000AA94 E855000000          <1> 	call	isdir
  2389                              <1> 		; jsr r0,isdir / is it a directory
  2390 0000AA99 E83D040000          <1> 	call	namei
  2391                              <1> 		; jsr r0,namei / no, get i-number of name2
  2392                              <1> 	;jnc	error
  2393                              <1> 		; br .+4   / not found 
  2394                              <1> 			 ; / so r1 = i-number of current directory
  2395                              <1> 			 ; / ii = i-number of current directory
  2396                              <1> 		; br error9 / file already exists., error
  2397 0000AA9E 720F                <1> 	jc	short syslink1
  2398                              <1> 	; pop ax
  2399                              <1> 	; pop ax
  2400                              <1> 	; 'file exists !' error
  2401 0000AAA0 C705[9DE30000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2401 0000AAA8 0000                <1>
  2402 0000AAAA E9D8F5FFFF          <1> 	jmp	error
  2403                              <1> syslink1:
  2404 0000AAAF 6659                <1> 	pop	cx
  2405                              <1> 	;cmp	cx, [cdev]
  2406 0000AAB1 3A0D[2AE30000]      <1> 	cmp	cl, [cdev]
  2407                              <1> 	;jne	error
  2408                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
  2409                              <1> 			       ; / end of current directory
  2410                              <1> 	        ; bne error9
  2411 0000AAB7 740F                <1> 	je	short syslink2
  2412                              <1> 	; 'not same drive !' error
  2413 0000AAB9 C705[9DE30000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2413 0000AAC1 0000                <1>
  2414 0000AAC3 E9BFF5FFFF          <1> 	jmp	error
  2415                              <1> syslink2:
  2416 0000AAC8 6658                <1> 	pop	ax
  2417 0000AACA 6650                <1> 	push	ax
  2418 0000AACC 66A3[7AE30000]      <1> 	mov	[u.dirbuf], ax
  2419                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2420 0000AAD2 E8A8000000          <1> 	call	mkdir
  2421                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2422                              <1> 		 	     ; / in current directory
  2423 0000AAD7 6658                <1> 	pop	ax
  2424                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2425 0000AAD9 E802130000          <1> 	call	iget
  2426                              <1> 		; jsr r0,iget / get i-node into core
  2427 0000AADE FE05[0EE00000]      <1> 	inc	byte [i.nlks]
  2428                              <1> 		; incb i.nlks / add 1 to its number of links
  2429 0000AAE4 E8FE120000          <1> 	call	setimod
  2430                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2431 0000AAE9 E9B9F5FFFF          <1> 	jmp	sysret
  2432                              <1> 
  2433                              <1> isdir:
  2434                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  2435                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  2436                              <1> 	;
  2437                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
  2438                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
  2439                              <1> 	;  called by syslink and sysunlink to make sure directories
  2440                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
  2441                              <1> 	; 'isdir' does not bother checking. The current i-node
  2442                              <1> 	;  is not disturbed.			
  2443                              <1> 	;		
  2444                              <1> 	; INPUTS ->
  2445                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
  2446                              <1> 	;    u.uid - user id
  2447                              <1> 	; OUTPUTS ->
  2448                              <1> 	;    r1 - contains current i-number upon exit
  2449                              <1> 	;    	 (current i-node back in core) 
  2450                              <1> 	;	
  2451                              <1> 	; ((AX = R1))
  2452                              <1> 	;
  2453                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2454                              <1> 	;
  2455                              <1> 
  2456                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
  2457                              <1> 	; / there is an error unless super user made the call
  2458                              <1> 	
  2459 0000AAEE 803D[94E30000]00    <1> 	cmp	byte [u.uid], 0 
  2460                              <1> 		; tstb u.uid / super user
  2461 0000AAF5 762D                <1> 	jna	short isdir1
  2462                              <1> 		; beq 1f / yes, don't care
  2463 0000AAF7 66FF35[CDE30000]    <1> 	push	word [ii]
  2464                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2465 0000AAFE E8DD120000          <1> 	call	iget
  2466                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2467 0000AB03 66F705[0CE00000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2467 0000AB0B 40                  <1>
  2468                              <1> 		; bit $40000,i.flgs / is it a directory
  2469                              <1> 	;jnz	error
  2470                              <1> 		; bne error9 / yes, error
  2471 0000AB0C 740F                <1> 	jz	short isdir0
  2472 0000AB0E C705[9DE30000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2472 0000AB16 0000                <1>
  2473                              <1> 				; 'permission denied !' error
  2474                              <1> 	; pop	ax
  2475 0000AB18 E96AF5FFFF          <1> 	jmp	error	
  2476                              <1> isdir0:	
  2477 0000AB1D 6658                <1> 	pop	ax
  2478                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2479 0000AB1F E8BC120000          <1> 	call	iget
  2480                              <1> 		; jsr r0,iget / get it back in
  2481                              <1> isdir1: ; 1:
  2482 0000AB24 C3                  <1> 	retn
  2483                              <1> 		; rts r0
  2484                              <1> 
  2485                              <1> sysunlink:
  2486                              <1> 	; 04/12/2015 (14 byte file names)
  2487                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2488                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2489                              <1> 	;
  2490                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
  2491                              <1> 	; name from its directory. If this entry was the last link
  2492                              <1> 	; to the file, the contents of the file are freed and the
  2493                              <1> 	; file is destroyed. If, however, the file was open in any
  2494                              <1> 	; process, the actual destruction is delayed until it is 
  2495                              <1> 	; closed, even though the directory entry has disappeared.
  2496                              <1> 	; 
  2497                              <1> 	; The error bit (e-bit) is set to indicate that the file	
  2498                              <1> 	; does not exist or that its directory can not be written.
  2499                              <1> 	; Write permission is not required on the file itself.
  2500                              <1> 	; It is also illegal to unlink a directory (except for
  2501                              <1> 	; the superuser).
  2502                              <1> 	;
  2503                              <1> 	; Calling sequence:
  2504                              <1> 	;	sysunlink; name
  2505                              <1> 	; Arguments:
  2506                              <1> 	;	name - name of directory entry to be removed 
  2507                              <1> 	; Inputs: -
  2508                              <1> 	; Outputs: -
  2509                              <1> 	; ...............................................................
  2510                              <1> 	;				
  2511                              <1> 	; Retro UNIX 8086 v1 modification:
  2512                              <1> 	;	 The user/application program puts address of the name
  2513                              <1> 	;        in BX register as 'sysunlink' system call argument.
  2514                              <1> 
  2515                              <1> 	; / name - remove link name
  2516 0000AB25 891D[60E30000]      <1> 	mov	[u.namep], ebx
  2517                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2518 0000AB2B E8AB030000          <1> 	call	namei
  2519                              <1> 		; jsr r0,namei / find the i-number associated 
  2520                              <1> 			     ; / with the path name
  2521                              <1> 	;jc	error
  2522                              <1> 		; br error9 / not found
  2523 0000AB30 730F                <1> 	jnc	short sysunlink1
  2524                              <1> 	; 'file not found !' error
  2525 0000AB32 C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2525 0000AB3A 0000                <1>
  2526 0000AB3C E946F5FFFF          <1> 	jmp	error
  2527                              <1> sysunlink1:
  2528 0000AB41 6650                <1> 	push	ax
  2529                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2530 0000AB43 E8A6FFFFFF          <1> 	call	isdir
  2531                              <1> 		; jsr r0,isdir / is it a directory
  2532 0000AB48 6631C0              <1> 	xor 	ax, ax
  2533 0000AB4B 66A3[7AE30000]      <1> 	mov	[u.dirbuf], ax ; 0
  2534                              <1> 		; clr u.dirbuf / no, clear the location that will
  2535                              <1> 			   ; / get written into the i-number portion
  2536                              <1> 			 ; / of the entry
  2537 0000AB51 832D[64E30000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
  2538                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
  2539 0000AB58 E86E000000          <1> 	call	wdir
  2540                              <1> 		; jsr r0,wdir / free the directory entry
  2541 0000AB5D 6658                <1> 	pop	ax
  2542                              <1> 		; mov (sp)+,r1 / get i-number back
  2543 0000AB5F E87C120000          <1> 	call	iget
  2544                              <1> 		; jsr r0,iget / get i-node
  2545 0000AB64 E87E120000          <1> 	call	setimod
  2546                              <1> 		; jsr r0,setimod / set modified flag
  2547 0000AB69 FE0D[0EE00000]      <1> 	dec	byte [i.nlks]
  2548                              <1> 		; decb i.nlks / decrement the number of links
  2549 0000AB6F 0F8532F5FFFF        <1> 	jnz	sysret
  2550                              <1> 		; bgt sysret9 / if this was not the last link
  2551                              <1> 			    ; / to file return
  2552                              <1> 	; AX = r1 = i-number
  2553 0000AB75 E886070000          <1> 	call	anyi
  2554                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
  2555                              <1> 			 ; / Then free contents of file and destroy it.
  2556 0000AB7A E928F5FFFF          <1> 	jmp	sysret
  2557                              <1> 		; br sysret9
  2558                              <1> 
  2559                              <1> mkdir:
  2560                              <1> 	; 04/12/2015 (14 byte directory names)
  2561                              <1> 	; 12/10/2015
  2562                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  2563                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2564                              <1> 	;
  2565                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  2566                              <1> 	; by u.namep into the current directory.
  2567                              <1> 	;
  2568                              <1> 	; INPUTS ->
  2569                              <1> 	;    u.namep - points to a file name 
  2570                              <1> 	;	           that is about to be a directory entry.
  2571                              <1> 	;    ii - current directory's i-number.	
  2572                              <1> 	; OUTPUTS ->
  2573                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  2574                              <1> 	;    u.off - points to entry to be filled 
  2575                              <1> 	;	     in the current directory		
  2576                              <1> 	;    u.base - points to start of u.dirbuf.
  2577                              <1> 	;    r1 - contains i-number of current directory 
  2578                              <1> 	;	
  2579                              <1> 	; ((AX = R1)) output
  2580                              <1> 	;
  2581                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  2582                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2583                              <1> 	;
  2584                              <1> 
  2585                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  2586 0000AB7F 31C0                <1> 	xor 	eax, eax
  2587 0000AB81 BF[7CE30000]        <1> 	mov     edi, u.dirbuf+2
  2588 0000AB86 89FE                <1> 	mov	esi, edi
  2589 0000AB88 AB                  <1> 	stosd
  2590 0000AB89 AB                  <1> 	stosd
  2591                              <1> 	; 04/12/2015 (14 byte directory names)
  2592 0000AB8A AB                  <1> 	stosd
  2593 0000AB8B 66AB                <1> 	stosw
  2594                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2595 0000AB8D 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2596                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2597                              <1> 	;mov 	ebp, [u.namep]
  2598 0000AB8F E88C040000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  2599                              <1> 		; esi = physical address (page start + offset)
  2600                              <1> 		; ecx = byte count in the page (1 - 4096)
  2601                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2602                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  2603                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  2604                              <1> mkdir_1: ; 1: 
  2605 0000AB94 45                  <1> 	inc	ebp ; 12/10/2015
  2606                              <1> 	;
  2607                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  2608                              <1> 	 ; 01/08/2013
  2609 0000AB95 AC                  <1> 	lodsb
  2610                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2611 0000AB96 20C0                <1> 	and 	al, al
  2612 0000AB98 7427                <1> 	jz 	short mkdir_3 	  
  2613                              <1> 		; beq 1f / if null, done
  2614 0000AB9A 3C2F                <1> 	cmp	al, '/'
  2615                              <1> 		; cmp r1,$'/ / is it a "/"?
  2616 0000AB9C 7414                <1> 	je	short mkdir_err
  2617                              <1> 	;je	error
  2618                              <1> 		; beq error9 / yes, error
  2619                              <1> 	; 12/10/2015
  2620 0000AB9E 6649                <1> 	dec	cx
  2621 0000ABA0 7505                <1> 	jnz	short mkdir_2
  2622                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2623 0000ABA2 E87F040000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  2624                              <1> 		; esi = physical address (page start + offset)
  2625                              <1> 		; ecx = byte count in the page
  2626                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2627                              <1> mkdir_2:
  2628 0000ABA7 81FF[8AE30000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  2629                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  2630                              <1> 				     ; / a char?
  2631 0000ABAD 74E5                <1> 	je	short mkdir_1
  2632                              <1> 		; beq 1b / yes, go back
  2633 0000ABAF AA                  <1> 	stosb
  2634                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2635 0000ABB0 EBE2                <1> 	jmp 	short mkdir_1
  2636                              <1> 		; br 1b / get next char
  2637                              <1> mkdir_err:
  2638                              <1> 	; 17/06/2015
  2639 0000ABB2 C705[9DE30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2639 0000ABBA 0000                <1>
  2640 0000ABBC E9C6F4FFFF          <1> 	jmp	error
  2641                              <1> 
  2642                              <1> mkdir_3: ; 1:
  2643 0000ABC1 A1[5CE30000]        <1> 	mov	eax, [u.dirp]
  2644 0000ABC6 A3[64E30000]        <1> 	mov	[u.off], eax
  2645                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  2646                              <1> 				 ; / slot to u.off
  2647                              <1> wdir: ; 29/04/2013
  2648 0000ABCB C705[68E30000]-     <1>         mov     dword [u.base], u.dirbuf
  2648 0000ABD1 [7AE30000]          <1>
  2649                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2650 0000ABD5 C705[6CE30000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2650 0000ABDD 0000                <1>
  2651                              <1> 		; mov $10.,u.count / u.count = 10
  2652 0000ABDF 66A1[CDE30000]      <1> 	mov	ax, [ii] 
  2653                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2654 0000ABE5 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2655 0000ABE7 E8FF110000          <1> 	call 	access
  2656                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  2657                              <1> 				 ; / for writing
  2658                              <1> 	; AX = i-number of current directory
  2659                              <1> 	; 01/08/2013
  2660 0000ABEC FE05[AFE30000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2661 0000ABF2 E8EC110000          <1> 	call	writei
  2662                              <1> 		; jsr r0,writei / write into directory
  2663 0000ABF7 C3                  <1> 	retn	
  2664                              <1> 		; rts r0
  2665                              <1> 
  2666                              <1> sysexec:
  2667                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  2668                              <1> 	; 23/06/2015 - 23/10/2015 (Retro UNIX 386 v1)
  2669                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2670                              <1> 	;
  2671                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  2672                              <1> 	; pointed to by 'name' in the sysexec call. 
  2673                              <1> 	; 'sysexec' performs the following operations:
  2674                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  2675                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
  2676                              <1> 	;    3. sets trap vectors to system routines.
  2677                              <1> 	;    4. loads arguments to be passed to executing file into
  2678                              <1> 	;	highest locations of user's core
  2679                              <1> 	;    5. puts pointers to arguments in locations immediately
  2680                              <1> 	;	following arguments.
  2681                              <1> 	;    6.	saves number of arguments in next location.
  2682                              <1> 	;    7. intializes user's stack area so that all registers
  2683                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  2684                              <1> 	;	to core when 'sysret' restores registers 
  2685                              <1> 	;	and does an rti.
  2686                              <1> 	;    8. inializes u.r0 and u.sp
  2687                              <1> 	;    9. zeros user's core down to u.r0
  2688                              <1> 	;   10.	reads executable file from storage device into core
  2689                              <1> 	;	starting at location 'core'.
  2690                              <1> 	;   11.	sets u.break to point to end of user's code with
  2691                              <1> 	;	data area appended.
  2692                              <1> 	;   12.	calls 'sysret' which returns control at location
  2693                              <1> 	;	'core' via 'rti' instruction. 		  		
  2694                              <1> 	;
  2695                              <1> 	; Calling sequence:
  2696                              <1> 	;	sysexec; namep; argp
  2697                              <1> 	; Arguments:
  2698                              <1> 	;	namep - points to pathname of file to be executed
  2699                              <1> 	;	argp  - address of table of argument pointers
  2700                              <1> 	;	argp1... argpn - table of argument pointers
  2701                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  2702                              <1> 	; Inputs: (arguments)
  2703                              <1> 	; Outputs: -	
  2704                              <1> 	; ...............................................................
  2705                              <1> 	;
  2706                              <1> 	; Retro UNIX 386 v1 modification: 
  2707                              <1> 	;	User application runs in it's own virtual space 
  2708                              <1> 	;	which is izolated from kernel memory (and other
  2709                              <1> 	;	memory pages) via 80386	paging in ring 3 
  2710                              <1> 	;	privilige mode. Virtual start address is always 0.
  2711                              <1> 	;	User's core memory starts at linear address 400000h
  2712                              <1> 	;	(the end of the 1st 4MB).
  2713                              <1> 	;
  2714                              <1> 	; Retro UNIX 8086 v1 modification: 
  2715                              <1> 	;	user/application segment and system/kernel segment
  2716                              <1> 	;	are different and sysenter/sysret/sysrele routines
  2717                              <1> 	;	are different (user's registers are saved to 
  2718                              <1> 	;	and then restored from system's stack.)
  2719                              <1> 	;
  2720                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2721                              <1> 	;	      arguments which were in these registers;
  2722                              <1> 	;	      but, it returns by putting the 1st argument
  2723                              <1> 	;	      in 'u.namep' and the 2nd argument
  2724                              <1> 	;	      on top of stack. (1st argument is offset of the
  2725                              <1> 	;	      file/path name in the user's program segment.)		 	
  2726                              <1> 	
  2727                              <1> 	;call	arg2
  2728                              <1> 	; * name - 'u.namep' points to address of file/path name
  2729                              <1> 	;          in the user's program segment ('u.segmnt')
  2730                              <1> 	;          with offset in BX register (as sysopen argument 1).
  2731                              <1> 	; * argp - sysexec argument 2 is in CX register 
  2732                              <1> 	;          which is on top of stack.
  2733                              <1> 	;
  2734                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  2735                              <1> 
  2736                              <1> 	; 23/06/2015 (32 bit modifications)
  2737                              <1> 
  2738 0000ABF8 891D[60E30000]      <1> 	mov	[u.namep], ebx ; argument 1
  2739                              <1>         ; 18/10/2015
  2740 0000ABFE 890D[C8E30000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2741 0000AC04 E8D2020000          <1> 	call	namei
  2742                              <1> 		; jsr r0,namei / namei returns i-number of file 
  2743                              <1> 			     ; / named in sysexec call in r1
  2744                              <1> 	;jc	error
  2745                              <1> 		; br error9
  2746 0000AC09 731E                <1> 	jnc	short sysexec_0
  2747                              <1> 	;
  2748                              <1> 	; 'file not found !' error
  2749 0000AC0B C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2749 0000AC13 0000                <1>
  2750 0000AC15 E96DF4FFFF          <1> 	jmp	error 
  2751                              <1> sysexec_not_exf:
  2752                              <1> 	; 'not executable file !' error
  2753 0000AC1A C705[9DE30000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
  2753 0000AC22 0000                <1>
  2754 0000AC24 E95EF4FFFF          <1> 	jmp	error 
  2755                              <1> sysexec_0:
  2756 0000AC29 E8B2110000          <1> 	call	iget
  2757                              <1> 		; jsr r0,iget / get i-node for file to be executed
  2758 0000AC2E 66F705[0CE00000]10- <1>         test    word [i.flgs], 10h
  2758 0000AC36 00                  <1>
  2759                              <1> 		; bit $20,i.flgs / is file executable
  2760 0000AC37 74E1                <1> 	jz	short sysexec_not_exf
  2761                              <1> 	;jz	error
  2762                              <1> 		; beq error9
  2763                              <1> 	;;
  2764 0000AC39 E8A6110000          <1> 	call	iopen
  2765                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
  2766                              <1> 			     ; / given in r1 (opens file)
  2767                              <1> 	; AX = i-number of the file
  2768 0000AC3E 66F705[0CE00000]20- <1> 	test	word [i.flgs], 20h
  2768 0000AC46 00                  <1>
  2769                              <1> 		; bit $40,i.flgs / test user id on execution bit
  2770 0000AC47 7415                <1> 	jz	short sysexec_1
  2771                              <1> 		; beq 1f
  2772 0000AC49 803D[94E30000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
  2773                              <1> 		; tstb u.uid / test user id
  2774 0000AC50 760C                <1> 	jna	short sysexec_1
  2775                              <1> 		; beq 1f / super user
  2776 0000AC52 8A0D[0FE00000]      <1> 	mov	cl, [i.uid]
  2777 0000AC58 880D[94E30000]      <1> 	mov	[u.uid], cl ; 02/08/2013
  2778                              <1> 		; movb i.uid,u.uid / put user id of owner of file
  2779                              <1> 				 ; / as process user id
  2780                              <1> sysexec_1:
  2781                              <1> 	; 18/10/2215
  2782                              <1> 	; 10/10/2015
  2783                              <1> 	; 24/07/2015
  2784                              <1> 	; 21/07/2015
  2785                              <1> 	; 25/06/2015
  2786                              <1> 	; 24/06/2015
  2787                              <1>         ; Moving arguments to the end of [u.upage]
  2788                              <1> 	; (by regarding page borders in user's memory space)
  2789                              <1> 	;
  2790                              <1> 	; 10/10/2015
  2791                              <1> 	; 21/07/2015
  2792 0000AC5E 89E5                <1> 	mov	ebp, esp ; (**)
  2793                              <1> 	; 18/10/2015
  2794 0000AC60 89EF                <1> 	mov 	edi, ebp
  2795 0000AC62 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2796                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2797 0000AC67 29CF                <1> 	sub	edi, ecx
  2798 0000AC69 89FC                <1> 	mov	esp, edi
  2799 0000AC6B 31C0                <1> 	xor	eax, eax
  2800 0000AC6D A3[70E30000]        <1> 	mov 	[u.nread], eax ; 0
  2801 0000AC72 49                  <1> 	dec	ecx ; 256 - 1
  2802 0000AC73 890D[6CE30000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  2803                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  2804                              <1> sysexec_2:
  2805 0000AC79 8B35[C8E30000]      <1> 	mov	esi, [argv] ; 18/10/2015 
  2806 0000AC7F E866000000          <1> 	call	get_argp
  2807 0000AC84 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  2808                              <1> sysexec_3:
  2809 0000AC89 21C0                <1> 	and	eax, eax
  2810 0000AC8B 0F84BD090000        <1>         jz      sysexec_6
  2811                              <1> 	; 18/10/2015
  2812 0000AC91 010D[C8E30000]      <1> 	add	[argv], ecx ; 4
  2813 0000AC97 66FF05[C6E30000]    <1> 	inc	word [argc]
  2814                              <1> 	;
  2815 0000AC9E A3[68E30000]        <1> 	mov	[u.base], eax
  2816                              <1>  	; 23/10/2015
  2817 0000ACA3 66C705[ADE30000]00- <1> 	mov	word [u.pcount], 0
  2817 0000ACAB 00                  <1>
  2818                              <1> sysexec_4:
  2819 0000ACAC E849100000          <1> 	call	cpass ; get a character from user's core memory
  2820 0000ACB1 750E                <1>         jnz      short sysexec_5
  2821                              <1> 		; (max. 255 chars + null)
  2822                              <1> 	; 18/10/2015
  2823 0000ACB3 28C0                <1> 	sub 	al, al
  2824 0000ACB5 AA                  <1> 	stosb
  2825 0000ACB6 FF05[70E30000]      <1> 	inc	dword [u.nread]
  2826 0000ACBC E98D090000          <1> 	jmp	sysexec_6 ; 24/04/2016
  2827                              <1> sysexec_5:
  2828 0000ACC1 AA                  <1> 	stosb
  2829 0000ACC2 20C0                <1> 	and 	al, al
  2830 0000ACC4 75E6                <1> 	jnz	short sysexec_4
  2831 0000ACC6 B904000000          <1> 	mov	ecx, 4
  2832 0000ACCB 390D[C4E30000]      <1> 	cmp	[ncount], ecx ; 4
  2833 0000ACD1 72A6                <1> 	jb	short sysexec_2
  2834 0000ACD3 8B35[C0E30000]      <1> 	mov	esi, [nbase]
  2835 0000ACD9 010D[C0E30000]      <1> 	add	[nbase], ecx ; 4	
  2836 0000ACDF 66290D[C4E30000]    <1> 	sub	[ncount], cx 
  2837 0000ACE6 8B06                <1> 	mov	eax, [esi]
  2838 0000ACE8 EB9F                <1> 	jmp	short sysexec_3
  2839                              <1> 
  2840                              <1> get_argp:
  2841                              <1> 	; 18/10/2015 (nbase, ncount)
  2842                              <1> 	; 21/07/2015
  2843                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  2844                              <1> 	; Get (virtual) address of argument from user's core memory
  2845                              <1> 	;
  2846                              <1> 	; INPUT:
  2847                              <1> 	;	esi = virtual address of argument pointer
  2848                              <1> 	; OUTPUT:
  2849                              <1> 	;	eax = virtual address of argument
  2850                              <1> 	;
  2851                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  2852                              <1> 	;
  2853 0000ACEA 833D[A5E30000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  2854                              <1> 				    ; (the caller is kernel)
  2855 0000ACF1 7667                <1>         jna     short get_argpk 
  2856                              <1> 	;
  2857 0000ACF3 89F3                <1>      	mov	ebx, esi
  2858 0000ACF5 E8328BFFFF          <1> 	call	get_physical_addr ; get physical address
  2859 0000ACFA 0F8289000000        <1>         jc      get_argp_err
  2860 0000AD00 A3[C0E30000]        <1> 	mov 	[nbase], eax ; physical address	
  2861 0000AD05 66890D[C4E30000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  2862 0000AD0C B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  2863 0000AD11 6639C1              <1> 	cmp	cx, ax ; 4
  2864 0000AD14 735D                <1> 	jnb	short get_argp2
  2865 0000AD16 89F3                <1> 	mov	ebx, esi
  2866 0000AD18 01CB                <1> 	add	ebx, ecx
  2867 0000AD1A E80D8BFFFF          <1> 	call	get_physical_addr ; get physical address
  2868 0000AD1F 7268                <1> 	jc	short get_argp_err
  2869                              <1> 	;push	esi
  2870 0000AD21 89C6                <1> 	mov	esi, eax
  2871 0000AD23 66870D[C4E30000]    <1> 	xchg	cx, [ncount]
  2872 0000AD2A 8735[C0E30000]      <1> 	xchg	esi, [nbase]
  2873 0000AD30 B504                <1> 	mov	ch, 4
  2874 0000AD32 28CD                <1> 	sub	ch, cl
  2875                              <1> get_argp0:
  2876 0000AD34 AC                  <1> 	lodsb
  2877 0000AD35 6650                <1> 	push	ax
  2878 0000AD37 FEC9                <1> 	dec	cl
  2879 0000AD39 75F9                <1>         jnz     short get_argp0
  2880 0000AD3B 8B35[C0E30000]      <1> 	mov	esi, [nbase]
  2881                              <1> 	; 21/07/2015
  2882 0000AD41 0FB6C5              <1> 	movzx	eax, ch
  2883 0000AD44 0105[C0E30000]      <1> 	add	[nbase], eax
  2884 0000AD4A 662905[C4E30000]    <1> 	sub	[ncount], ax
  2885                              <1> get_argp1:
  2886 0000AD51 AC                  <1> 	lodsb
  2887 0000AD52 FECD                <1> 	dec	ch
  2888 0000AD54 743D                <1>         jz      short get_argp3
  2889 0000AD56 6650                <1>         push	ax
  2890 0000AD58 EBF7                <1> 	jmp     short get_argp1
  2891                              <1> get_argpk:
  2892                              <1> 	; Argument is in kernel's memory space
  2893 0000AD5A 66C705[C4E30000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  2893 0000AD62 10                  <1>
  2894 0000AD63 8935[C0E30000]      <1> 	mov	[nbase], esi
  2895 0000AD69 8305[C0E30000]04    <1> 	add	dword [nbase], 4
  2896 0000AD70 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  2897 0000AD72 C3                  <1> 	retn
  2898                              <1> get_argp2:
  2899                              <1> 	; 21/07/2015
  2900                              <1> 	;mov	eax, 4
  2901 0000AD73 8B15[C0E30000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  2902 0000AD79 0105[C0E30000]      <1> 	add	[nbase], eax
  2903 0000AD7F 662905[C4E30000]    <1> 	sub	[ncount], ax
  2904                              <1> 	;
  2905 0000AD86 8B02                <1> 	mov	eax, [edx]
  2906 0000AD88 C3                  <1> 	retn
  2907                              <1> get_argp_err:
  2908 0000AD89 A3[9DE30000]        <1> 	mov	[u.error], eax
  2909 0000AD8E E9F4F2FFFF          <1> 	jmp	error
  2910                              <1> get_argp3:
  2911 0000AD93 B103                <1> 	mov	cl, 3
  2912                              <1> get_argp4:
  2913 0000AD95 C1E008              <1> 	shl	eax, 8
  2914 0000AD98 665A                <1> 	pop	dx
  2915 0000AD9A 88D0                <1> 	mov 	al, dl
  2916 0000AD9C E2F7                <1>         loop    get_argp4
  2917                              <1> 	;pop	esi
  2918 0000AD9E C3                  <1> 	retn	
  2919                              <1> 
  2920                              <1> sysfstat: 
  2921                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2922                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2923                              <1> 	;
  2924                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
  2925                              <1> 	; on open files instead of files given by name. It puts the
  2926                              <1> 	; buffer address on the stack, gets the i-number and
  2927                              <1> 	; checks to see if the file is open for reading or writing.
  2928                              <1> 	; If the file is open for writing (i-number is negative)
  2929                              <1> 	; the i-number is set positive and a branch into 'sysstat'
  2930                              <1> 	; is made.	
  2931                              <1> 	;
  2932                              <1> 	; Calling sequence:
  2933                              <1> 	;	sysfstat; buf
  2934                              <1> 	; Arguments:
  2935                              <1> 	;	buf - buffer address
  2936                              <1> 	;
  2937                              <1> 	; Inputs: *u.r0 - file descriptor
  2938                              <1> 	; Outputs: buffer is loaded with file information
  2939                              <1> 	; ...............................................................
  2940                              <1> 	;				
  2941                              <1> 	; Retro UNIX 8086 v1 modification:
  2942                              <1> 	;       'sysfstat' system call has two arguments; so,
  2943                              <1> 	;	* 1st argument, file descriptor is in BX register
  2944                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2945                              <1> 
  2946                              <1> 	; / set status of open file
  2947                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
  2948 0000AD9F 51                  <1> 	push	ecx
  2949                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
  2950                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
  2951                              <1> 		; jsr r0,getf / get the files i-number
  2952                              <1> 	; BX = file descriptor (file number)
  2953 0000ADA0 E8FF000000          <1> 	call	getf1
  2954 0000ADA5 6621C0              <1> 	and	ax, ax ; i-number of the file
  2955                              <1> 		; tst	r1 / is it 0?
  2956                              <1> 	;jz	error
  2957                              <1> 		; beq error3 / yes, error
  2958 0000ADA8 750F                <1> 	jnz	short sysfstat1
  2959 0000ADAA C705[9DE30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  2959 0000ADB2 0000                <1>
  2960 0000ADB4 E9CEF2FFFF          <1> 	jmp	error
  2961                              <1> sysfstat1:
  2962 0000ADB9 80FC80              <1> 	cmp	ah, 80h
  2963 0000ADBC 7223                <1>         jb      short sysstat1
  2964                              <1> 		; bgt 1f / if i-number is negative (open for writing)
  2965 0000ADBE 66F7D8              <1> 	neg	ax
  2966                              <1> 		; neg r1 / make it positive, then branch
  2967 0000ADC1 EB1E                <1> 	jmp	short sysstat1
  2968                              <1> 		; br 1f / to 1f
  2969                              <1> sysstat:
  2970                              <1> 	; 18/10/2015
  2971                              <1> 	; 07/10/2015
  2972                              <1> 	; 02/09/2015
  2973                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2974                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2975                              <1> 	;
  2976                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
  2977                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
  2978                              <1> 	; long and information about the file placed in it.	
  2979                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
  2980                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
  2981                              <1> 	; is then loaded and the results are given in the UNIX
  2982                              <1> 	; Programmers Manual sysstat (II).	
  2983                              <1> 	;
  2984                              <1> 	; Calling sequence:
  2985                              <1> 	;	sysstat; name; buf
  2986                              <1> 	; Arguments:
  2987                              <1> 	;	name - points to the name of the file
  2988                              <1> 	;	buf - address of a 34 bytes buffer
  2989                              <1> 	; Inputs: -
  2990                              <1> 	; Outputs: buffer is loaded with file information
  2991                              <1> 	; ...............................................................
  2992                              <1> 	;				
  2993                              <1> 	; Retro UNIX 8086 v1 modification: 
  2994                              <1> 	;       'sysstat' system call has two arguments; so,
  2995                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  2996                              <1> 	;	to get sysstat system call arguments from the user;
  2997                              <1> 	;	* 1st argument, name is pointed to by BX register
  2998                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2999                              <1> 	;
  3000                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  3001                              <1> 	;	      arguments which were in these registers;
  3002                              <1> 	;	      but, it returns by putting the 1st argument
  3003                              <1> 	;	      in 'u.namep' and the 2nd argument
  3004                              <1> 	;	      on top of stack. (1st argument is offset of the
  3005                              <1> 	;	      file/path name in the user's program segment.)		 	
  3006                              <1> 	
  3007                              <1> 	; / ; name of file; buffer - get files status
  3008                              <1> 		; jsr r0,arg2 / get the 2 arguments
  3009 0000ADC3 891D[60E30000]      <1> 	mov	[u.namep], ebx
  3010 0000ADC9 51                  <1> 	push	ecx
  3011 0000ADCA E80C010000          <1> 	call	namei
  3012                              <1> 		; jsr r0,namei / get the i-number for the file
  3013                              <1> 	;jc	error
  3014                              <1> 		; br error3 / no such file, error
  3015 0000ADCF 7310                <1> 	jnc	short sysstat1
  3016                              <1> 	; pop 	ecx
  3017                              <1> sysstat_err0:
  3018                              <1> 	; 'file not found !' error
  3019 0000ADD1 C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3019 0000ADD9 0000                <1>
  3020 0000ADDB E9A7F2FFFF          <1> 	jmp	error
  3021                              <1> 
  3022 0000ADE0 00                  <1> statx: db 0
  3023                              <1> 
  3024                              <1> sysstat1: ; 1:
  3025 0000ADE1 E8FA0F0000          <1> 	call	iget
  3026                              <1> 		; jsr r0,iget / get the i-node into core
  3027                              <1> 	; 07/10/2015 (ax = [ii], inode number)
  3028                              <1> 	; 02/09/2015
  3029 0000ADE6 8F05[68E30000]      <1> 	pop	dword [u.base]
  3030                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  3031 0000ADEC E858000000          <1> 	call	sysstat_gpa ; get physical address
  3032 0000ADF1 730A                <1> 	jnc 	short sysstat2
  3033                              <1> sysstat_err1:
  3034 0000ADF3 A3[9DE30000]        <1> 	mov	dword [u.error], eax ; error code
  3035 0000ADF8 E98AF2FFFF          <1> 	jmp	error
  3036                              <1> sysstat2:
  3037 0000ADFD A0[CDE30000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  3038 0000AE02 AA                  <1> 	stosb
  3039 0000AE03 FF05[68E30000]      <1> 	inc 	dword [u.base]
  3040 0000AE09 6649                <1> 	dec 	cx
  3041 0000AE0B 7505                <1> 	jnz	short sysstat3
  3042 0000AE0D E837000000          <1> 	call	sysstat_gpa
  3043                              <1> 	;jc	short sysstat_err1
  3044                              <1> sysstat3:
  3045 0000AE12 A0[CEE30000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  3046 0000AE17 AA                  <1> 	stosb
  3047                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  3048 0000AE18 FF05[68E30000]      <1> 	inc 	dword [u.base]
  3049                              <1> 	;dec 	word [u.pcount]
  3050 0000AE1E 6649                <1> 	dec	cx
  3051 0000AE20 7505                <1> 	jnz	short sysstat4
  3052 0000AE22 E822000000          <1> 	call	sysstat_gpa
  3053                              <1> 	;jc	short sysstat_err1	
  3054                              <1> sysstat4:
  3055 0000AE27 BE[0CE00000]        <1> 	mov	esi, inode
  3056                              <1> 		; mov $inode,r2 / r2 points to i-node
  3057                              <1> sysstat5: ; 1:
  3058 0000AE2C A4                  <1> 	movsb
  3059                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  3060 0000AE2D FF05[68E30000]      <1> 	inc 	dword [u.base]
  3061                              <1> 	;dec 	word [u.pcount]
  3062 0000AE33 6649                <1> 	dec	cx
  3063 0000AE35 7505                <1> 	jnz	short sysstat6
  3064 0000AE37 E80D000000          <1> 	call	sysstat_gpa
  3065                              <1> 	;jc	short sysstat_err1
  3066                              <1> sysstat6:		
  3067 0000AE3C 81FE[2CE00000]      <1> 	cmp	esi, inode + 32
  3068                              <1> 		; cmp r2,$inode+32 / done?
  3069 0000AE42 75E8                <1> 	jne	short sysstat5
  3070                              <1> 		; bne 1b / no, go back
  3071 0000AE44 E95EF2FFFF          <1> 	jmp	sysret
  3072                              <1> 		; br sysret3 / return through sysret
  3073                              <1> 	;
  3074                              <1> sysstat_gpa: ; get physical address of file status buffer
  3075                              <1> 	; 02/09/2015
  3076 0000AE49 8B1D[68E30000]      <1> 	mov 	ebx, [u.base]
  3077                              <1> 	; 07/10/2015
  3078 0000AE4F E8D889FFFF          <1> 	call	get_physical_addr ; get physical address
  3079                              <1> 	;jc	short sysstat_gpa1
  3080 0000AE54 729D                <1> 	jc	short sysstat_err1
  3081                              <1> 	; 18/10/2015
  3082 0000AE56 89C7                <1> 	mov	edi, eax ; physical address
  3083                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3084                              <1> ;sysstat_gpa1:
  3085 0000AE58 C3                  <1> 	retn
  3086                              <1> 
  3087                              <1> fclose:
  3088                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  3089                              <1> 	;            (32 bit offset pointer modification)
  3090                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  3091                              <1> 	;
  3092                              <1> 	; Given the file descriptor (index to the u.fp list)
  3093                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  3094                              <1> 	; If i-node is active (i-number > 0) the entry in 
  3095                              <1> 	; u.fp list is cleared. If all the processes that opened
  3096                              <1> 	; that file close it, then fsp etry is freed and the file
  3097                              <1> 	; is closed. If not a return is taken. 
  3098                              <1> 	; If the file has been deleted while open, 'anyi' is called
  3099                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  3100                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  3101                              <1> 	; a check is made to see if the file is special.	
  3102                              <1> 	;
  3103                              <1> 	; INPUTS ->
  3104                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  3105                              <1> 	;    u.fp - list of entries in the fsp table
  3106                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  3107                              <1> 	; OUTPUTS ->
  3108                              <1> 	;    r1 - contains the same file descriptor
  3109                              <1> 	;    r2 - contains i-number
  3110                              <1> 	;
  3111                              <1> 	; ((AX = R1))
  3112                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
  3113                              <1> 	;
  3114                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  3115                              <1> 	;              if i-number of the file is 0. (error)  	
  3116                              <1> 	;
  3117 0000AE59 0FB7D0              <1> 	movzx	edx, ax ; **
  3118 0000AE5C 6650                <1> 	push	ax ; ***
  3119                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
  3120                              <1> 			     ; / the index to u.fp list)
  3121 0000AE5E E83F000000          <1> 	call	getf
  3122                              <1> 		; jsr r0,getf / r1 contains i-number, 
  3123                              <1> 			    ; / cdev has device =, u.fofp 
  3124                              <1> 			    ; / points to 3rd word of fsp entry
  3125 0000AE63 6683F801            <1> 	cmp	ax, 1 ; r1
  3126                              <1> 		; tst r1 / is i-number 0?
  3127 0000AE67 7236                <1> 	jb	short fclose_2
  3128                              <1> 		; beq 1f / yes, i-node not active so return
  3129                              <1> 		; tst (r0)+ / no, jump over error return
  3130 0000AE69 89D3                <1> 	mov	ebx, edx ; **
  3131 0000AE6B 6689C2              <1> 	mov 	dx, ax ; *
  3132                              <1> 		; mov r1,r2 / move i-number to r2 ;*
  3133                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
  3134                              <1> 			    ; / which is index to u.fp ; **
  3135 0000AE6E C683[4EE30000]00    <1> 	mov	byte [ebx+u.fp], 0
  3136                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3137 0000AE75 8B1D[58E30000]      <1> 	mov	ebx, [u.fofp]
  3138                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3139                              <1> fclose_0:
  3140 0000AE7B FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
  3141                              <1> 		; decb 2(r1) / decrement the number of processes 
  3142                              <1> 			   ; / that have opened the file
  3143 0000AE7E 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
  3144                              <1> 		; bge 1f / if all processes haven't closed the file, return
  3145                              <1> 	;
  3146 0000AE80 6652                <1> 	push	dx ;*
  3147                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3148 0000AE82 6631C0              <1> 	xor	ax, ax ; 0
  3149 0000AE85 668943FC            <1> 	mov	[ebx-4], ax ; 0
  3150                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3151 0000AE89 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
  3152                              <1> 		; tstb	3(r1) / has this file been deleted
  3153 0000AE8C 20C0                <1> 	and	al, al
  3154 0000AE8E 7408                <1> 	jz	short fclose_1
  3155                              <1> 		; beq 2f / no, branch
  3156 0000AE90 6689D0              <1> 	mov	ax, dx ; *
  3157                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3158                              <1> 	; AX = inode number
  3159 0000AE93 E868040000          <1> 	call	anyi
  3160                              <1> 		; jsr r0,anyi / free all blocks related to i-number
  3161                              <1> 			    ; / check if file appears in fsp again
  3162                              <1> fclose_1: ; 2:
  3163 0000AE98 6658                <1> 	pop	ax ; *
  3164                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3165 0000AE9A E8460F0000          <1> 	call	iclose ; close if it is special file 
  3166                              <1> 		; jsr r0,iclose / check to see if its a special file
  3167                              <1> fclose_2: ; 1:
  3168 0000AE9F 6658                <1> 	pop	ax ; ***
  3169                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3170 0000AEA1 C3                  <1> 	retn
  3171                              <1> 		; rts r0
  3172                              <1> 
  3173                              <1> getf:	; / get the device number and the i-number of an open file
  3174                              <1> 	; 13/05/2015
  3175                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3176                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3177                              <1> 	;
  3178 0000AEA2 89C3                <1> 	mov	ebx, eax
  3179                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3180 0000AEA4 83FB0A              <1> 	cmp	ebx, 10
  3181                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3182 0000AEA7 730A                <1>         jnb	short getf2 ; 13/05/2015
  3183                              <1> 	;jnb     error
  3184                              <1> 		; bhis error3 / u.fp is table of users open files, 
  3185                              <1> 			    ; / index in fsp table
  3186 0000AEA9 8A9B[4EE30000]      <1> 	mov	bl, [ebx+u.fp]
  3187                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
  3188                              <1> 		                  ; / in fsp table
  3189 0000AEAF 08DB                <1> 	or	bl, bl
  3190 0000AEB1 7503                <1> 	jnz	short getf3
  3191                              <1> 	;jz	short getf4
  3192                              <1> 		; beq 1f / if its zero return
  3193                              <1> getf2:
  3194                              <1> 	; 'File not open !' error (ax=0)
  3195 0000AEB3 29C0                <1> 	sub	eax, eax
  3196 0000AEB5 C3                  <1> 	retn
  3197                              <1> getf3:	
  3198                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
  3199                              <1> 	;
  3200                              <1> 	; 'fsp' table (10 bytes/entry)
  3201                              <1> 	; bit 15				   bit 0
  3202                              <1> 	; ---|-------------------------------------------
  3203                              <1> 	; r/w|		i-number of open file
  3204                              <1> 	; ---|-------------------------------------------
  3205                              <1> 	;		   device number
  3206                              <1> 	; -----------------------------------------------
  3207                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3208                              <1> 	; -----------------------------------------------
  3209                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3210                              <1> 	; ----------------------|------------------------
  3211                              <1> 	;  flag that says file 	| number of processes
  3212                              <1> 	;   has been deleted	| that have file open 
  3213                              <1> 	; ----------------------|------------------------
  3214                              <1> 	;
  3215 0000AEB6 B80A000000          <1> 	mov	eax, 10
  3216 0000AEBB F6E3                <1> 	mul	bl
  3217 0000AEBD BB[16E10000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
  3218 0000AEC2 01C3                <1> 	add	ebx, eax
  3219                              <1> 		; asl r1
  3220                              <1> 		; asl r1 / multiply by 8 to get index into 
  3221                              <1> 		       ; / fsp table entry
  3222                              <1> 		; asl r1
  3223                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
  3224                              <1> 			      ; / in the fsp entry
  3225 0000AEC4 891D[58E30000]      <1> 	mov	[u.fofp], ebx
  3226                              <1> 		; mov r1,u.fofp / save address of 3rd word 
  3227                              <1> 			      ; / in fsp entry in u.fofp
  3228 0000AECA 4B                  <1> 	dec	ebx
  3229 0000AECB 4B                  <1> 	dec	ebx
  3230 0000AECC 668B03              <1> 	mov	ax, [ebx]
  3231                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3232 0000AECF 66A3[2AE30000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
  3233                              <1> 			     ;;dev number is in 1 byte
  3234                              <1> 		; mov -(r1),cdev / remove the device number  cdev
  3235 0000AED5 4B                  <1> 	dec	ebx
  3236 0000AED6 4B                  <1> 	dec	ebx
  3237 0000AED7 668B03              <1> 	mov	ax, [ebx]
  3238                              <1> 		; mov -(r1),r1 / and the i-number  r1
  3239                              <1> getf4:	; 1:
  3240 0000AEDA C3                  <1> 	retn
  3241                              <1> 		; rts r0
  3242                              <1> 
  3243                              <1> namei:
  3244                              <1> 	; 04/12/2015 (14 byte file names)
  3245                              <1> 	; 18/10/2015 (nbase, ncount)
  3246                              <1> 	; 12/10/2015
  3247                              <1> 	; 21/08/2015
  3248                              <1> 	; 18/07/2015
  3249                              <1> 	; 02/07/2015
  3250                              <1> 	; 17/06/2015
  3251                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
  3252                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3253                              <1> 	;
  3254                              <1> 	; 'namei' takes a file path name and returns i-number of
  3255                              <1> 	; the file in the current directory or the root directory
  3256                              <1> 	; (if the first character of the pathname is '/').	
  3257                              <1> 	;
  3258                              <1> 	; INPUTS ->
  3259                              <1> 	;    u.namep - points to a file path name
  3260                              <1> 	;    u.cdir - i-number of users directory
  3261                              <1> 	;    u.cdev - device number on which user directory resides	
  3262                              <1> 	; OUTPUTS ->
  3263                              <1> 	;    r1 - i-number of file
  3264                              <1> 	;    cdev
  3265                              <1> 	;    u.dirbuf - points to directory entry where a match 
  3266                              <1> 	;               occurs in the search for file path name.
  3267                              <1> 	;	        If no match u.dirb points to the end of 
  3268                              <1> 	;               the directory and r1 = i-number of the current
  3269                              <1> 	;	        directory.	
  3270                              <1> 	; ((AX = R1))
  3271                              <1> 	;
  3272                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
  3273                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
  3274                              <1> 	;
  3275                              <1> 
  3276 0000AEDB 66A1[4CE30000]      <1> 	mov	ax, [u.cdir]
  3277                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3278                              <1> 			      ; / in r1
  3279 0000AEE1 668B15[92E30000]    <1> 	mov	dx, [u.cdrv]
  3280 0000AEE8 668915[2AE30000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
  3281                              <1> 				    ; device/drive number is in 1 byte, 
  3282                              <1> 				    ; not in 1 word!
  3283                              <1> 		; mov u.cdev,cdev / device number for users directory 
  3284                              <1> 				; / into cdev
  3285                              <1> 	; 12/10/2015
  3286                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3287                              <1>       	 ; convert virtual (pathname) addr to physical address
  3288 0000AEEF E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
  3289                              <1> 		; esi = physical address of [u.namep]
  3290                              <1> 		; ecx = byte count in the page
  3291 0000AEF4 803E2F              <1> 	cmp	byte [esi], '/'
  3292                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3293 0000AEF7 751E                <1> 	jne	short namei_1
  3294                              <1> 		; bne 1f
  3295 0000AEF9 FF05[60E30000]      <1> 	inc	dword [u.namep]
  3296                              <1> 		; inc u.namep / go to next char
  3297 0000AEFF 6649                <1> 	dec	cx ; remain byte count in the page
  3298 0000AF01 7506                <1> 	jnz	short namei_0
  3299                              <1> 	; 12/10/2015
  3300 0000AF03 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  3301                              <1> 		; esi = physical address (page start + offset)
  3302                              <1> 		; ecx = byte count in the page
  3303 0000AF08 4E                  <1> 	dec	esi
  3304                              <1> namei_0:
  3305 0000AF09 46                  <1> 	inc 	esi  ; go to next char
  3306 0000AF0A 66A1[34E30000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
  3307                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3308 0000AF10 C605[2AE30000]00    <1> 	mov	byte [cdev], 0
  3309                              <1> 		; clr cdev / clear device number
  3310                              <1> namei_1: ; 1:
  3311 0000AF17 F606FF              <1> 	test	byte [esi], 0FFh
  3312 0000AF1A 74BE                <1> 	jz	short getf4
  3313                              <1> 	;jz      nig
  3314                              <1> 		; tstb *u.namep / is the character in file name a nul
  3315                              <1> 		; beq nig / yes, end of file name reached; 
  3316                              <1> 			; / branch to "nig"
  3317                              <1> namei_2: ; 1:
  3318                              <1> 	; 18/10/2015
  3319 0000AF1C 8935[C0E30000]      <1> 	mov 	[nbase], esi
  3320 0000AF22 66890D[C4E30000]    <1> 	mov 	[ncount], cx
  3321                              <1> 	;
  3322                              <1> 	;mov	dx, 2
  3323 0000AF29 B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
  3324 0000AF2B E8BB0E0000          <1> 	call	access
  3325                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
  3326                              <1> 	; 'access' will not return here if user has not "r" permission !
  3327 0000AF30 66F705[0CE00000]00- <1> 	test 	word [i.flgs], 4000h
  3327 0000AF38 40                  <1>
  3328                              <1> 		; bit $40000,i.flgs / directory i-node?
  3329 0000AF39 746A                <1>         jz      short namei_err
  3330                              <1> 		; beq error3 / no, got an error
  3331                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3332 0000AF3B 31C0                <1> 	xor	eax, eax
  3333 0000AF3D A3[64E30000]        <1> 	mov	[u.off], eax ; 0
  3334 0000AF42 66A1[D1E30000]      <1> 	mov	ax, [i.size]
  3335 0000AF48 A3[5CE30000]        <1> 	mov	[u.dirp], eax
  3336                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
  3337                              <1> 		; clr u.off / u.off is file offset used by user
  3338 0000AF4D C705[58E30000]-     <1> 	mov	dword [u.fofp], u.off
  3338 0000AF53 [64E30000]          <1>
  3339                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
  3340                              <1> 				  ; / the offset portion of fsp entry
  3341                              <1> namei_3: ; 2:
  3342 0000AF57 C705[68E30000]-     <1> 	mov	dword [u.base], u.dirbuf
  3342 0000AF5D [7AE30000]          <1>
  3343                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  3344                              <1> 				    ; / copied from a directory
  3345 0000AF61 C705[6CE30000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  3345 0000AF69 0000                <1>
  3346                              <1>  		; mov $10.,u.count / u.count is byte count 
  3347                              <1> 				 ; / for reads and writes
  3348 0000AF6B 66A1[CDE30000]      <1> 	mov 	ax, [ii]
  3349                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  3350 0000AF71 FE05[AFE30000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  3351 0000AF77 E80E090000          <1>     	call	readi
  3352                              <1> 		; jsr r0,readi / read 10. bytes of file 
  3353                              <1> 		      ; with i-number (r1); i.e. read a directory entry
  3354 0000AF7C 8B0D[70E30000]      <1> 	mov 	ecx, [u.nread]
  3355 0000AF82 09C9                <1> 	or 	ecx, ecx
  3356                              <1> 		; tst u.nread
  3357 0000AF84 741B                <1> 	jz	short nib
  3358                              <1> 		; ble nib / gives error return
  3359                              <1> 	;
  3360 0000AF86 668B1D[7AE30000]    <1> 	mov 	bx, [u.dirbuf]
  3361 0000AF8D 6621DB              <1> 	and 	bx, bx       
  3362                              <1> 		; tst u.dirbuf /
  3363 0000AF90 7522                <1> 	jnz	short namei_4
  3364                              <1> 		; bne 3f / branch when active directory entry 
  3365                              <1> 		       ; / (i-node word in entry non zero)
  3366 0000AF92 A1[64E30000]        <1> 	mov	eax, [u.off]
  3367 0000AF97 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  3368 0000AF9A A3[5CE30000]        <1> 	mov	[u.dirp], eax
  3369                              <1> 		; mov u.off,u.dirp
  3370                              <1> 		; sub $10.,u.dirp
  3371 0000AF9F EBB6                <1> 	jmp	short namei_3
  3372                              <1> 		; br 2b
  3373                              <1> 
  3374                              <1> 	; 18/07/2013
  3375                              <1> nib: 
  3376 0000AFA1 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  3377 0000AFA3 F9                  <1> 	stc
  3378                              <1> nig:
  3379 0000AFA4 C3                  <1> 	retn
  3380                              <1> 
  3381                              <1> namei_err:
  3382                              <1> 	; 16/06/2015
  3383 0000AFA5 C705[9DE30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  3383 0000AFAD 0000                <1>
  3384 0000AFAF E9D3F0FFFF          <1> 	jmp	error
  3385                              <1> 
  3386                              <1> namei_4: ; 3:
  3387                              <1> 	; 18/10/2015
  3388                              <1> 	; 12/10/2015
  3389                              <1> 	; 21/08/2015
  3390                              <1> 	; 18/07/2015
  3391 0000AFB4 8B2D[60E30000]      <1> 	mov	ebp, [u.namep]
  3392                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  3393 0000AFBA BF[7CE30000]        <1> 	mov 	edi, u.dirbuf + 2
  3394                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
  3395                              <1> 	; 18/10/2015
  3396 0000AFBF 8B35[C0E30000]      <1> 	mov	esi, [nbase]	
  3397 0000AFC5 668B0D[C4E30000]    <1> 	mov	cx, [ncount]
  3398                              <1> 	;
  3399 0000AFCC 6621C9              <1> 	and	cx, cx
  3400 0000AFCF 7505                <1> 	jnz	short namei_5	
  3401                              <1> 	;
  3402 0000AFD1 E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3403                              <1> 		; esi = physical address (page start + offset)
  3404                              <1> 		; ecx = byte count in the page
  3405                              <1> namei_5: ; 3:
  3406 0000AFD6 45                  <1> 	inc	ebp ; 18/07/2015
  3407 0000AFD7 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
  3408                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
  3409 0000AFD8 08C0                <1> 	or 	al, al
  3410 0000AFDA 741D                <1> 	jz 	short namei_7
  3411                              <1> 		; beq 3f / if char is nul, then the last char in string
  3412                              <1> 			; / has been moved
  3413 0000AFDC 3C2F                <1> 	cmp	al, '/'
  3414                              <1> 		; cmp r4,$'/ / is char a </>
  3415 0000AFDE 7419                <1> 	je 	short namei_7
  3416                              <1> 		; beq 3f	
  3417                              <1> 	; 12/10/2015
  3418 0000AFE0 6649                <1> 	dec	cx ; remain byte count in the page
  3419 0000AFE2 7505                <1> 	jnz	short namei_6
  3420 0000AFE4 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3421                              <1> 		; esi = physical address (page start + offset)
  3422                              <1> 		; ecx = byte count in the page
  3423                              <1> namei_6:
  3424 0000AFE9 81FF[8AE30000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3425                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
  3426                              <1> 				     ; / all 8 bytes of file name
  3427 0000AFEF 74E5                <1> 	je	short namei_5
  3428                              <1> 		; beq 3b
  3429 0000AFF1 AE                  <1> 	scasb	
  3430                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  3431                              <1> 			      ; / char read from directory
  3432 0000AFF2 74E2                <1> 	je 	short namei_5
  3433                              <1> 		; beq 3b / branch if chars match
  3434                              <1> 
  3435 0000AFF4 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
  3436                              <1> 		; br 2b / file names do not match go to next directory entry
  3437                              <1> namei_7: ; 3:
  3438 0000AFF9 81FF[8AE30000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3439                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
  3440 0000AFFF 740A                <1> 	je	short namei_8
  3441                              <1> 		; beq 3f
  3442 0000B001 8A27                <1> 	mov 	ah, [edi]
  3443                              <1> 	;inc 	edi 
  3444 0000B003 20E4                <1> 	and 	ah, ah
  3445                              <1> 		; tstb (r3)+ /
  3446 0000B005 0F854CFFFFFF        <1>         jnz     namei_3
  3447                              <1> 		; bne 2b
  3448                              <1> namei_8: ; 3
  3449 0000B00B 892D[60E30000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
  3450                              <1> 		; mov r2,u.namep / u.namep points to char 
  3451                              <1> 			       ; / following a / or nul
  3452                              <1> 	;mov	bx, [u.dirbuf]
  3453                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
  3454                              <1> 				; / entry to r1
  3455 0000B011 20C0                <1> 	and 	al, al
  3456                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
  3457                              <1> 		      ;  / if r4 = </> then go to next directory
  3458                              <1> 	; mov	ax, bx
  3459 0000B013 66A1[7AE30000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
  3460 0000B019 0F85FDFEFFFF        <1>         jnz     namei_2 
  3461                              <1> 		; bne 1b
  3462                              <1> 	; AX = i-number of the file
  3463                              <1> ;;nig:
  3464 0000B01F C3                  <1> 	retn
  3465                              <1> 		; tst (r0)+ / gives non-error return
  3466                              <1> ;;nib:
  3467                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
  3468                              <1> 		       ; ax = 0 -> file not found 
  3469                              <1> ;;	stc	; 27/05/2013
  3470                              <1> ;;	retn
  3471                              <1> 		; rts r0
  3472                              <1> 
  3473                              <1> trans_addr_nmbp:
  3474                              <1> 	; 18/10/2015
  3475                              <1> 	; 12/10/2015
  3476 0000B020 8B2D[60E30000]      <1> 	mov 	ebp, [u.namep]
  3477                              <1> trans_addr_nm: 
  3478                              <1> 	; Convert virtual (pathname) address to physical address
  3479                              <1> 	; (Retro UNIX 386 v1 feature only !)
  3480                              <1> 	; 18/10/2015
  3481                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  3482                              <1> 	; 02/07/2015
  3483                              <1> 	; 17/06/2015
  3484                              <1> 	; 16/06/2015
  3485                              <1> 	;
  3486                              <1> 	; INPUTS: 
  3487                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  3488                              <1> 	;	[u.pgdir] = user's page directory
  3489                              <1> 	; OUTPUT:
  3490                              <1> 	;       esi = physical address of the pathname
  3491                              <1> 	;	ecx = remain byte count in the page
  3492                              <1> 	;
  3493                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
  3494                              <1> 	;
  3495 0000B026 833D[A5E30000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  3496 0000B02D 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  3497                              <1> 				     ; it is already physical address
  3498 0000B02F 50                  <1>    	push	eax	
  3499 0000B030 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  3500 0000B032 E8F587FFFF          <1>        	call	get_physical_addr ; get physical address
  3501 0000B037 7204                <1> 	jc	short tr_addr_nm_err
  3502                              <1> 	; 18/10/2015
  3503                              <1> 	; eax = physical address 
  3504                              <1> 	; cx = remain byte count in page (1-4096) 
  3505                              <1> 		; 12/10/2015 (cx = [u.pncount])
  3506 0000B039 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  3507 0000B03B 58                  <1> 	pop	eax 
  3508 0000B03C C3                  <1> 	retn
  3509                              <1> 
  3510                              <1> tr_addr_nm_err:
  3511 0000B03D A3[9DE30000]        <1> 	mov	[u.error], eax
  3512                              <1> 	;pop 	eax
  3513 0000B042 E940F0FFFF          <1> 	jmp	error
  3514                              <1> 
  3515                              <1> trans_addr_nmk:
  3516                              <1> 	; 12/10/2015
  3517                              <1> 	; 02/07/2015
  3518 0000B047 8B35[60E30000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  3519 0000B04D 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  3520 0000B051 C3                  <1> 	retn
  3521                              <1> 
  3522                              <1> syschdir:
  3523                              <1> 	; / makes the directory specified in the argument
  3524                              <1> 	; / the current directory
  3525                              <1> 	;
  3526                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3527                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3528                              <1> 	;
  3529                              <1> 	; 'syschdir' makes the directory specified in its argument
  3530                              <1> 	; the current working directory.
  3531                              <1> 	;
  3532                              <1> 	; Calling sequence:
  3533                              <1> 	;	syschdir; name
  3534                              <1> 	; Arguments:
  3535                              <1> 	;	name - address of the path name of a directory
  3536                              <1> 	;	       terminated by nul byte.	
  3537                              <1> 	; Inputs: -
  3538                              <1> 	; Outputs: -
  3539                              <1> 	; ...............................................................
  3540                              <1> 	;				
  3541                              <1> 	; Retro UNIX 8086 v1 modification:
  3542                              <1> 	;	 The user/application program puts address of 
  3543                              <1> 	;	 the path name in BX register as 'syschdir' 
  3544                              <1> 	; 	 system call argument.
  3545                              <1> 
  3546 0000B052 891D[60E30000]      <1> 	mov	[u.namep], ebx
  3547                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  3548 0000B058 E87EFEFFFF          <1> 	call	namei
  3549                              <1> 		; jsr r0,namei / find its i-number
  3550                              <1> 	;jc	error
  3551                              <1> 		; br error3
  3552 0000B05D 730F                <1> 	jnc	short syschdir0
  3553                              <1> 	; 'directory not found !' error
  3554 0000B05F C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  3554 0000B067 0000                <1>
  3555 0000B069 E919F0FFFF          <1> 	jmp	error
  3556                              <1> syschdir0:
  3557 0000B06E E8780D0000          <1> 	call	access
  3558                              <1> 		; jsr r0,access; 2 / get i-node into core
  3559 0000B073 66F705[0CE00000]00- <1> 	test	word [i.flgs], 4000h
  3559 0000B07B 40                  <1>
  3560                              <1> 		; bit $40000,i.flgs / is it a directory?
  3561                              <1> 	;jz	error 
  3562                              <1> 		; beq error3 / no error
  3563 0000B07C 750F                <1> 	jnz	short syschdir1
  3564 0000B07E C705[9DE30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  3564 0000B086 0000                <1>
  3565 0000B088 E9FAEFFFFF          <1> 	jmp	error
  3566                              <1> syschdir1:
  3567 0000B08D 66A3[4CE30000]      <1> 	mov	[u.cdir], ax
  3568                              <1> 		; mov r1,u.cdir / move i-number to users 
  3569                              <1> 			      ; / current directory
  3570 0000B093 66A1[2AE30000]      <1> 	mov	ax, [cdev]
  3571 0000B099 66A3[92E30000]      <1> 	mov	[u.cdrv], ax
  3572                              <1> 		; mov cdev,u.cdev / move its device to users 
  3573                              <1> 			        ; / current device
  3574 0000B09F E903F0FFFF          <1> 	jmp	sysret
  3575                              <1> 		; br sysret3
  3576                              <1> 	
  3577                              <1> syschmod: ; < change mode of file >
  3578                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3579                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3580                              <1> 	;
  3581                              <1> 	; 'syschmod' changes mode of the file whose name is given as
  3582                              <1> 	; null terminated string pointed to by 'name' has it's mode 
  3583                              <1> 	; changed to 'mode'.
  3584                              <1> 	;
  3585                              <1> 	; Calling sequence:
  3586                              <1> 	;	syschmod; name; mode
  3587                              <1> 	; Arguments:
  3588                              <1> 	;	name - address of the file name
  3589                              <1> 	;	       terminated by null byte.
  3590                              <1> 	;	mode - (new) mode/flags < attributes >
  3591                              <1> 	;	
  3592                              <1> 	; Inputs: -
  3593                              <1> 	; Outputs: -
  3594                              <1> 	; ...............................................................
  3595                              <1> 	;				
  3596                              <1> 	; Retro UNIX 8086 v1 modification: 
  3597                              <1> 	;       'syschmod' system call has two arguments; so,
  3598                              <1> 	;	* 1st argument, name is pointed to by BX register
  3599                              <1> 	;	* 2nd argument, mode is in CX register
  3600                              <1> 	;
  3601                              <1> 	; Mode bits (Flags):
  3602                              <1> 	;	bit 0 - write permission for non-owner (1)
  3603                              <1> 	;	bit 1 - read permission for non-owner (2)
  3604                              <1> 	;	bit 2 - write permission for owner (4)
  3605                              <1> 	;	bit 3 - read permission for owner (8)
  3606                              <1> 	;	bit 4 - executable flag (16) 	
  3607                              <1> 	;	bit 5 - set user ID on execution flag (32) 
  3608                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
  3609                              <1> 	;	bit 12 - large file flag (4096)
  3610                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
  3611                              <1> 	;	bit 14 - directory flag (16384)
  3612                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
  3613                              <1> 
  3614                              <1> 	; / name; mode
  3615 0000B0A4 E814000000          <1> 	call	isown
  3616                              <1> 		;jsr r0,isown / get the i-node and check user status
  3617 0000B0A9 66F705[0CE00000]00- <1> 	test	word [i.flgs], 4000h
  3617 0000B0B1 40                  <1>
  3618                              <1> 		; bit	$40000,i.flgs / directory?
  3619 0000B0B2 7402                <1> 	jz	short syschmod1
  3620                              <1> 		; beq 2f / no
  3621                              <1> 	; AL = (new) mode
  3622 0000B0B4 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
  3623                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
  3624                              <1> 			   ; / executable modes
  3625                              <1> syschmod1: ; 2:
  3626 0000B0B6 A2[0CE00000]        <1> 	mov	[i.flgs], al	
  3627                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
  3628 0000B0BB EB42                <1> 	jmp	short isown1
  3629                              <1> 		; br 1f
  3630                              <1> 
  3631                              <1> isown:
  3632                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3633                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3634                              <1> 	;
  3635                              <1> 	; 'isown' is given a file name (the 1st argument).
  3636                              <1> 	;  It find the i-number of that file via 'namei' 
  3637                              <1> 	;  then gets the i-node into core via 'iget'.
  3638                              <1> 	;  It then tests to see if the user is super user. 
  3639                              <1> 	;  If not, it cheks to see if the user is owner of 
  3640                              <1> 	;  the file. If he is not an error occurs.
  3641                              <1> 	;  If user is the owner 'setimod' is called to indicate
  3642                              <1> 	;  the inode has been modificed and the 2nd argument of
  3643                              <1> 	;  the call is put in r2.
  3644                              <1> 	;
  3645                              <1> 	; INPUTS ->
  3646                              <1> 	;    arguments of syschmod and syschown calls
  3647                              <1> 	; OUTPUTS ->
  3648                              <1> 	;    u.uid - id of user
  3649                              <1> 	;    imod - set to a 1
  3650                              <1> 	;    r2 - contains second argument of the system call				 	
  3651                              <1> 	;
  3652                              <1> 	;   ((AX=R2) output as 2nd argument)
  3653                              <1> 	;
  3654                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  3655                              <1> 	;
  3656                              <1> 		; jsr r0,arg2 / u.namep points to file name
  3657                              <1> 	;; ! 2nd argument on top of stack !
  3658                              <1> 	;; 22/06/2015 - 32 bit modifications
  3659                              <1> 	;; 07/07/2013
  3660 0000B0BD 891D[60E30000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  3661 0000B0C3 51                  <1> 	push 	ecx ;; 2nd argument
  3662                              <1> 	;;
  3663 0000B0C4 E812FEFFFF          <1> 	call	namei
  3664                              <1> 		; jsr r0,namei / get its i-number
  3665                              <1>        ; Retro UNIX 8086 v1 modification !
  3666                              <1>        ; ax = 0 -> file not found 
  3667                              <1> 	;and	ax, ax
  3668                              <1> 	;jz	error
  3669                              <1> 	;jc	error ; 27/05/2013
  3670                              <1> 		; br error3
  3671 0000B0C9 730F                <1> 	jnc	short isown0
  3672                              <1> 	; 'file not found !' error
  3673 0000B0CB C705[9DE30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3673 0000B0D3 0000                <1>
  3674 0000B0D5 E9ADEFFFFF          <1> 	jmp	error
  3675                              <1> isown0:
  3676 0000B0DA E8010D0000          <1> 	call	iget
  3677                              <1> 		; jsr r0,iget / get i-node into core
  3678 0000B0DF A0[94E30000]        <1> 	mov	al, [u.uid] ; 02/08/2013
  3679 0000B0E4 08C0                <1> 	or	al, al
  3680                              <1> 		; tstb u.uid / super user?
  3681 0000B0E6 7417                <1> 	jz	short isown1
  3682                              <1> 		; beq 1f / yes, branch
  3683 0000B0E8 3A05[0FE00000]      <1> 	cmp	al, [i.uid]
  3684                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
  3685                              <1> 				 ; / the file
  3686                              <1> 	;jne	error
  3687                              <1> 		; beq 1f / yes
  3688                              <1> 		; jmp error3 / no, error
  3689 0000B0EE 740F                <1> 	je	short isown1
  3690                              <1> 
  3691 0000B0F0 C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
  3691 0000B0F8 0000                <1>
  3692                              <1> 			;  'permission denied !' error
  3693 0000B0FA E988EFFFFF          <1> 	jmp	error
  3694                              <1> isown1: ; 1:
  3695 0000B0FF E8E30C0000          <1> 	call	setimod
  3696                              <1> 		; jsr r0,setimod / indicates 
  3697                              <1> 		;	       ; / i-node has been modified
  3698 0000B104 58                  <1> 	pop	eax ; 2nd argument
  3699                              <1> 		; mov (sp)+,r2 / mode is put in r2 
  3700                              <1> 		       ; / (u.off put on stack with 2nd arg)
  3701 0000B105 C3                  <1> 	retn
  3702                              <1> 		; rts r0
  3703                              <1> 
  3704                              <1> ;;arg:  ; < get system call arguments >
  3705                              <1> 	; 'arg' extracts an argument for a routine whose call is 
  3706                              <1> 	; of form:
  3707                              <1> 	;	sys 'routine' ; arg1
  3708                              <1> 	;		or
  3709                              <1> 	;	sys 'routine' ; arg1 ; arg2
  3710                              <1> 	;		or
  3711                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
  3712                              <1> 	;	
  3713                              <1> 	; INPUTS ->
  3714                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
  3715                              <1> 	;	This pointers's value is actually the value of
  3716                              <1> 	;	update pc at the the trap to sysent (unkni) is
  3717                              <1> 	;	made to process the sys instruction
  3718                              <1> 	;    r0 - contains the return address for the routine
  3719                              <1> 	;	that called arg. The data in the word pointer 
  3720                              <1> 	;	to by the return address is used as address
  3721                              <1> 	;	in which the extracted argument is stored   		
  3722                              <1> 	;    	
  3723                              <1> 	; OUTPUTS ->
  3724                              <1> 	;    'address' - contains the extracted argument 
  3725                              <1> 	;    u.sp+18 - is incremented by 2 
  3726                              <1> 	;    r1 - contains the extracted argument
  3727                              <1> 	;    r0 - points to the next instruction to be
  3728                              <1> 	;	 executed in the calling routine.
  3729                              <1> 	;
  3730                              <1>   
  3731                              <1> 	; mov u.sp,r1
  3732                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
  3733                              <1> 			; / into argument of arg2
  3734                              <1> 	; add $2,18.(r1) / point pc on stack 
  3735                              <1> 			      ; / to next system argument
  3736                              <1> 	; rts r0
  3737                              <1> 
  3738                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
  3739                              <1> 	; 'arg2' takes first argument in system call
  3740                              <1> 	;  (pointer to name of the file) and puts it in location
  3741                              <1> 	;  u.namep; takes second argument and puts it in u.off
  3742                              <1> 	;  and on top of the stack
  3743                              <1> 	;	
  3744                              <1> 	; INPUTS ->
  3745                              <1> 	;    u.sp, r0
  3746                              <1> 	;    	
  3747                              <1> 	; OUTPUTS ->
  3748                              <1> 	;    u.namep
  3749                              <1> 	;    u.off 
  3750                              <1> 	;    u.off pushed on stack
  3751                              <1> 	;    r1
  3752                              <1> 	;
  3753                              <1> 
  3754                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
  3755                              <1> 				; / first arg in sys call
  3756                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
  3757                              <1> 				; / second arg in sys call
  3758                              <1> 	; mov r0,r1 / r0 points to calling routine
  3759                              <1> 	; mov (sp),r0 / put operation code back in r0
  3760                              <1> 	; mov u.off,(sp) / put pointer to second argument 
  3761                              <1> 			; / on stack
  3762                              <1> 	; jmp (r1) / return to calling routine
  3763                              <1> 
  3764                              <1> syschown: ; < change owner of file >
  3765                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3766                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3767                              <1> 	;
  3768                              <1> 	; 'syschown' changes the owner of the file whose name is given
  3769                              <1> 	; as null terminated string pointed to by 'name' has it's owner
  3770                              <1> 	; changed to 'owner'
  3771                              <1> 	;
  3772                              <1> 	; Calling sequence:
  3773                              <1> 	;	syschown; name; owner
  3774                              <1> 	; Arguments:
  3775                              <1> 	;	name - address of the file name
  3776                              <1> 	;	       terminated by null byte.
  3777                              <1> 	;	owner - (new) owner (number/ID)
  3778                              <1> 	;	
  3779                              <1> 	; Inputs: -
  3780                              <1> 	; Outputs: -
  3781                              <1> 	; ...............................................................
  3782                              <1> 	;				
  3783                              <1> 	; Retro UNIX 8086 v1 modification: 
  3784                              <1> 	;       'syschown' system call has two arguments; so,
  3785                              <1> 	;	* 1st argument, name is pointed to by BX register
  3786                              <1> 	;	* 2nd argument, owner number is in CX register
  3787                              <1> 	;
  3788                              <1> 	; / name; owner
  3789 0000B106 E8B2FFFFFF          <1> 	call	isown
  3790                              <1> 		; jsr r0,isown / get the i-node and check user status
  3791 0000B10B 803D[94E30000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
  3792                              <1> 		; tstb u.uid / super user
  3793 0000B112 7418                <1> 	jz	short syschown1
  3794                              <1> 		; beq 2f / yes, 2f
  3795 0000B114 F605[0CE00000]20    <1>         test    byte [i.flgs], 20h ; 32
  3796                              <1> 		; bit $40,i.flgs / no, set userid on execution?
  3797                              <1> 	;jnz	error
  3798                              <1> 		; bne 3f / yes error, could create Trojan Horses
  3799 0000B11B 740F                <1> 	jz	short syschown1
  3800                              <1> 	; 'permission denied !'
  3801 0000B11D C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  3801 0000B125 0000                <1>
  3802 0000B127 E95BEFFFFF          <1> 	jmp	error
  3803                              <1> syschown1: ; 2:
  3804                              <1> 	; AL = owner (number/ID)
  3805 0000B12C A2[0FE00000]        <1> 	mov	[i.uid], al ; 23/06/2015
  3806                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
  3807                              <1> 			       ; / in the i-node
  3808 0000B131 E971EFFFFF          <1> 	jmp	sysret
  3809                              <1> 	; 1: 
  3810                              <1> 		; jmp sysret4
  3811                              <1> 	; 3:
  3812                              <1> 		; jmp	error
  3813                              <1> 
  3814                              <1> systime: ; / get time of year
  3815                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3816                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  3817                              <1> 	;
  3818                              <1> 	; 20/06/2013
  3819                              <1> 	; 'systime' gets the time of the year.
  3820                              <1> 	; The present time is put on the stack.
  3821                              <1> 	;
  3822                              <1> 	; Calling sequence:
  3823                              <1> 	;	systime
  3824                              <1> 	; Arguments: -
  3825                              <1> 	;	
  3826                              <1> 	; Inputs: -
  3827                              <1> 	; Outputs: sp+2, sp+4 - present time
  3828                              <1> 	; ...............................................................
  3829                              <1> 	;	
  3830                              <1> 	; Retro UNIX 8086 v1 modification: 
  3831                              <1> 	;       'systime' system call will return to the user
  3832                              <1> 	;	with unix time (epoch) in DX:AX register pair
  3833                              <1> 	;
  3834                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
  3835                              <1> 	;	system call for PC compatibility !!		 	
  3836                              <1> 
  3837 0000B136 E8B20C0000          <1> 	call 	epoch
  3838 0000B13B A3[48E30000]        <1> 	mov 	[u.r0], eax
  3839                              <1> 		; mov s.time,4(sp)
  3840                              <1> 		; mov s.time+2,2(sp) / put the present time 
  3841                              <1> 				   ; / on the stack
  3842                              <1> 		; br sysret4
  3843 0000B140 E962EFFFFF          <1> 	jmp	sysret 
  3844                              <1> 
  3845                              <1> sysstime: ; / set time
  3846                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3847                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3848                              <1> 	;
  3849                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
  3850                              <1> 	;
  3851                              <1> 	; Calling sequence:
  3852                              <1> 	;	sysstime
  3853                              <1> 	; Arguments: -
  3854                              <1> 	;	
  3855                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
  3856                              <1> 	; Outputs: -
  3857                              <1> 	; ...............................................................
  3858                              <1> 	;	
  3859                              <1> 	; Retro UNIX 8086 v1 modification: 
  3860                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
  3861                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
  3862                              <1> 	; 
  3863                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  3864                              <1> 	;	to get sysstime system call arguments from the user;
  3865                              <1> 	;	* 1st argument, lowword of unix time is in BX register
  3866                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
  3867                              <1> 	;
  3868                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
  3869                              <1> 	;	system call for PC compatibility !!	
  3870                              <1> 
  3871 0000B145 803D[94E30000]00    <1> 	cmp	byte [u.uid], 0
  3872                              <1> 		; tstb u.uid / is user the super user
  3873                              <1> 	;ja	error
  3874                              <1> 		; bne error4 / no, error
  3875 0000B14C 760F                <1> 	jna	short systime1
  3876                              <1> 	; 'permission denied !'
  3877 0000B14E C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  3877 0000B156 0000                <1>
  3878 0000B158 E92AEFFFFF          <1> 	jmp	error
  3879                              <1> systime1:
  3880                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
  3881                              <1> 	; EBX = unix (epoch) time (from user)
  3882 0000B15D 89D8                <1> 	mov	eax, ebx
  3883 0000B15F E88A0C0000          <1> 	call 	set_date_time
  3884                              <1> 		; mov 4(sp),s.time
  3885                              <1> 		; mov 2(sp),s.time+2 / set the system time
  3886 0000B164 E93EEFFFFF          <1> 	jmp	sysret
  3887                              <1> 		; br sysret4
  3888                              <1> 
  3889                              <1> sysbreak:
  3890                              <1> 	; 18/10/2015
  3891                              <1> 	; 07/10/2015
  3892                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3893                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  3894                              <1> 	;
  3895                              <1> 	; 'sysbreak' sets the programs break points. 
  3896                              <1> 	; It checks the current break point (u.break) to see if it is
  3897                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  3898                              <1> 	; even address (if it was odd) and the area between u.break
  3899                              <1> 	; and the stack is cleared. The new breakpoint is then put
  3900                              <1> 	; in u.break and control is passed to 'sysret'.
  3901                              <1> 	;
  3902                              <1> 	; Calling sequence:
  3903                              <1> 	;	sysbreak; addr
  3904                              <1> 	; Arguments: -
  3905                              <1> 	;	
  3906                              <1> 	; Inputs: u.break - current breakpoint
  3907                              <1> 	; Outputs: u.break - new breakpoint 
  3908                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  3909                              <1> 	; ...............................................................
  3910                              <1> 	;	
  3911                              <1> 	; Retro UNIX 8086 v1 modification:
  3912                              <1> 	;	The user/application program puts breakpoint address
  3913                              <1> 	;       in BX register as 'sysbreak' system call argument.
  3914                              <1> 	; 	(argument transfer method 1)
  3915                              <1> 	;
  3916                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  3917                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  3918                              <1> 	;  NOTE:
  3919                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  3920                              <1> 	;	'u.break' address) of user's memory for original unix's
  3921                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  3922                              <1> 
  3923                              <1> 		; mov u.break,r1 / move users break point to r1
  3924                              <1> 		; cmp r1,$core / is it the same or lower than core?
  3925                              <1> 		; blos 1f / yes, 1f
  3926                              <1> 	; 23/06/2015
  3927 0000B169 8B2D[74E30000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  3928                              <1> 	;and	ebp, ebp
  3929                              <1> 	;jz	short sysbreak_3 
  3930                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  3931                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  3932 0000B16F 8B15[40E30000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  3933 0000B175 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  3934                              <1> 	; 07/10/2015
  3935 0000B178 891D[74E30000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  3936                              <1> 	;
  3937 0000B17E 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  3938                              <1> 			   ; with top of user's stack (virtual!)
  3939 0000B180 7327                <1> 	jnb	short sysbreak_3
  3940                              <1> 		; cmp r1,sp / is it the same or higher 
  3941                              <1> 			  ; / than the stack?
  3942                              <1> 		; bhis 1f / yes, 1f
  3943 0000B182 89DE                <1> 	mov	esi, ebx
  3944 0000B184 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  3945 0000B186 7621                <1> 	jna	short sysbreak_3 
  3946                              <1> 	;push	ebx
  3947                              <1> sysbreak_1:
  3948 0000B188 89EB                <1> 	mov	ebx, ebp  
  3949 0000B18A E89D86FFFF          <1> 	call	get_physical_addr ; get physical address
  3950 0000B18F 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
  3951                              <1> 	; 18/10/2015
  3952 0000B195 89C7                <1> 	mov	edi, eax 
  3953 0000B197 29C0                <1> 	sub	eax, eax ; 0
  3954                              <1> 		 ; ECX = remain byte count in page (1-4096)
  3955 0000B199 39CE                <1> 	cmp	esi, ecx
  3956 0000B19B 7302                <1> 	jnb	short sysbreak_2
  3957 0000B19D 89F1                <1> 	mov	ecx, esi
  3958                              <1> sysbreak_2:
  3959 0000B19F 29CE                <1> 	sub	esi, ecx
  3960 0000B1A1 01CD                <1> 	add	ebp, ecx
  3961 0000B1A3 F3AA                <1> 	rep 	stosb
  3962 0000B1A5 09F6                <1> 	or	esi, esi
  3963 0000B1A7 75DF                <1> 	jnz	short sysbreak_1
  3964                              <1> 	;
  3965                              <1> 		; bit $1,r1 / is it an odd address
  3966                              <1> 		; beq 2f / no, its even
  3967                              <1> 		; clrb (r1)+ / yes, make it even
  3968                              <1> 	; 2: / clear area between the break point and the stack
  3969                              <1> 		; cmp r1,sp / is it higher or same than the stack
  3970                              <1> 		; bhis 1f / yes, quit
  3971                              <1> 		; clr (r1)+ / clear word
  3972                              <1> 		; br 2b / go back
  3973                              <1> 	;pop	ebx
  3974                              <1> sysbreak_3: ; 1:
  3975                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  3976                              <1> 		; jsr r0,arg; u.break / put the "address" 
  3977                              <1> 			; / in u.break (set new break point)
  3978                              <1> 		; br sysret4 / br sysret
  3979 0000B1A9 E9F9EEFFFF          <1> 	jmp	sysret
  3980                              <1> 
  3981                              <1> 
  3982                              <1> maknod: 
  3983                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3984                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3985                              <1> 	;
  3986                              <1> 	; 'maknod' creates an i-node and makes a directory entry
  3987                              <1> 	; for this i-node in the current directory.
  3988                              <1> 	;
  3989                              <1> 	; INPUTS ->
  3990                              <1> 	;    r1 - contains mode
  3991                              <1> 	;    ii - current directory's i-number	
  3992                              <1> 	;    	
  3993                              <1> 	; OUTPUTS ->
  3994                              <1> 	;    u.dirbuf - contains i-number of free i-node 
  3995                              <1> 	;    i.flgs - flags in new i-node 
  3996                              <1> 	;    i.uid - filled with u.uid
  3997                              <1> 	;    i.nlks - 1 is put in the number of links
  3998                              <1> 	;    i.ctim - creation time				
  3999                              <1> 	;    i.ctim+2 - modification time
  4000                              <1> 	;    imod - set via call to setimod
  4001                              <1> 	;	
  4002                              <1> 	; ((AX = R1)) input
  4003                              <1> 	;
  4004                              <1> 	; (Retro UNIX Prototype : 
  4005                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
  4006                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  4007                              <1> 
  4008                              <1> 	; / r1 contains the mode
  4009 0000B1AE 80CC80              <1> 	or 	ah, 80h  ; 10000000b
  4010                              <1> 		; bis	$100000,r1 / allocate flag set
  4011 0000B1B1 6650                <1> 	push	ax
  4012                              <1> 		; mov r1,-(sp) / put mode on stack
  4013                              <1> 	; 31/07/2013
  4014 0000B1B3 66A1[CDE30000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
  4015                              <1> 		; mov ii,r1 / move current i-number to r1
  4016 0000B1B9 B201                <1> 	mov	dl, 1 ; owner flag mask
  4017 0000B1BB E82B0C0000          <1> 	call	access	
  4018                              <1> 		; jsr r0,access; 1 / get its i-node into core
  4019 0000B1C0 6650                <1> 	push	ax
  4020                              <1> 		; mov r1,-(sp) / put i-number on stack
  4021 0000B1C2 66B82800            <1> 	mov	ax, 40
  4022                              <1> 		; mov $40.,r1 / r1 = 40
  4023                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
  4024 0000B1C6 6640                <1> 	inc	ax
  4025                              <1> 		; inc r1 / r1 = r1 + 1
  4026 0000B1C8 E8220C0000          <1> 	call	imap
  4027                              <1> 		; jsr r0,imap / get byte address and bit position in 
  4028                              <1> 			    ; /	inode map in r2 & m
  4029                              <1>           ; DX (MQ) has a 1 in the calculated bit position
  4030                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
  4031                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
  4032                              <1> 	;	       Inode count must be checked here
  4033                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
  4034 0000B1CD 8413                <1> 	test	[ebx], dl
  4035                              <1> 		; bitb mq,(r2) / is the i-node active
  4036 0000B1CF 75F5                <1> 	jnz	short maknod1
  4037                              <1> 		; bne 1b / yes, try the next one
  4038 0000B1D1 0813                <1> 	or	[ebx], dl
  4039                              <1> 		; bisb mq,(r2) / no, make it active 
  4040                              <1> 			     ; / (put a 1 in the bit map)
  4041 0000B1D3 E8080C0000          <1> 	call	iget
  4042                              <1> 		; jsr r0,iget / get i-node into core
  4043 0000B1D8 66F705[0CE00000]00- <1> 	test	word [i.flgs], 8000h 
  4043 0000B1E0 80                  <1>
  4044                              <1> 		; tst i.flgs / is i-node already allocated
  4045 0000B1E1 75E3                <1> 	jnz	short maknod1	
  4046                              <1> 		; blt 1b / yes, look for another one
  4047 0000B1E3 66A3[7AE30000]      <1> 	mov	[u.dirbuf], ax
  4048                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  4049 0000B1E9 6658                <1> 	pop	ax
  4050                              <1> 		; mov (sp)+,r1 / get current i-number back
  4051 0000B1EB E8F00B0000          <1> 	call	iget
  4052                              <1> 		; jsr r0,iget / get i-node in core
  4053 0000B1F0 E88AF9FFFF          <1> 	call	mkdir
  4054                              <1> 		; jsr r0,mkdir / make a directory entry 
  4055                              <1> 			     ; / in current directory
  4056 0000B1F5 66A1[7AE30000]      <1> 	mov	ax, [u.dirbuf]
  4057                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  4058 0000B1FB E8E00B0000          <1> 	call	iget
  4059                              <1> 		; jsr r0,iget / get it into core
  4060                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
  4061 0000B200 B908000000          <1> 	mov	ecx, 8 
  4062 0000B205 31C0                <1> 	xor	eax, eax ; 0
  4063 0000B207 BF[0CE00000]        <1> 	mov	edi, inode 
  4064 0000B20C F3AB                <1> 	rep	stosd
  4065                              <1> 	;
  4066 0000B20E 668F05[0CE00000]    <1> 	pop	word [i.flgs]
  4067                              <1> 		; mov (sp)+,i.flgs / fill flags
  4068 0000B215 8A0D[94E30000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
  4069 0000B21B 880D[0FE00000]      <1> 	mov 	[i.uid], cl
  4070                              <1> 		; movb u.uid,i.uid / user id	
  4071 0000B221 C605[0EE00000]01    <1> 	mov     byte [i.nlks], 1
  4072                              <1> 		; movb $1,i.nlks / 1 link
  4073                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
  4074                              <1> 	;mov	eax, [s.time]
  4075                              <1> 	;mov 	[i.ctim], eax
  4076                              <1> 	 	; mov s.time,i.ctim / time created
  4077                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
  4078                              <1> 	; Retro UNIX 8086 v1 modification !
  4079                              <1> 	; i.ctime=0, i.ctime+2=0 and
  4080                              <1>         ; 'setimod' will set ctime of file via 'epoch'
  4081 0000B228 E8BA0B0000          <1> 	call setimod
  4082                              <1> 		; jsr r0,setimod / set modified flag
  4083 0000B22D C3                  <1> 	retn
  4084                              <1> 		; rts r0 / return
  4085                              <1> 
  4086                              <1> sysseek: ; / moves read write pointer in an fsp entry
  4087                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4088                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4089                              <1> 	;
  4090                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  4091                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  4092                              <1> 	; The file descriptor refers to a file open for reading or
  4093                              <1> 	; writing. The read (or write) pointer is set as follows:
  4094                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  4095                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  4096                              <1> 	;	  current location plus offset.
  4097                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  4098                              <1> 	;	  size of file plus offset.
  4099                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  4100                              <1> 	;
  4101                              <1> 	; Calling sequence:
  4102                              <1> 	;	sysseek; offset; ptrname
  4103                              <1> 	; Arguments:
  4104                              <1> 	;	offset - number of bytes desired to move 
  4105                              <1> 	;		 the r/w pointer
  4106                              <1> 	;	ptrname - a switch indicated above
  4107                              <1> 	;
  4108                              <1> 	; Inputs: r0 - file descriptor 
  4109                              <1> 	; Outputs: -
  4110                              <1> 	; ...............................................................
  4111                              <1> 	;	
  4112                              <1> 	; Retro UNIX 8086 v1 modification: 
  4113                              <1> 	;       'sysseek' system call has three arguments; so,
  4114                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  4115                              <1> 	;	* 2nd argument, offset is in CX register
  4116                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  4117                              <1> 	;	
  4118                              <1> 
  4119 0000B22E E823000000          <1> 	call	seektell
  4120                              <1> 	; AX = u.count
  4121                              <1> 	; BX = *u.fofp
  4122                              <1> 		; jsr r0,seektell / get proper value in u.count
  4123                              <1> 		; add u.base,u.count / add u.base to it
  4124 0000B233 0305[68E30000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  4125 0000B239 8903                <1> 	mov	[ebx], eax
  4126                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  4127 0000B23B E967EEFFFF          <1> 	jmp	sysret
  4128                              <1> 		; br sysret4
  4129                              <1> 
  4130                              <1> systell: ; / get the r/w pointer
  4131                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4132                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4133                              <1> 	;
  4134                              <1> 	; Retro UNIX 8086 v1 modification:
  4135                              <1> 	; ! 'systell' does not work in original UNIX v1,
  4136                              <1> 	; 	    it returns with error !
  4137                              <1> 	; Inputs: r0 - file descriptor 
  4138                              <1> 	; Outputs: r0 - file r/w pointer
  4139                              <1> 
  4140                              <1> 	;xor	ecx, ecx ; 0
  4141 0000B240 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  4142                              <1> 	;call 	seektell
  4143 0000B245 E812000000          <1> 	call 	seektell0 ; 05/08/2013
  4144                              <1> 	;mov	ebx, [u.fofp]
  4145 0000B24A 8B03                <1> 	mov	eax, [ebx]
  4146 0000B24C A3[48E30000]        <1> 	mov	[u.r0], eax
  4147 0000B251 E951EEFFFF          <1> 	jmp	sysret
  4148                              <1> 
  4149                              <1> ; Original unix v1 'systell' system call:
  4150                              <1> 		; jsr r0,seektell
  4151                              <1> 		; br error4
  4152                              <1> 
  4153                              <1> seektell:
  4154                              <1> 	; 03/01/2016
  4155                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4156                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4157                              <1> 	;
  4158                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  4159                              <1> 	; call in u.base and u.count. It then gets the i-number of
  4160                              <1> 	; the file from the file descriptor in u.r0 and by calling
  4161                              <1> 	; getf. The i-node is brought into core and then u.count
  4162                              <1> 	; is checked to see it is a 0, 1, or 2.
  4163                              <1> 	; If it is 0 - u.count stays the same
  4164                              <1> 	;          1 - u.count = offset (u.fofp)
  4165                              <1> 	;	   2 - u.count = i.size (size of file)
  4166                              <1> 	; 	 		
  4167                              <1> 	; !! Retro UNIX 8086 v1 modification:
  4168                              <1> 	;	Argument 1, file descriptor is in BX;
  4169                              <1> 	;	Argument 2, offset is in CX;
  4170                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  4171                              <1> 	;
  4172                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
  4173                              <1> 	; call 	arg
  4174                              <1> 	;
  4175                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
  4176                              <1> 	;
  4177 0000B256 890D[68E30000]      <1> 	mov 	[u.base], ecx ; offset
  4178                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  4179                              <1> seektell0:
  4180 0000B25C 8915[6CE30000]      <1> 	mov 	[u.count], edx
  4181                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
  4182                              <1> 	; mov	ax, bx
  4183                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
  4184                              <1> 			     ; / (index in u.fp list)
  4185                              <1> 	; call	getf
  4186                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
  4187                              <1> 	; BX = file descriptor (file number)
  4188 0000B262 E83DFCFFFF          <1> 	call	getf1
  4189 0000B267 6609C0              <1> 	or	ax, ax ; i-number of the file
  4190                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
  4191                              <1> 		             ; / put it on the stack
  4192                              <1> 	;jz	error
  4193                              <1> 		; beq error4 / if i-number is 0, not active so error
  4194 0000B26A 750F                <1> 	jnz	short seektell1
  4195 0000B26C C705[9DE30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  4195 0000B274 0000                <1>
  4196 0000B276 E90CEEFFFF          <1> 	jmp	error
  4197                              <1> seektell1:
  4198                              <1> 	;push	eax
  4199 0000B27B 80FC80              <1> 	cmp	ah, 80h
  4200 0000B27E 7203                <1> 	jb	short seektell2
  4201                              <1> 		; bgt .+4 / if its positive jump
  4202 0000B280 66F7D8              <1> 	neg	ax
  4203                              <1> 		; neg r1 / if not make it positive
  4204                              <1> seektell2:
  4205 0000B283 E8580B0000          <1> 	call	iget
  4206                              <1> 		; jsr r0,iget / get its i-node into core
  4207 0000B288 8B1D[58E30000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  4208 0000B28E 803D[6CE30000]01    <1> 	cmp	byte [u.count], 1
  4209                              <1> 		; cmp u.count,$1 / is ptr name =1
  4210 0000B295 7705                <1> 	ja	short seektell3
  4211                              <1> 		; blt 2f / no its zero
  4212 0000B297 740A                <1> 	je	short seektell_4
  4213                              <1> 		; beq 1f / yes its 1
  4214 0000B299 31C0                <1> 	xor	eax, eax
  4215                              <1> 	;jmp	short seektell_5
  4216 0000B29B C3                  <1> 	retn
  4217                              <1> seektell3:
  4218                              <1> 	; 03/01/2016
  4219                              <1> 	;movzx	eax, word [i.size]
  4220 0000B29C 66A1[D1E30000]      <1>         mov   	ax, [i.size]
  4221                              <1>                 ; mov i.size,u.count /  put number of bytes 
  4222                              <1>                                    ; / in file in u.count
  4223                              <1> 	;jmp	short seektell_5
  4224                              <1> 		; br 2f
  4225 0000B2A2 C3                  <1> 	retn
  4226                              <1> seektell_4: ; 1: / ptrname =1
  4227                              <1> 	;mov	ebx, [u.fofp]
  4228 0000B2A3 8B03                <1> 	mov	eax, [ebx]
  4229                              <1> 		; mov *u.fofp,u.count / put offset in u.count
  4230                              <1> ;seektell_5: ; 2: / ptrname =0
  4231                              <1> 	;mov	[u.count], eax
  4232                              <1> 	;pop	eax 
  4233                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
  4234 0000B2A5 C3                  <1> 	retn
  4235                              <1> 		; rts r0
  4236                              <1> 
  4237                              <1> sysintr: ; / set interrupt handling
  4238                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4239                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4240                              <1> 	;
  4241                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  4242                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  4243                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  4244                              <1> 	; If one does the interrupt character in the tty buffer is
  4245                              <1> 	; cleared and 'sysret'is called. If one does not exits
  4246                              <1> 	; 'sysret' is just called.	
  4247                              <1> 	;
  4248                              <1> 	; Calling sequence:
  4249                              <1> 	;	sysintr; arg
  4250                              <1> 	; Argument:
  4251                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  4252                              <1> 	;	    - if 1, intterupts cause their normal result
  4253                              <1> 	;		 i.e force an exit.
  4254                              <1> 	;	    - if arg is a location within the program,
  4255                              <1> 	;		control is passed to that location when
  4256                              <1> 	;		an interrupt occurs.	
  4257                              <1> 	; Inputs: -
  4258                              <1> 	; Outputs: -
  4259                              <1> 	; ...............................................................
  4260                              <1> 	;	
  4261                              <1> 	; Retro UNIX 8086 v1 modification: 
  4262                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  4263                              <1> 	;	then branches into sysquit.
  4264                              <1> 	;
  4265 0000B2A6 66891D[8CE30000]    <1> 	mov	[u.intr], bx
  4266                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  4267                              <1> 		; br 1f / go into quit routine
  4268 0000B2AD E9F5EDFFFF          <1> 	jmp	sysret
  4269                              <1> 
  4270                              <1> sysquit:
  4271                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4272                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4273                              <1> 	;
  4274                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  4275                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  4276                              <1> 	; tty exists. If one does the interrupt character in the tty
  4277                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  4278                              <1> 	; 'sysret' is just called.	
  4279                              <1> 	;
  4280                              <1> 	; Calling sequence:
  4281                              <1> 	;	sysquit; arg
  4282                              <1> 	; Argument:
  4283                              <1> 	;	arg - if 0, this call diables quit signals from the
  4284                              <1> 	;		typewriter (ASCII FS)
  4285                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  4286                              <1> 	;		cease and a core image to be produced.
  4287                              <1> 	;		 i.e force an exit.
  4288                              <1> 	;	    - if arg is an addres in the program,
  4289                              <1> 	;		a quit causes control to sent to that
  4290                              <1> 	;		location.	
  4291                              <1> 	; Inputs: -
  4292                              <1> 	; Outputs: -
  4293                              <1> 	; ...............................................................
  4294                              <1> 	;	
  4295                              <1> 	; Retro UNIX 8086 v1 modification: 
  4296                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  4297                              <1> 	;	then branches into 'sysret'.
  4298                              <1> 	;
  4299 0000B2B2 66891D[8EE30000]    <1> 	mov	[u.quit], bx
  4300 0000B2B9 E9E9EDFFFF          <1> 	jmp	sysret
  4301                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  4302                              <1> 	;1:
  4303                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  4304                              <1> 			      ; / to r1
  4305                              <1> 		; beq sysret4 / return to user
  4306                              <1> 		; clrb 6(r1) / clear the interrupt character 
  4307                              <1> 			   ; / in the tty buffer
  4308                              <1> 		; br sysret4 / return to user
  4309                              <1> 
  4310                              <1> syssetuid: ; / set process id
  4311                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4312                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4313                              <1> 	;
  4314                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
  4315                              <1> 	; to the process id in (u.r0). Both the effective user and 
  4316                              <1> 	; u.uid and the real user u.ruid are set to this. 
  4317                              <1> 	; Only the super user can make this call.	
  4318                              <1> 	;
  4319                              <1> 	; Calling sequence:
  4320                              <1> 	;	syssetuid
  4321                              <1> 	; Arguments: -
  4322                              <1> 	;
  4323                              <1> 	; Inputs: (u.r0) - contains the process id.
  4324                              <1> 	; Outputs: -
  4325                              <1> 	; ...............................................................
  4326                              <1> 	;	
  4327                              <1> 	; Retro UNIX 8086 v1 modification: 
  4328                              <1> 	;       BL contains the (new) user ID of the current process
  4329                              <1> 
  4330                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
  4331 0000B2BE 3A1D[95E30000]      <1> 	cmp	bl, [u.ruid] 
  4332                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
  4333                              <1> 			       ; / id number
  4334 0000B2C4 741E                <1> 	je	short setuid1
  4335                              <1> 		; beq 1f / yes
  4336 0000B2C6 803D[94E30000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  4337                              <1> 		; tstb u.uid / no, is current user the super user?
  4338                              <1> 	;ja	error
  4339                              <1> 		; bne error4 / no, error
  4340 0000B2CD 760F                <1> 	jna	short setuid0
  4341 0000B2CF C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  4341 0000B2D7 0000                <1>
  4342                              <1> 				;  'permission denied !' error
  4343 0000B2D9 E9A9EDFFFF          <1> 	jmp	error
  4344                              <1> setuid0:
  4345 0000B2DE 881D[95E30000]      <1> 	mov	[u.ruid], bl
  4346                              <1> setuid1: ; 1:
  4347 0000B2E4 881D[94E30000]      <1> 	mov	[u.uid], bl ; 02/08/2013
  4348                              <1> 		; movb r1,u.uid / put process id in u.uid
  4349                              <1> 		; movb r1,u.ruid / put process id in u.ruid
  4350 0000B2EA E9B8EDFFFF          <1> 	jmp	sysret
  4351                              <1> 		; br sysret4 / system return
  4352                              <1> 
  4353                              <1> sysgetuid: ; < get user id >
  4354                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4355                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4356                              <1> 	;
  4357                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
  4358                              <1> 	; The real user ID identifies the person who is logged in,
  4359                              <1> 	; in contradistinction to the effective user ID, which
  4360                              <1> 	; determines his access permission at each moment. It is thus
  4361                              <1> 	; useful to programs which operate using the 'set user ID'
  4362                              <1> 	; mode, to find out who invoked them.	
  4363                              <1> 	;
  4364                              <1> 	; Calling sequence:
  4365                              <1> 	;	syssetuid
  4366                              <1> 	; Arguments: -
  4367                              <1> 	;
  4368                              <1> 	; Inputs: -
  4369                              <1> 	; Outputs: (u.r0) - contains the real user's id.
  4370                              <1> 	; ...............................................................
  4371                              <1> 	;	
  4372                              <1> 	; Retro UNIX 8086 v1 modification: 
  4373                              <1> 	;       AL contains the real user ID at return.
  4374                              <1> 	;
  4375 0000B2EF 0FB605[95E30000]    <1> 	movzx 	eax, byte [u.ruid]
  4376 0000B2F6 A3[48E30000]        <1> 	mov	[u.r0], eax
  4377                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  4378 0000B2FB E9A7EDFFFF          <1> 	jmp	sysret
  4379                              <1> 		; br sysret4 / systerm return, sysret
  4380                              <1> 
  4381                              <1> anyi: 
  4382                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4383                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  4384                              <1> 	;
  4385                              <1> 	; 'anyi' is called if a file deleted while open.
  4386                              <1> 	; "anyi" checks to see if someone else has opened this file.
  4387                              <1> 	;
  4388                              <1> 	; INPUTS ->
  4389                              <1> 	;    r1 - contains an i-number
  4390                              <1> 	;    fsp - start of table containing open files
  4391                              <1> 	;
  4392                              <1> 	; OUTPUTS ->
  4393                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  4394                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  4395                              <1> 	;    if file not found - bit in i-node map is cleared
  4396                              <1> 	;    			 (i-node is freed)
  4397                              <1> 	;               all blocks related to i-node are freed
  4398                              <1> 	;	        all flags in i-node are cleared
  4399                              <1> 	; ((AX = R1)) input
  4400                              <1> 	;
  4401                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  4402                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  4403                              <1> 	;
  4404                              <1> 		; / r1 contains an i-number
  4405 0000B300 BB[1CE10000]        <1> 	mov	ebx, fsp
  4406                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  4407                              <1> anyi_1: ; 1:
  4408 0000B305 663B03              <1> 	cmp	ax, [ebx]
  4409                              <1> 		; cmp r1,(r2) / do i-numbers match?
  4410 0000B308 7433                <1> 	je	short anyi_3
  4411                              <1> 		; beq 1f / yes, 1f
  4412 0000B30A 66F7D8              <1> 	neg	ax
  4413                              <1> 		; neg r1 / no complement r1
  4414 0000B30D 663B03              <1> 	cmp	ax, [ebx]
  4415                              <1> 		; cmp r1,(r2) / do they match now?
  4416 0000B310 742B                <1> 	je	short anyi_3
  4417                              <1> 		; beq 1f / yes, transfer
  4418                              <1> 		; / i-numbers do not match
  4419 0000B312 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
  4420                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
  4421                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
  4422 0000B315 81FB[10E30000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
  4423                              <1> 		; cmp r2,$fsp+[nfiles*8] 
  4424                              <1> 				; / are we at last entry in the table
  4425 0000B31B 72E8                <1> 	jb	short anyi_1
  4426                              <1> 		; blt 1b / no, check next entries i-number
  4427                              <1> 	;cmp	ax, 32768
  4428 0000B31D 80FC80              <1> 	cmp	ah, 80h ; negative number check
  4429                              <1> 		; tst r1 / yes, no match
  4430                              <1> 		; bge .+4
  4431 0000B320 7203                <1> 	jb	short anyi_2
  4432 0000B322 66F7D8              <1> 	neg	ax
  4433                              <1> 		; neg r1 / make i-number positive
  4434                              <1> anyi_2:	
  4435 0000B325 E8C50A0000          <1> 	call	imap
  4436                              <1> 		; jsr r0,imap / get address of allocation bit 
  4437                              <1> 			    ; / in the i-map in r2
  4438                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
  4439                              <1>         ;; eBX (R2) has address of the byte with allocation bit
  4440                              <1>  	; not	dx
  4441 0000B32A F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
  4442                              <1>         ;and	[ebx], dx
  4443 0000B32C 2013                <1> 	and 	[ebx], dl 
  4444                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  4445 0000B32E E8B30A0000          <1> 	call	itrunc
  4446                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  4447 0000B333 66C705[0CE00000]00- <1>  	mov 	word [i.flgs], 0
  4447 0000B33B 00                  <1>
  4448                              <1> 		; clr i.flgs / clear all flags in the i-node
  4449 0000B33C C3                  <1> 	retn
  4450                              <1> 		;rts	r0 / return
  4451                              <1> anyi_3: ; 1: / i-numbers match
  4452 0000B33D FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
  4453                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
  4454                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
  4455 0000B340 C3                  <1> 	retn
  4456                              <1> 		; rts r0
  4457                              <1> 
  4458                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u7.s
  4459                              <1> ; Last Modification: 14/11/2015
  4460                              <1> 
  4461                              <1> sysmount: ; / mount file system; args special; name
  4462                              <1> 	; 14/11/2015
  4463                              <1> 	; 24/10/2015
  4464                              <1> 	; 13/10/2015
  4465                              <1> 	; 10/07/2015
  4466                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4467                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4468                              <1> 	;
  4469                              <1> 	; 'sysmount' anounces to the system that a removable 
  4470                              <1> 	; file system has been mounted on a special file.
  4471                              <1> 	; The device number of the special file is obtained via
  4472                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
  4473                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
  4474                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
  4475                              <1> 	; to read file system into core, i.e. the first block on the
  4476                              <1> 	; mountable file system is read in. This block is super block
  4477                              <1> 	; for the file system. This call is super user restricted.	
  4478                              <1> 	;
  4479                              <1> 	; Calling sequence:
  4480                              <1> 	;	sysmount; special; name
  4481                              <1> 	; Arguments:
  4482                              <1> 	;	special - pointer to name of special file (device)
  4483                              <1> 	;	name -  pointer to name of the root directory of the
  4484                              <1> 	;		newly mounted file system. 'name' should 
  4485                              <1> 	;		always be a directory.
  4486                              <1> 	; Inputs: - 
  4487                              <1> 	; Outputs: -
  4488                              <1> 	; ...............................................................
  4489                              <1> 	;				
  4490                              <1> 	; Retro UNIX 8086 v1 modification: 
  4491                              <1> 	;       'sysmount' system call has two arguments; so,
  4492                              <1> 	;	* 1st argument, special is pointed to by BX register
  4493                              <1> 	;	* 2nd argument, name is in CX register
  4494                              <1> 	;
  4495                              <1> 	;	NOTE: Device numbers, names and related procedures are 
  4496                              <1> 	;	       already modified for IBM PC compatibility and 
  4497                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
  4498                              <1> 	
  4499                              <1> 	;call	arg2
  4500                              <1> 		; jsr r0,arg2 / get arguments special and name
  4501 0000B341 891D[60E30000]      <1> 	mov	[u.namep], ebx
  4502 0000B347 51                  <1> 	push	ecx ; directory name
  4503 0000B348 66833D[30E30000]00  <1> 	cmp	word [mnti], 0
  4504                              <1> 		; tst mnti / is the i-number of the cross device file
  4505                              <1> 			 ; / zero?
  4506                              <1> 	;ja	error
  4507                              <1>         	; bne errora / no, error
  4508 0000B350 0F87E9000000        <1> 	ja	sysmnt_err0
  4509                              <1> 	;
  4510 0000B356 E8CC000000          <1> 	call	getspl
  4511                              <1> 		; jsr r0,getspl / get special files device number in r1
  4512                              <1> 	; 13/10/2015
  4513 0000B35B 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
  4514 0000B35E F683[DACD0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
  4515 0000B365 750F                <1> 	jnz	short sysmnt_1
  4516                              <1> sysmnt_err1:
  4517 0000B367 C705[9DE30000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  4517 0000B36F 0000                <1>
  4518 0000B371 E911EDFFFF          <1> 	jmp	error
  4519                              <1> sysmnt_1:
  4520 0000B376 8F05[60E30000]      <1> 	pop	dword [u.namep]
  4521                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
  4522                              <1> 				  ; / on the device
  4523                              <1> 	; 14/11/2015
  4524 0000B37C 53                  <1> 	push	ebx ; 13/10/2015
  4525                              <1> 		; mov r1,-(sp) / save the device number
  4526                              <1>         ;
  4527 0000B37D E859FBFFFF          <1> 	call	namei
  4528                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4529                              <1> 		       ; ax = 0 -> file not found 	
  4530                              <1> 	;jz	error
  4531                              <1> 	;jc	error
  4532                              <1> 		; jsr r0,namei / get the i-number of the file
  4533                              <1>                	; br errora
  4534 0000B382 730F                <1> 	jnc	short sysmnt_2
  4535                              <1> sysmnt_err2:
  4536 0000B384 C705[9DE30000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  4536 0000B38C 0000                <1>
  4537 0000B38E E9F4ECFFFF          <1> 	jmp	error
  4538                              <1> sysmnt_2:	
  4539 0000B393 66A3[30E30000]      <1> 	mov	[mnti], ax
  4540                              <1>         	; mov r1,mnti / put it in mnti
  4541                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
  4542                              <1> sysmnt_3: ;1:
  4543                              <1>         ;cmp	byte [ebx+1], 0
  4544                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
  4545                              <1> 			   ; / dismountable device set?
  4546                              <1>         ;jna	short sysmnt_4		
  4547                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
  4548                              <1> 	;call	idle 	; (wait for hardware interrupt)
  4549                              <1> 	;jmp	short sysmnt_3
  4550                              <1> sysmnt_4:   
  4551 0000B399 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  4552 0000B39A A2[2DE30000]        <1> 	mov	[mdev], al
  4553                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
  4554 0000B39F 8803                <1> 	mov	[ebx], al
  4555                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
  4556                              <1> 			      ; / of the I/O queue entry
  4557                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
  4558                              <1>         	; mov (sp)+,cdev / put device number in cdev
  4559 0000B3A1 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
  4560                              <1> 		; bis $2000,sb1 / set the read bit
  4561                              <1> 	; Retro UNIX 386 v1 modification : 
  4562                              <1> 	;	32 bit block number at buffer header offset 4
  4563 0000B3A6 C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
  4564 0000B3AD E83E0A0000          <1> 	call 	diskio
  4565 0000B3B2 731C                <1> 	jnc	short sysmnt_5
  4566 0000B3B4 31C0                <1> 	xor 	eax, eax
  4567 0000B3B6 66A3[30E30000]      <1> 	mov	[mnti], ax ; 0
  4568 0000B3BC A2[2DE30000]        <1> 	mov	[mdev], al ; 0
  4569                              <1> 	;mov	[cdev], al ; 0
  4570                              <1> sysmnt_invd:
  4571                              <1> 	; 14/11/2015
  4572 0000B3C1 FEC8                <1> 	dec 	al
  4573 0000B3C3 8903                <1> 	mov	[ebx], eax ; 000000FFh
  4574 0000B3C5 FEC0                <1> 	inc	al
  4575 0000B3C7 48                  <1> 	dec	eax
  4576 0000B3C8 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  4577 0000B3CB E9B7ECFFFF          <1> 	jmp	error
  4578                              <1> sysmnt_5:
  4579                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
  4580                              <1> 	; (Following check is needed to prevent mounting an
  4581                              <1> 	; in valid valid file system (in valid super block).
  4582                              <1> 	; 
  4583 0000B3D0 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  4584 0000B3D3 C0E002              <1> 	shl	al, 2 ; 4*index
  4585 0000B3D6 8B88[BECD0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  4586 0000B3DC C1E103              <1> 	shl 	ecx, 3
  4587 0000B3DF 0FB715[01EE0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
  4588 0000B3E6 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
  4589                              <1> 			 ; (in sectors), if they are not equal
  4590                              <1> 			 ; the disk to be mounted is an...	
  4591 0000B3E8 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
  4592                              <1> 			 ; (which has not got a valid super block)
  4593                              <1> 	;
  4594 0000B3EA C6430100            <1> 	mov	byte [ebx+1], 0
  4595                              <1> 	       	; jsr r0,ppoke / read in entire file system
  4596                              <1> ;sysmnt_6: ;1:
  4597                              <1> 	;;cmp	byte [sb1+1], 0
  4598                              <1> 		; tstb   sb1+1 / done reading?
  4599                              <1>    	;;jna	sysret
  4600                              <1> 	;;call	idle ; (wait for hardware interrupt)
  4601                              <1> 	;;jmp	short sysmnt_6
  4602                              <1> 		;bne 1b / no, wait
  4603                              <1>         	;br sysreta / yes
  4604 0000B3EE E9B4ECFFFF          <1> 	jmp	sysret
  4605                              <1> 
  4606                              <1> sysumount: ; / special dismount file system
  4607                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4608                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4609                              <1> 	;
  4610                              <1> 	; 04/11/2013
  4611                              <1> 	; 09/07/2013
  4612                              <1> 	; 'sysumount' anounces to the system that the special file, 
  4613                              <1> 	; indicated as an argument is no longer contain a removable
  4614                              <1> 	; file system. 'getspl' gets the device number of the special
  4615                              <1> 	; file. If no file system was mounted on that device an error
  4616                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
  4617                              <1> 	; to 'sysret'.
  4618                              <1> 	;
  4619                              <1> 	; Calling sequence:
  4620                              <1> 	;	sysmount; special
  4621                              <1> 	; Arguments:
  4622                              <1> 	;	special - special file to dismount (device)
  4623                              <1> 	;
  4624                              <1> 	; Inputs: - 
  4625                              <1> 	; Outputs: -
  4626                              <1> 	; ...............................................................
  4627                              <1> 	;				
  4628                              <1> 	; Retro UNIX 8086 v1 modification: 
  4629                              <1> 	;       'sysumount' system call has one argument; so,
  4630                              <1> 	;	* Single argument, special is pointed to by BX register
  4631                              <1> 	;
  4632                              <1> 	
  4633                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
  4634                              <1> 	;call	arg
  4635                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
  4636 0000B3F3 891D[60E30000]      <1>         mov	[u.namep], ebx
  4637 0000B3F9 E829000000          <1> 	call	getspl
  4638                              <1> 		; jsr r0,getspl / get the device number in r1
  4639 0000B3FE 3A05[2DE30000]      <1> 	cmp	al, [mdev]
  4640                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  4641 0000B404 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  4642                              <1> 	;jne	error
  4643                              <1>         	; bne errora / no error
  4644 0000B406 30C0                <1> 	xor	al, al ; ah = 0
  4645                              <1> sysumnt_0: ;1:
  4646 0000B408 3805[FEED0000]      <1>      	cmp 	[sb1+1], al ; 0
  4647                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
  4648                              <1> 			   ; / (inhibit bit set)?
  4649 0000B40E 7607                <1> 	jna	short sysumnt_1		
  4650                              <1> 		; bne 1b / yes, wait
  4651 0000B410 E8DC090000          <1> 	call	idle ; (wait for hardware interrupt)
  4652 0000B415 EBF1                <1> 	jmp	short sysumnt_0
  4653                              <1> sysumnt_1:        
  4654 0000B417 A2[2DE30000]        <1> 	mov	[mdev], al
  4655                              <1> 	     	; clr mntd / no, clear these
  4656 0000B41C 66A3[30E30000]      <1>    	mov	[mnti], ax
  4657                              <1>         	; clr mnti
  4658 0000B422 E980ECFFFF          <1>         jmp	sysret
  4659                              <1> 		; br sysreta / return
  4660                              <1> 
  4661                              <1> getspl: ; / get device number from a special file name
  4662 0000B427 E8AFFAFFFF          <1> 	call	namei
  4663                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4664                              <1> 		       ; ax = 0 -> file not found 	
  4665 0000B42C 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
  4666                              <1> 	;jz	error
  4667                              <1> 	;jc	error
  4668                              <1> 		; jsr r0,namei / get the i-number of the special file
  4669                              <1>                 ; br errora / no such file
  4670 0000B432 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
  4671                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
  4672                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
  4673 0000B436 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  4674                              <1> 	;jc	error
  4675                              <1> 		; ble errora / less than 0?  yes, error
  4676 0000B438 6683F805            <1>         cmp	ax, 5 ;
  4677                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
  4678 0000B43C 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
  4679                              <1> 	;ja	error
  4680                              <1>         	; bgt errora / yes, error
  4681                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
  4682                              <1> iopen_retn:
  4683 0000B43E C3                  <1> 	retn
  4684                              <1> 		; rts    r0 / return with device number in r1
  4685                              <1> sysmnt_err0:
  4686 0000B43F C705[9DE30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  4686 0000B447 0000                <1>
  4687 0000B449 E939ECFFFF          <1> 	jmp	error
  4688                              <1> 
  4689                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
  4690                              <1> ; Last Modification: 09/12/2015
  4691                              <1> 
  4692                              <1> syssleep:
  4693                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  4694                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  4695                              <1> 	;
  4696                              <1> 	; Retro UNIX 8086 v1 feature only
  4697                              <1> 	; (INPUT -> none)
  4698                              <1> 	;
  4699 0000B44E 0FB61D[97E30000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4700 0000B455 8AA3[8BE00000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  4701 0000B45B E892090000          <1> 	call	sleep
  4702 0000B460 E942ECFFFF          <1> 	jmp	sysret
  4703                              <1> 
  4704                              <1> _vp_clr:
  4705                              <1> 	; Reset/Clear Video Page
  4706                              <1> 	;
  4707                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  4708                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  4709                              <1> 	;
  4710                              <1> 	; Retro UNIX 8086 v1 feature only !
  4711                              <1> 	;
  4712                              <1> 	; INPUTS -> 
  4713                              <1> 	;   BH = video page number	 
  4714                              <1> 	;
  4715                              <1> 	; OUTPUT ->
  4716                              <1> 	;   none
  4717                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  4718                              <1> 	;
  4719                              <1> 	; 04/12/2013
  4720 0000B465 28C0                <1> 	sub	al, al
  4721                              <1> 	; al = 0 (clear video page)
  4722                              <1> 	; bh = video page ; 13/05/2016
  4723 0000B467 B407                <1> 	mov	ah, 07h
  4724                              <1> 	; ah = 7 (attribute/color)
  4725 0000B469 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  4726 0000B46C 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  4727 0000B470 E8AF60FFFF          <1> 	call	_scroll_up
  4728                              <1> 	; bh = video page
  4729 0000B475 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  4730 0000B478 E9F662FFFF          <1> 	jmp 	_set_cpos
  4731                              <1> 
  4732                              <1> sysmsg:
  4733                              <1> 	; 13/05/2016
  4734                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  4735                              <1> 	; 01/07/2015 - 11/11/2015 (Retro UNIX 386 v1)
  4736                              <1> 	; Print user-application message on user's console tty
  4737                              <1> 	;
  4738                              <1> 	; Input -> EBX = Message address
  4739                              <1> 	;	   ECX = Message length (max. 255)
  4740                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  4741                              <1> 	;
  4742 0000B47D 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  4743 0000B483 0F871EECFFFF        <1> 	ja	sysret ; nothing to do with big message size
  4744 0000B489 08C9                <1> 	or	cl, cl
  4745 0000B48B 0F8416ECFFFF        <1> 	jz	sysret
  4746 0000B491 20D2                <1> 	and	dl, dl
  4747 0000B493 7502                <1> 	jnz	short sysmsg0
  4748 0000B495 B207                <1> 	mov	dl, 07h ; default color
  4749                              <1> 		; (black background, light gray character) 
  4750                              <1> sysmsg0:
  4751 0000B497 891D[68E30000]      <1> 	mov	[u.base], ebx
  4752 0000B49D 8815[B9D20000]      <1> 	mov	[ccolor], dl ; color attributes
  4753 0000B4A3 89E5                <1> 	mov	ebp, esp
  4754 0000B4A5 31DB                <1> 	xor	ebx, ebx ; 0
  4755 0000B4A7 891D[70E30000]      <1> 	mov	[u.nread], ebx ; 0
  4756                              <1> 	;
  4757 0000B4AD 381D[AFE30000]      <1> 	cmp	[u.kcall], bl ; 0
  4758 0000B4B3 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  4759                              <1> 	;
  4760 0000B4B5 890D[6CE30000]      <1> 	mov	[u.count], ecx
  4761 0000B4BB 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ
  4762 0000B4BC 29CC                <1> 	sub	esp, ecx
  4763 0000B4BE 89E7                <1> 	mov	edi, esp
  4764 0000B4C0 89E6                <1> 	mov	esi, esp
  4765 0000B4C2 66891D[ADE30000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  4766                              <1> 	; 11/11/2015
  4767 0000B4C9 8A25[78E30000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  4768                              <1> 	; 0 = none
  4769 0000B4CF FECC                <1> 	dec	ah
  4770 0000B4D1 790C                <1> 	jns	short sysmsg1 
  4771 0000B4D3 8A1D[97E30000]      <1> 	mov	bl, [u.uno] ; process number	
  4772 0000B4D9 8AA3[8BE00000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  4773                              <1> sysmsg1:
  4774 0000B4DF 8825[9CE30000]      <1> 	mov	[u.ttyn], ah
  4775                              <1> sysmsg2:
  4776 0000B4E5 E810080000          <1> 	call	cpass
  4777 0000B4EA 7416                <1> 	jz	short sysmsg5
  4778 0000B4EC AA                  <1> 	stosb
  4779 0000B4ED 20C0                <1> 	and	al, al
  4780 0000B4EF 75F4                <1> 	jnz	short sysmsg2
  4781                              <1> sysmsg3:
  4782 0000B4F1 80FC07              <1> 	cmp	ah, 7 ; tty number
  4783 0000B4F4 7711                <1> 	ja	short sysmsg6 ; serial port
  4784 0000B4F6 E83E000000          <1> 	call	print_cmsg
  4785                              <1> sysmsg4:
  4786 0000B4FB 89EC                <1> 	mov	esp, ebp	
  4787 0000B4FD E9A5EBFFFF          <1> 	jmp	sysret
  4788                              <1> sysmsg5:
  4789 0000B502 C60700              <1> 	mov	byte [edi], 0
  4790 0000B505 EBEA                <1> 	jmp	short sysmsg3
  4791                              <1> sysmsg6:
  4792 0000B507 8A06                <1> 	mov	al, [esi]
  4793 0000B509 E8DC080000          <1> 	call	sndc
  4794 0000B50E 72EB                <1> 	jc	short sysmsg4
  4795 0000B510 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  4796 0000B513 76E6                <1> 	jna	short sysmsg4
  4797 0000B515 46                  <1> 	inc 	esi
  4798 0000B516 8A25[9CE30000]      <1> 	mov	ah, [u.ttyn]
  4799 0000B51C EBE9                <1> 	jmp	short sysmsg6
  4800                              <1> 
  4801                              <1> sysmsgk: ; Temporary (01/07/2015)
  4802                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  4803                              <1> 	; (ECX -character count- will not be considered)
  4804 0000B51E 8B35[68E30000]      <1> 	mov	esi, [u.base]
  4805 0000B524 8A25[B8D20000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  4806 0000B52A 8825[9CE30000]      <1> 	mov	[u.ttyn], ah
  4807 0000B530 C605[AFE30000]00    <1> 	mov	byte [u.kcall], 0
  4808 0000B537 EBB8                <1> 	jmp	short sysmsg3
  4809                              <1> 	
  4810                              <1> print_cmsg: 
  4811                              <1> 	; 13/05/2016 - TRDOS 386 (TRDOS v2.0)
  4812                              <1> 	; 01/07/2015 (Retro UNIX 386 v1)
  4813                              <1> 	;
  4814                              <1> 	; print message (on user's console tty) 
  4815                              <1> 	;	with requested color
  4816                              <1> 	;
  4817                              <1> 	; INPUTS:
  4818                              <1> 	;	esi = message address
  4819                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  4820                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  4821                              <1> 	
  4822 0000B539 8A3D[9CE30000]      <1> 	mov	bh, [u.ttyn]
  4823                              <1> 	;mov	bh, ah
  4824                              <1> 
  4825 0000B53F AC                  <1> 	lodsb
  4826                              <1> pcmsg1:
  4827 0000B540 56                  <1> 	push 	esi
  4828 0000B541 8A1D[B9D20000]      <1> 	mov	bl, [ccolor]
  4829                              <1> 	;mov	bh, [u.ttyn]
  4830 0000B547 E89C61FFFF          <1> 	call 	_write_tty
  4831 0000B54C 5E                  <1> 	pop	esi
  4832 0000B54D AC                  <1> 	lodsb
  4833 0000B54E 20C0                <1> 	and 	al, al  ; 0
  4834 0000B550 75EE                <1> 	jnz 	short pcmsg1
  4835 0000B552 C3                  <1> 	retn
  4836                              <1> 
  4837                              <1> sysgeterr:
  4838                              <1> 	; 09/12/2015
  4839                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  4840                              <1> 	; Get last error number or page fault count
  4841                              <1> 	; (for debugging)
  4842                              <1> 	;
  4843                              <1> 	; Input -> EBX = return type
  4844                              <1> 	;	   0 = last error code (which is in 'u.error')	
  4845                              <1> 	;	   FFFFFFFFh = page fault count for running process
  4846                              <1> 	;	   FFFFFFFEh = total page fault count
  4847                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  4848                              <1> 	;
  4849                              <1> 	; Output -> EAX = last error number or page fault count
  4850                              <1> 	;	   (depending on EBX input)
  4851                              <1> 	; 	
  4852 0000B553 21DB                <1> 	and 	ebx, ebx
  4853 0000B555 750B                <1> 	jnz	short glerr_2
  4854                              <1> glerr_0:
  4855 0000B557 A1[9DE30000]        <1> 	mov	eax, [u.error]
  4856                              <1> glerr_1:
  4857 0000B55C A3[48E30000]        <1> 	mov	[u.r0], eax
  4858 0000B561 C3                  <1>  	retn
  4859                              <1> glerr_2:
  4860 0000B562 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  4861 0000B563 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  4862 0000B565 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  4863 0000B566 75EF                <1> 	jnz	short glerr_0
  4864 0000B568 A1[2CF10000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  4865 0000B56D EBED                <1>         jmp     short glerr_1
  4866                              <1> glerr_3:
  4867 0000B56F A1[B1E30000]        <1> 	mov 	eax, [u.pfcount]
  4868 0000B574 EBE6                <1> 	jmp	short glerr_1
  4869                              <1> 
  4870                              <1> load_and_run_file:
  4871                              <1> 	; 06/05/2016
  4872                              <1> 	; 03/05/2016
  4873                              <1> 	; 02/05/2016
  4874                              <1> 	; 24/04/2016
  4875                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  4876                              <1> 	; 23/10/2015 (Retro UNIX 386 v1, 'sysexec')
  4877                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4878                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  4879                              <1> 	; EAX = First Cluster number
  4880                              <1> 	; EDX = File Size
  4881                              <1> 	; ESI = Argument list address
  4882                              <1> 	; [argc] = argument count
  4883                              <1> 	; [u.nread] = argument list length
  4884                              <1> 	; [esp] = return address to the caller (*)
  4885                              <1> 	;
  4886 0000B576 8935[C8E30000]      <1> 	mov	[argv], esi
  4887 0000B57C 8915[D1E30000]      <1> 	mov	[i.size], edx
  4888 0000B582 A3[CDE30000]        <1> 	mov	[ii], eax
  4889                              <1> 
  4890                              <1> 	; 06/05/2016
  4891                              <1> 	; Set 'sysexit' return order to MainProg
  4892                              <1> 	;
  4893 0000B587 58                  <1> 	pop	eax ; * 'loc_load_and_run_file_8:' address
  4894 0000B588 8B25[24D20000]      <1> 	mov	esp, [tss.esp0]
  4895                              <1> 	;
  4896                              <1> 	; 'loc_load_run_file_8' address has 
  4897                              <1> 	; 'jmp loc_file_rw_restore_retn' instruction
  4898                              <1> 	; 'loc_file_rw_restore_retn:' will return to
  4899                              <1> 	; [mainprog_return_addr] 
  4900                              <1> 	; just after 'call command_interpreter'
  4901                              <1> 	;
  4902 0000B58E 68[923F0000]        <1> 	push	_end_of_mainprog ; we must not return to here !
  4903 0000B593 FF35[FCDF0000]      <1> 	push	dword [mainprog_return_addr]
  4904 0000B599 89E5                <1> 	mov	ebp, esp ; **
  4905                              <1> 	;	
  4906 0000B59B 9C                  <1> 	pushfd  ; EFLAGS      ; IRETD
  4907 0000B59C 6A08                <1> 	push	KCODE ; cs    ; IRETD
  4908 0000B59E 50                  <1> 	push	eax ; * (eip) ; IRETD
  4909 0000B59F 8925[40E30000]      <1> 	mov	[u.sp], esp
  4910 0000B5A5 1E                  <1> 	push	ds
  4911 0000B5A6 06                  <1> 	push	es
  4912 0000B5A7 0FA0                <1> 	push	fs
  4913 0000B5A9 0FA8                <1> 	push	gs	
  4914 0000B5AB 60                  <1> 	pushad
  4915 0000B5AC 68[A7A00000]        <1> 	push	sysret
  4916 0000B5B1 8925[44E30000]      <1> 	mov	[u.usp], esp
  4917                              <1> 	;
  4918 0000B5B7 E851060000          <1> 	call	wswap ; Save MainProg (process 1) 'u' structure
  4919                              <1> 		      ; and registers for return (from program)	
  4920 0000B5BC 89EC                <1> 	mov	esp, ebp ; **
  4921 0000B5BE 50                  <1> 	push	eax  ; * 'loc_load_and_run_file_8:' address
  4922                              <1> 	;
  4923                              <1> 	;;; 02/05/2016
  4924                              <1> 	;;; Create a new process (parent: MainProg)	
  4925 0000B5BF 31F6                <1> 	xor 	esi, esi
  4926                              <1> cnpm_1: ; search p.stat table for unused process number
  4927 0000B5C1 46                  <1> 	inc	esi
  4928 0000B5C2 80BE[BBE00000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE
  4929                              <1> 				; is process active, unused, dead
  4930 0000B5C9 760B                <1> 	jna	short cnpm_2	; it's unused so branch
  4931 0000B5CB 6683FE10            <1> 	cmp	si, nproc 	; all processes checked
  4932 0000B5CF 72F0                <1> 	jb	short cnpm_1    ; no, branch back
  4933 0000B5D1 E9328AFFFF          <1> 	jmp	panic 
  4934                              <1> cnpm_2:
  4935 0000B5D6 A1[A1E30000]        <1> 	mov	eax, [u.pgdir] ; page directory of MainProg
  4936 0000B5DB A3[A5E30000]        <1> 	mov	[u.ppgdir], eax ; parent's page directory
  4937 0000B5E0 E87C7BFFFF          <1> 	call	allocate_page
  4938 0000B5E5 0F821D8AFFFF        <1> 	jc	panic
  4939                              <1> 	; EAX = UPAGE (user structure page) address
  4940 0000B5EB A3[98E30000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  4941 0000B5F0 89F7                <1> 	mov	edi, esi
  4942 0000B5F2 66C1E702            <1> 	shl	di, 2
  4943 0000B5F6 8987[C8E00000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  4944 0000B5FC E8DA7BFFFF          <1> 	call	clear_page ; 03/05/2016
  4945                              <1> 	;movzx	eax, byte [p.ttyc] ; console tty (for MainProg)
  4946 0000B601 6629C0              <1> 	sub	ax, ax ; 0
  4947 0000B604 668986[8BE00000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  4948                              <1> 				   ; ah - reset child's wait channel	
  4949 0000B60B 89F0                <1> 	mov	eax, esi
  4950 0000B60D A2[97E30000]        <1> 	mov	[u.uno], al ; child process number
  4951 0000B612 FE86[BBE00000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN
  4952 0000B618 66D1E6              <1> 	shl	si, 1 ; multiply si by 2 to get index into p.pid table
  4953 0000B61B 66FF05[32E30000]    <1> 	inc	word [mpid] ; increment m.pid; get a new process name
  4954 0000B622 66A1[32E30000]      <1> 	mov	ax, [mpid]
  4955 0000B628 668986[2AE00000]    <1> 	mov	[esi+p.pid-2], ax ; put new process name 
  4956                              <1> 				  ; in child process' name slot
  4957                              <1> 	;mov	ax, [p.pid]  ; get process name of MainProg
  4958 0000B62F 66B80100            <1> 	mov	ax, 1
  4959 0000B633 668986[4AE00000]    <1> 	mov	[esi+p.ppid-2], ax ; put parent process name 
  4960                              <1> 			           ; in parent process slot for child
  4961 0000B63A 6648                <1> 	dec	ax ; 0
  4962 0000B63C 66A3[78E30000]      <1> 	mov 	[u.ttyp], ax ; 0
  4963                              <1> 	;;;
  4964 0000B642 A1[CDE30000]        <1> 	mov 	eax,  [ii]
  4965                              <1> 	; Retro UNIX 386 v1, 'sysexec' (u2.s)
  4966 0000B647 E898070000          <1> 	call	iopen
  4967 0000B64C EB0A                <1> 	jmp	short sysexec_7 ; 02/05/2016
  4968                              <1> 
  4969                              <1> sysexec_6:
  4970                              <1> 	;;02/05/2016
  4971                              <1> 	; 23/04/2016
  4972                              <1> 	; 18/10/2015 ('sysexec_6')
  4973                              <1> 	; 23/06/2015
  4974                              <1> 	;;mov	eax, [u.pgdir] ; parent's page directory
  4975                              <1> 	;;cmp 	eax, [k_page_dir] ; TRDOS MainProg ? 
  4976                              <1> 	;;je	short sysexec_7
  4977 0000B64E A1[A1E30000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  4978 0000B653 E8427CFFFF          <1> 	call	deallocate_page_dir
  4979                              <1> sysexec_7:
  4980 0000B658 E8727BFFFF          <1> 	call	make_page_dir
  4981 0000B65D 0F82A589FFFF        <1> 	jc	panic  ; allocation error 
  4982                              <1> 		       ; after a deallocation would be nonsence !?
  4983                              <1> 	; 24/07/2015
  4984                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  4985                              <1> 	;     of the user's page directory
  4986                              <1> 	;     (It is needed for interrupts!)
  4987                              <1> 	; 18/10/2015
  4988 0000B663 8B15[88D20000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  4989 0000B669 8B02                <1> 	mov	eax, [edx] ; physical address of
  4990                              <1> 			   ; kernel's first page table (1st 4 MB)
  4991                              <1> 			   ; (PDE 0 of kernel's page directory)
  4992 0000B66B 8B15[A1E30000]      <1> 	mov 	edx, [u.pgdir]
  4993 0000B671 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  4994                              <1> 	;
  4995                              <1> 	; 20/07/2015
  4996 0000B673 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  4997                              <1> 	; 18/10/2015
  4998 0000B678 BE[B8E30000]        <1> 	mov	esi, pcore ; physical start address
  4999                              <1> sysexec_8:	
  5000 0000B67D B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  5001 0000B682 E8667BFFFF          <1> 	call	make_page_table
  5002 0000B687 0F827B89FFFF        <1> 	jc	panic
  5003                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  5004 0000B68D E8697BFFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  5005 0000B692 0F827089FFFF        <1> 	jc	panic
  5006                              <1> 	;
  5007 0000B698 8906                <1> 	mov	[esi], eax ; 24/06/2015
  5008                              <1> 	; ebx = virtual address (24/07/2015)
  5009 0000B69A E8B780FFFF          <1> 	call 	add_to_swap_queue
  5010                              <1> 	; 18/10/2015
  5011 0000B69F 81FE[BCE30000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  5012 0000B6A5 740C                <1> 	je	short sysexec_9 ; yes
  5013 0000B6A7 BE[BCE30000]        <1> 	mov	esi, ecore  ; physical address of the last page 
  5014                              <1> 	; 20/07/2015
  5015 0000B6AC BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  5016                              <1> 	; ebx = virtual end address + segment base address - 4K
  5017 0000B6B1 EBCA                <1>         jmp     short sysexec_8
  5018                              <1> sysexec_9:
  5019                              <1> 	; 24/04/2016
  5020                              <1> 	; 18/10/2015
  5021                              <1> 	; 26/08/2015
  5022                              <1> 	; 25/06/2015
  5023                              <1> 	; move arguments from kernel stack to [ecore]
  5024                              <1> 	; (argument list/line will be copied from kernel stack
  5025                              <1> 	; frame to the last (stack) page of user's core memory)
  5026                              <1> 	; 18/10/2015
  5027 0000B6B3 8B3D[BCE30000]      <1> 	mov	edi, [ecore]
  5028 0000B6B9 81C700100000        <1> 	add	edi, PAGE_SIZE
  5029 0000B6BF 0FB705[C6E30000]    <1> 	movzx	eax, word [argc]
  5030 0000B6C6 09C0                <1> 	or	eax, eax
  5031 0000B6C8 7509                <1> 	jnz	short sysexec_10
  5032 0000B6CA 89FB                <1> 	mov 	ebx, edi
  5033 0000B6CC 83EB04              <1> 	sub	ebx, 4 
  5034 0000B6CF 8903                <1> 	mov	[ebx], eax ; 0
  5035 0000B6D1 EB44                <1> 	jmp 	short sysexec_13
  5036                              <1> sysexec_10:
  5037 0000B6D3 8B0D[70E30000]      <1> 	mov	ecx, [u.nread]
  5038                              <1> 	;mov	esi, TextBuffer
  5039 0000B6D9 8B35[C8E30000]      <1> 	mov	esi, [argv] ; 24/04/2016 (TRDOS 386  = TRDOS v2.0)
  5040 0000B6DF 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  5041 0000B6E1 89C2                <1> 	mov	edx, eax
  5042 0000B6E3 FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  5043 0000B6E5 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  5044 0000B6E8 89FB                <1> 	mov	ebx, edi
  5045 0000B6EA 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  5046 0000B6ED 29D3                <1> 	sub 	ebx, edx
  5047 0000B6EF 89FA                <1> 	mov	edx, edi
  5048 0000B6F1 F3A4                <1> 	rep	movsb
  5049 0000B6F3 89D6                <1> 	mov 	esi, edx
  5050 0000B6F5 89DF                <1> 	mov 	edi, ebx
  5051 0000B6F7 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  5052 0000B6FC 2B15[BCE30000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  5053 0000B702 AB                  <1> 	stosd	; eax = argument count	
  5054                              <1> sysexec_11:
  5055 0000B703 89F0                <1> 	mov	eax, esi
  5056 0000B705 01D0                <1> 	add	eax, edx
  5057 0000B707 AB                  <1> 	stosd  ; eax = virtual address
  5058 0000B708 FE0D[C6E30000]      <1> 	dec	byte [argc]
  5059 0000B70E 7407                <1> 	jz	short sysexec_13
  5060                              <1> sysexec_12:
  5061 0000B710 AC                  <1> 	lodsb
  5062 0000B711 20C0                <1> 	and	al, al
  5063 0000B713 75FB                <1> 	jnz	short sysexec_12
  5064 0000B715 EBEC                <1> 	jmp	short sysexec_11
  5065                              <1> sysexec_13:
  5066                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  5067                              <1> 	; 23/06/2015 - 19/10/2015 (Retro UNIX 386 v1, 'sysexec_13')
  5068                              <1> 	;
  5069                              <1> 	; moving arguments to [ecore] is OK here..
  5070                              <1> 	;
  5071                              <1> 	; ebx = beginning addres of argument list pointers
  5072                              <1> 		;	in user's stack
  5073 0000B717 2B1D[BCE30000]      <1> 	sub 	ebx, [ecore]
  5074 0000B71D 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  5075                              <1> 			; end of core - 4096 (last page)
  5076                              <1> 			; (virtual address)
  5077 0000B723 891D[C8E30000]      <1> 	mov	[argv], ebx
  5078 0000B729 891D[74E30000]      <1> 	mov	[u.break], ebx ; available user memory
  5079                              <1> 	;
  5080 0000B72F 29C0                <1> 	sub	eax, eax
  5081 0000B731 C705[6CE30000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  5081 0000B739 0000                <1>
  5082 0000B73B C705[58E30000]-     <1> 	mov	dword [u.fofp], u.off
  5082 0000B741 [64E30000]          <1>
  5083 0000B745 A3[64E30000]        <1> 	mov	[u.off], eax ; 0
  5084 0000B74A A3[68E30000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  5085 0000B74F A1[CDE30000]        <1> 	mov	eax, [ii] ; Fist Cluster of the Program (PRG) file
  5086                              <1> 	; EAX = First cluster of the executable file
  5087 0000B754 E831010000          <1> 	call	readi
  5088                              <1> 
  5089 0000B759 8B0D[74E30000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  5090 0000B75F 890D[6CE30000]      <1> 	mov	[u.count], ecx ; save for overrun check
  5091                              <1> 	;
  5092 0000B765 8B0D[70E30000]      <1> 	mov	ecx, [u.nread]
  5093 0000B76B 890D[74E30000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  5094 0000B771 80F920              <1> 	cmp	cl, 32
  5095 0000B774 7540                <1>         jne     short sysexec_15
  5096                              <1> 	;:
  5097                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  5098 0000B776 8B35[B8E30000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  5099                              <1> 		             ; (phys. start addr. of the exec. file)
  5100 0000B77C AD                  <1> 	lodsd
  5101 0000B77D 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  5102 0000B781 7533                <1> 	jne	short sysexec_15
  5103 0000B783 AD                  <1> 	lodsd
  5104 0000B784 89C1                <1> 	mov	ecx, eax ; text (code) section size
  5105 0000B786 AD                  <1> 	lodsd
  5106 0000B787 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  5107 0000B789 89CB                <1> 	mov	ebx, ecx
  5108 0000B78B AD                  <1> 	lodsd	
  5109 0000B78C 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  5110 0000B78E 3B1D[6CE30000]      <1> 	cmp	ebx, [u.count]
  5111 0000B794 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  5112                              <1> 	;
  5113                              <1> 	; add bss section size to [u.break]
  5114 0000B796 0105[74E30000]      <1> 	add 	[u.break], eax
  5115                              <1> 	;
  5116 0000B79C 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  5117                              <1> 	;cmp	ecx, [u.count]
  5118                              <1> 	;jnb	short sysexec_16
  5119 0000B79F 890D[6CE30000]      <1> 	mov	[u.count], ecx ; required read count
  5120 0000B7A5 EB29                <1> 	jmp	short sysexec_16
  5121                              <1> sysexec_14:
  5122                              <1> 	; insufficient (out of) memory
  5123 0000B7A7 C705[9DE30000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  5123 0000B7AF 0000                <1>
  5124 0000B7B1 E9D1E8FFFF          <1> 	jmp	error
  5125                              <1> sysexec_15:
  5126 0000B7B6 8B15[D1E30000]      <1>         mov	edx, [i.size] ; file size
  5127 0000B7BC 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  5128 0000B7BE 7626                <1> 	jna	short sysexec_17 ; no need to next read
  5129 0000B7C0 01D1                <1> 	add	ecx, edx ; [i.size]
  5130 0000B7C2 3B0D[6CE30000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  5131 0000B7C8 77DD                <1> 	ja	short sysexec_14
  5132 0000B7CA 8915[6CE30000]      <1> 	mov	[u.count], edx
  5133                              <1> sysexec_16:
  5134 0000B7D0 A1[CDE30000]        <1> 	mov	eax, [ii] ; first cluster
  5135 0000B7D5 E8B0000000          <1> 	call	readi
  5136 0000B7DA 8B0D[70E30000]      <1> 	mov	ecx, [u.nread]
  5137 0000B7E0 010D[74E30000]      <1> 	add	[u.break], ecx
  5138                              <1> sysexec_17:
  5139 0000B7E6 A1[CDE30000]        <1> 	mov	eax, [ii] ; first cluster
  5140 0000B7EB E8F5050000          <1> 	call	iclose
  5141 0000B7F0 31C0                <1> 	xor     eax, eax
  5142 0000B7F2 FEC0                <1> 	inc	al
  5143 0000B7F4 66A3[8CE30000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  5144 0000B7FA 66A3[8EE30000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  5145 0000B800 833D[A5E30000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller MainProg (kernel) ?
  5146 0000B807 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  5147                              <1> 	; If the caller is kernel (MainProg), 'sysexec' will come here
  5148 0000B809 8B15[88D20000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  5149 0000B80F 8915[A5E30000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
  5150                              <1> sysexec_18:
  5151                              <1> 	; 02/05/2016
  5152                              <1> 	; 24/04/2016 (TRDOS 386 = TRDOS v2.0)
  5153                              <1> 	; 18/10/2015 (Retro UNIX 386 v1)
  5154                              <1> 	; 05/08/2015
  5155                              <1> 	; 29/07/2015
  5156 0000B815 8B2D[C8E30000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  5157                              <1> 			    ; list pointers (argument count)
  5158 0000B81B FA                  <1> 	cli
  5159 0000B81C 8B25[24D20000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
  5160                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  5161                              <1> 			    ; for this process	 
  5162                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  5163                              <1> 	;xor	eax, eax ; 0
  5164 0000B822 FEC8                <1> 	dec	al ; eax = 0
  5165 0000B824 66BA2300            <1> 	mov	dx, UDATA
  5166 0000B828 6652                <1> 	push	dx  ; user's stack segment
  5167 0000B82A 55                  <1> 	push	ebp ; user's stack pointer
  5168                              <1> 		    ; (points to number of arguments)
  5169 0000B82B FB                  <1> 	sti
  5170 0000B82C 9C                  <1> 	pushfd	; EFLAGS
  5171                              <1> 		; Set IF for enabling interrupts in user mode	
  5172                              <1> 	;or	dword [esp], 200h 
  5173                              <1> 	;
  5174                              <1> 	;mov	bx, UCODE
  5175                              <1> 	;push	bx ; user's code segment
  5176 0000B82D 6A1B                <1> 	push	UCODE
  5177                              <1> 	;push	0
  5178 0000B82F 50                  <1> 	push	eax ; EIP (=0) - start address -	
  5179 0000B830 8925[40E30000]      <1> 	mov	[u.sp], esp ; 29/07/2015
  5180                              <1> 	; 05/08/2015
  5181                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  5182                              <1> 	; ('push dx' would cause to general protection fault, 
  5183                              <1> 	; after 'pop ds' etc.)
  5184                              <1> 	;
  5185                              <1> 	;; push dx ; ds (UDATA)
  5186                              <1> 	;; push dx ; es (UDATA)
  5187                              <1> 	;; push dx ; fs (UDATA)
  5188                              <1> 	;; push dx ; gs (UDATA)
  5189                              <1> 	;
  5190                              <1> 	; This is a trick to prevent general protection fault
  5191                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  5192 0000B836 8EC2                <1> 	mov 	es, dx ; UDATA
  5193 0000B838 06                  <1> 	push 	es ; ds (UDATA)
  5194 0000B839 06                  <1> 	push 	es ; es (UDATA)
  5195 0000B83A 06                  <1> 	push 	es ; fs (UDATA)
  5196 0000B83B 06                  <1> 	push	es ; gs (UDATA)
  5197 0000B83C 66BA1000            <1> 	mov	dx, KDATA
  5198 0000B840 8EC2                <1> 	mov	es, dx
  5199                              <1> 	;
  5200                              <1> 	;; pushad simulation
  5201 0000B842 89E5                <1> 	mov	ebp, esp ; esp before pushad
  5202 0000B844 50                  <1> 	push	eax ; eax (0)
  5203 0000B845 50                  <1> 	push	eax ; ecx (0)
  5204 0000B846 50                  <1> 	push	eax ; edx (0)
  5205 0000B847 50                  <1> 	push	eax ; ebx (0)
  5206 0000B848 55                  <1> 	push	ebp ; esp before pushad
  5207 0000B849 50                  <1> 	push	eax ; ebp (0)
  5208 0000B84A 50                  <1> 	push	eax ; esi (0)		
  5209 0000B84B 50                  <1> 	push	eax ; edi (0)	
  5210                              <1> 	;
  5211 0000B84C A3[48E30000]        <1> 	mov	[u.r0], eax ; eax = 0
  5212 0000B851 8925[44E30000]      <1> 	mov	[u.usp], esp
  5213                              <1> 
  5214                              <1> 	; 02/05/2016
  5215 0000B857 FE05[3FE30000]      <1> 	inc	byte [sysflg] ; 0FFh -> 0
  5216 0000B85D 0FB61D[97E30000]    <1> 	movzx	ebx, byte [u.uno]	
  5217 0000B864 6683BB[4AE00000]01  <1> 	cmp	word [ebx+p.ppid-2], 1 ; MainProg
  5218 0000B86C 0F8738E8FFFF        <1> 	ja	sysret0 ; 03/05/2016
  5219 0000B872 68[A7A00000]        <1> 	push	sysret ; * 
  5220 0000B877 8925[44E30000]      <1> 	mov	[u.usp], esp
  5221 0000B87D E88B030000          <1> 	call	wswap ; save child process 'u' structure and
  5222                              <1> 		      ; registers
  5223 0000B882 8305[44E30000]04    <1> 	add	dword [u.usp], 4 ; 03/05/2016 
  5224                              <1> sysexec_19: ; 02/05/2016
  5225 0000B889 C3                  <1> 	retn ; * 'sysret' ; byte [sysflg] -> 0FFh
  5226                              <1> 
  5227                              <1> readi:
  5228                              <1> 	; 01/05/2016
  5229                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5230                              <1> 	; 20/05/2015 - Retro UNIX 386 v1
  5231                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5232                              <1> 	;
  5233                              <1> 	; Reads from a file whose the first cluster number in EAX
  5234                              <1> 	; 
  5235                              <1> 	; INPUTS ->
  5236                              <1> 	;    EAX - First cluster number of the file
  5237                              <1> 	;    u.count - byte count user desires
  5238                              <1> 	;    u.base - points to user buffer
  5239                              <1> 	;    u.fofp - points to dword with current file offset
  5240                              <1> 	;    i.size - file size
  5241                              <1> 	; OUTPUTS ->
  5242                              <1> 	;    u.count - cleared
  5243                              <1> 	;    u.nread - accumulates total bytes passed back
  5244                              <1> 	;
  5245                              <1> 	; ((EAX)) input/output
  5246                              <1> 	; (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
  5247                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
  5248                              <1> 
  5249 0000B88A 31D2                <1> 	xor	edx, edx ; 0
  5250 0000B88C 8915[70E30000]      <1> 	mov 	[u.nread], edx ; 0
  5251 0000B892 668915[ADE30000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  5252 0000B899 3915[6CE30000]      <1> 	cmp 	[u.count], edx ; 0
  5253 0000B89F 7701                <1> 	ja 	short readi_1
  5254 0000B8A1 C3                  <1> 	retn
  5255                              <1> readi_1:
  5256                              <1> dskr:
  5257                              <1> 	; 01/05/2016
  5258                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5259                              <1> 	; 24/05/2015 - 12/10/2015 (Retro UNIX 386 v1)
  5260                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  5261                              <1> dskr_0:
  5262 0000B8A2 8B15[D1E30000]      <1>         mov	edx, [i.size]
  5263 0000B8A8 8B1D[58E30000]      <1> 	mov	ebx, [u.fofp]
  5264 0000B8AE 2B13                <1> 	sub	edx, [ebx]
  5265 0000B8B0 7647                <1> 	jna	short dskr_4
  5266                              <1> 	;
  5267 0000B8B2 50                  <1> 	push	eax ; 01/05/2016
  5268 0000B8B3 3B15[6CE30000]      <1> 	cmp     edx, [u.count] 
  5269 0000B8B9 7306                <1> 	jnb	short dskr_1
  5270 0000B8BB 8915[6CE30000]      <1> 	mov	[u.count], edx
  5271                              <1> dskr_1:
  5272                              <1> 	; EAX = First Cluster
  5273                              <1> 	; [Current_Drv] = Physical drive number 
  5274 0000B8C1 E83B000000          <1> 	call	mget_r
  5275                              <1> 	; NOTE: in 'mget_r', relevant sector will be read in buffer
  5276                              <1> 	; if it not already in buffer !
  5277 0000B8C6 BB[DDE30000]        <1> 	mov	ebx, readi_buffer
  5278 0000B8CB 803D[AFE30000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  5279 0000B8D2 770F                <1> 	ja	short dskr_3	  ; zf=0 -> the caller is 'namei'
  5280 0000B8D4 66833D[ADE30000]00  <1> 	cmp	word [u.pcount], 0
  5281 0000B8DC 7705                <1> 	ja	short dskr_3
  5282                              <1> dskr_2:
  5283                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  5284 0000B8DE E89A010000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  5285                              <1> dskr_3:
  5286                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
  5287 0000B8E3 E8F3010000          <1> 	call	sioreg
  5288 0000B8E8 87F7                <1> 	xchg	esi, edi
  5289                              <1> 	; EDI = file (user data) offset
  5290                              <1> 	; ESI = sector (I/O) buffer offset
  5291                              <1> 	; ECX = byte count
  5292 0000B8EA F3A4                <1> 	rep	movsb
  5293                              <1> 	; eax = remain bytes in buffer
  5294                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  5295 0000B8EC 09C0                <1> 	or	eax, eax
  5296 0000B8EE 75EE                <1> 	jnz	short dskr_2 ; (page end before system buffer end!)		
  5297 0000B8F0 58                  <1> 	pop	eax  ; (first cluster number)
  5298 0000B8F1 390D[6CE30000]      <1> 	cmp	[u.count], ecx ; 0
  5299 0000B8F7 77A9                <1> 	ja	short dskr_0
  5300                              <1> dskr_4:
  5301 0000B8F9 C605[AFE30000]00    <1> 	mov	byte [u.kcall], 0
  5302 0000B900 C3                  <1> 	retn
  5303                              <1> 
  5304                              <1> mget_r:
  5305                              <1> 	; 29/04/2016
  5306                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5307                              <1> 	; 03/06/2015 (Retro UNIX 386 v1, 'mget', u.5s)
  5308                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5309                              <1> 	;
  5310                              <1> 	; Get existing or (allocate) a new disk block for file
  5311                              <1> 	; 
  5312                              <1> 	; INPUTS ->
  5313                              <1> 	;    u.fofp = file offset pointer
  5314                              <1> 	;    EAX = First Cluster
  5315                              <1> 	;    (u.off = file offset)
  5316                              <1> 	; OUTPUTS ->
  5317                              <1> 	;    EAX = logical sector number
  5318                              <1> 	;    ESI = Logical Dos Drive Description Table address	
  5319                              <1> 	;
  5320                              <1> 	; Modified registers: EDX, EBX, ECX, ESI, EDI, EBP  
  5321                              <1> 
  5322 0000B901 8B35[58E30000]      <1> 	mov     esi, [u.fofp]
  5323 0000B907 8B1E                <1> 	mov	ebx, [esi] ; u.off
  5324                              <1> 
  5325 0000B909 29C9                <1> 	sub	ecx, ecx
  5326 0000B90B 8A2D[4ED30000]      <1> 	mov	ch, [Current_Drv]
  5327                              <1> 
  5328 0000B911 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5329 0000B916 01CE                <1> 	add	esi, ecx
  5330                              <1> 
  5331 0000B918 380D[BCDF0000]      <1> 	cmp	[readi.valid], cl ; 0
  5332 0000B91E 764B                <1> 	jna	short mget_r_0
  5333                              <1> 	
  5334 0000B920 3A2D[BDDF0000]      <1> 	cmp	ch, [readi.drv]
  5335 0000B926 7543                <1> 	jne	short mget_r_0
  5336                              <1> 
  5337 0000B928 3B05[D0DF0000]      <1> 	cmp	eax, [readi.fclust]
  5338 0000B92E 7567                <1> 	jne	short mget_r_3
  5339                              <1> 	
  5340 0000B930 668B0D[C4DF0000]    <1> 	mov	cx, [readi.bpc]
  5341 0000B937 41                  <1> 	inc	ecx ; <= 65536
  5342 0000B938 29D2                <1> 	sub	edx, edx
  5343 0000B93A F7F1                <1> 	div	ecx
  5344                              <1> 
  5345 0000B93C 8B3D[CCDF0000]      <1> 	mov	edi, [readi.c_index] ; cluster index
  5346                              <1> 
  5347 0000B942 39F8                <1> 	cmp	eax, edi
  5348 0000B944 0F858B000000        <1>         jne     mget_r_5  ; (*)
  5349                              <1> 
  5350                              <1> 	; edx = byte offset in cluster (<= 65535)
  5351 0000B94A 668915[C6DF0000]    <1> 	mov	[readi.offset], dx
  5352 0000B951 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5353 0000B955 8815[BFDF0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5354                              <1> 	
  5355 0000B95B A1[C8DF0000]        <1> 	mov	eax, [readi.cluster]
  5356 0000B960 8B15[D4DF0000]      <1> 	mov	edx, [readi.fs_index]
  5357 0000B966 E9AF000000          <1>         jmp     mget_r_8
  5358                              <1> 	
  5359                              <1> mget_r_0:
  5360 0000B96B 882D[BDDF0000]      <1> 	mov	[readi.drv], ch ; physical drive number
  5361 0000B971 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5362 0000B975 7707                <1> 	ja	short  mget_r_1
  5363 0000B977 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  5364 0000B97A D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  5365 0000B97C EB03                <1> 	jmp	short mget_r_2	
  5366                              <1> mget_r_1:
  5367 0000B97E 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]
  5368                              <1> mget_r_2:
  5369 0000B981 880D[BEDF0000]      <1> 	mov	[readi.spc], cl  ; sectors per cluster
  5370                              <1> 	; NOTE: readi bytes per sector value is always 512 ! 
  5371 0000B987 66C1E109            <1> 	shl	cx, 9 ; * 512
  5372 0000B98B 6649                <1> 	dec	cx ; bytes per cluster - 1
  5373 0000B98D 66890D[C4DF0000]    <1> 	mov	[readi.bpc], cx
  5374 0000B994 6629C9              <1> 	sub	cx, cx
  5375                              <1> mget_r_3:
  5376 0000B997 A3[D0DF0000]        <1> 	mov	[readi.fclust], eax ; first cluster (or FDT address)
  5377 0000B99C 880D[BCDF0000]      <1> 	mov	[readi.valid], cl ; 0 
  5378 0000B9A2 880D[BFDF0000]      <1> 	mov	[readi.s_index], cl ; 0
  5379 0000B9A8 66890D[C6DF0000]    <1> 	mov	[readi.offset], cx ; 0
  5380 0000B9AF 890D[CCDF0000]      <1> 	mov	[readi.c_index], ecx ; 0
  5381 0000B9B5 890D[C8DF0000]      <1> 	mov	[readi.cluster], ecx ; 0
  5382 0000B9BB 890D[C0DF0000]      <1> 	mov	[readi.sector], ecx ; 0
  5383                              <1> mget_r_4:	
  5384 0000B9C1 89D8                <1> 	mov	eax, ebx ; file offset
  5385 0000B9C3 668B0D[C4DF0000]    <1> 	mov	cx, [readi.bpc]
  5386 0000B9CA 41                  <1> 	inc	ecx ; <= 65536
  5387 0000B9CB 29D2                <1> 	sub	edx, edx
  5388 0000B9CD F7F1                <1> 	div	ecx
  5389 0000B9CF 8B3D[CCDF0000]      <1> 	mov	edi, [readi.c_index] ; previous cluster index
  5390                              <1> mget_r_5:
  5391 0000B9D5 A3[CCDF0000]        <1> 	mov	[readi.c_index], eax ; cluster index
  5392                              <1> 	; edx = byte offset in cluster (<= 65535)
  5393 0000B9DA 668915[C6DF0000]    <1> 	mov	[readi.offset], dx
  5394 0000B9E1 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5395 0000B9E5 8815[BFDF0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5396                              <1> 
  5397 0000B9EB 89C1                <1> 	mov	ecx, eax ; current cluster index
  5398 0000B9ED A1[D0DF0000]        <1> 	mov	eax, [readi.fclust]
  5399 0000B9F2 09C9                <1> 	or	ecx, ecx ; cluster index
  5400 0000B9F4 741F                <1> 	jz	short mget_r_7
  5401                              <1> 
  5402 0000B9F6 39CF                <1> 	cmp	edi, ecx
  5403 0000B9F8 7710                <1> 	ja	short mget_r_6 ; old cluster index is higher
  5404 0000B9FA 8B15[C8DF0000]      <1> 	mov	edx, [readi.cluster]
  5405 0000BA00 21D2                <1> 	and	edx, edx
  5406 0000BA02 7406                <1> 	jz	short mget_r_6
  5407                              <1> 	; valid 'readi' parameters (*)
  5408 0000BA04 89D0                <1> 	mov	eax, edx
  5409 0000BA06 29F9                <1> 	sub	ecx, edi
  5410 0000BA08 7410                <1> 	jz	short mget_r_8
  5411                              <1> mget_r_6:
  5412                              <1> 	; EAX = Beginning cluster
  5413                              <1> 	; EDX = Sector index in disk/file section
  5414                              <1> 	;	(Only for SINGLIX file system!)
  5415                              <1> 	; ECX = Cluster sequence number after the beginning cluster
  5416                              <1> 	; ESI = Logical DOS Drive Description Table address
  5417 0000BA0A E846E5FFFF          <1> 	call	get_cluster_by_index
  5418 0000BA0F 0F8272E6FFFF        <1> 	jc	error
  5419                              <1> 	; EAX = Cluster number		
  5420                              <1> mget_r_7:
  5421 0000BA15 A3[C8DF0000]        <1> 	mov	[readi.cluster], eax ; FDT number for Singlix File System
  5422                              <1> mget_r_8:
  5423 0000BA1A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5424 0000BA1E 764E                <1> 	jna	short  mget_r_13
  5425                              <1> 
  5426 0000BA20 83E802              <1> 	sub	eax, 2
  5427 0000BA23 0FB615[BEDF0000]    <1> 	movzx	edx, byte [readi.spc]
  5428 0000BA2A F7E2                <1> 	mul	edx
  5429                              <1> 
  5430 0000BA2C 034668              <1> 	add	eax, [esi+LD_DATABegin]
  5431 0000BA2F 8A15[BFDF0000]      <1> 	mov	dl, [readi.s_index]
  5432 0000BA35 01D0                <1> 	add	eax, edx
  5433                              <1> msget_r_9:
  5434                              <1> 	; eax = logical sector number
  5435 0000BA37 803D[BCDF0000]00    <1> 	cmp	byte [readi.valid], 0
  5436 0000BA3E 7608                <1> 	jna	short mget_r_10
  5437 0000BA40 3B05[C0DF0000]      <1> 	cmp	eax, [readi.sector]
  5438 0000BA46 7425                <1> 	je	short mget_r_12 ; sector is already in 'readi' buffer
  5439                              <1> mget_r_10:
  5440 0000BA48 A3[C0DF0000]        <1> 	mov	[readi.sector], eax
  5441 0000BA4D BB[DDE30000]        <1> 	mov	ebx, readi_buffer ; buffer address
  5442 0000BA52 B901000000          <1> 	mov	ecx, 1
  5443                              <1> 	; 29/04/2016
  5444                              <1> 	;xor	dl, dl
  5445                              <1> 
  5446                              <1> 	; EAX = Logical sector number
  5447                              <1> 	; ECX = Sector count
  5448                              <1> 	; EBX = Buffer address
  5449                              <1> 	; (EDX = 0)
  5450                              <1> 	; ESI = Logical DOS drive description table address	
  5451                              <1> 
  5452 0000BA57 E8A6030000          <1> 	call	disk_read
  5453 0000BA5C 730A                <1> 	jnc	short mget_r_11
  5454                              <1> 
  5455 0000BA5E B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  5456 0000BA63 E91FE6FFFF          <1> 	jmp	error
  5457                              <1> mget_r_11:
  5458 0000BA68 A1[C0DF0000]        <1> 	mov	eax, [readi.sector]
  5459                              <1> mget_r_12:
  5460 0000BA6D C3                  <1> 	retn
  5461                              <1> mget_r_13:
  5462                              <1> 	; EAX = FDT number
  5463                              <1> 	; EDX = Sector index from FDT sector (0,1,2,3,4...)
  5464 0000BA6E 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  5465 0000BA6F 8915[D4DF0000]      <1> 	mov	[readi.fs_index], edx
  5466 0000BA75 01D0                <1> 	add	eax, edx
  5467 0000BA77 EBBE                <1> 	jmp	short msget_r_9
  5468                              <1> 
  5469                              <1> trans_addr_r:
  5470                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  5471                              <1> 	; Translate virtual address to physical address 
  5472                              <1> 	; for reading from user's memory space
  5473                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5474                              <1> 
  5475 0000BA79 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  5476 0000BA7B EB04                <1> 	jmp 	short trans_addr_rw
  5477                              <1> 
  5478                              <1> trans_addr_w:
  5479                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5480                              <1> 	; Translate virtual address to physical address 
  5481                              <1> 	; for writing to user's memory space
  5482                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5483                              <1> 	
  5484 0000BA7D 29D2                <1> 	sub	edx, edx
  5485 0000BA7F FEC2                <1> 	inc	dl ; 1 (write access sign)
  5486                              <1> trans_addr_rw:
  5487 0000BA81 50                  <1> 	push	eax
  5488 0000BA82 53                  <1> 	push	ebx
  5489 0000BA83 52                  <1> 	push 	edx ; r/w sign (in DL)
  5490                              <1> 	;
  5491 0000BA84 8B1D[68E30000]      <1> 	mov	ebx, [u.base]
  5492 0000BA8A E89D7DFFFF          <1> 	call	get_physical_addr ; get physical address
  5493 0000BA8F 730A                <1> 	jnc	short passc_0
  5494 0000BA91 A3[9DE30000]        <1> 	mov	[u.error], eax
  5495                              <1> 	;pop	edx
  5496                              <1> 	;pop 	ebx
  5497                              <1> 	;pop	eax
  5498 0000BA96 E9ECE5FFFF          <1> 	jmp	error
  5499                              <1> passc_0:
  5500 0000BA9B F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page
  5501 0000BA9E 5A                  <1> 	pop	edx
  5502 0000BA9F 751C                <1> 	jnz	short passc_1
  5503                              <1> 	
  5504 0000BAA1 20D2                <1> 	and 	dl, dl
  5505 0000BAA3 7418                <1> 	jz	short passc_1
  5506                              <1> 	; read only (duplicated) page -must be copied to a new page-
  5507                              <1> 	; EBX = linear address
  5508 0000BAA5 51                  <1> 	push 	ecx
  5509 0000BAA6 E85E7AFFFF          <1> 	call 	copy_page
  5510 0000BAAB 59                  <1> 	pop	ecx
  5511 0000BAAC 721E                <1> 	jc	short passc_2
  5512 0000BAAE 50                  <1> 	push	eax ; physical address of the new/allocated page
  5513 0000BAAF E8A27CFFFF          <1> 	call	add_to_swap_queue	
  5514 0000BAB4 58                  <1> 	pop	eax
  5515 0000BAB5 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  5516                              <1> 	;mov 	ecx, PAGE_SIZE
  5517                              <1> 	;sub	ecx, ebx 
  5518 0000BABB 01D8                <1> 	add	eax, ebx  
  5519                              <1> passc_1: 
  5520 0000BABD A3[A9E30000]        <1> 	mov 	[u.pbase], eax ; physical address	
  5521 0000BAC2 66890D[ADE30000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  5522 0000BAC9 5B                  <1> 	pop	ebx
  5523 0000BACA 58                  <1> 	pop	eax
  5524 0000BACB C3                  <1> 	retn
  5525                              <1> passc_2:
  5526 0000BACC C705[9DE30000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
  5526 0000BAD4 0000                <1>
  5527                              <1> 	;pop 	ebx
  5528                              <1> 	;pop	eax
  5529 0000BAD6 E9ACE5FFFF          <1> 	jmp	error
  5530                              <1> 
  5531                              <1> sioreg: 
  5532                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5533                              <1> 	; 19/05/2015 - 25/07/2015 (Retro UNIX 386 v1)
  5534                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
  5535                              <1> 	; INPUTS -> 
  5536                              <1> 	;     EBX = system buffer (data) address (r5)
  5537                              <1> 	;     [u.fofp] = pointer to file offset pointer
  5538                              <1> 	;     [u.base] = virtual address of the user buffer
  5539                              <1> 	;     [u.pbase] = physical address of the user buffer
  5540                              <1> 	;     [u.count] = byte count
  5541                              <1> 	;     [u.pcount] = byte count within page frame 			
  5542                              <1> 	; OUTPUTS -> 
  5543                              <1> 	;     ESI = user data offset (r1)
  5544                              <1> 	;     EDI = system (I/O) buffer offset (r2)
  5545                              <1> 	;     ECX = byte count (r3)
  5546                              <1> 	;     EAX = remain bytes after byte count within page frame
  5547                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
  5548                              <1>         ;
  5549                              <1> 	; ((Modified registers:  EDX))
  5550                              <1>  
  5551 0000BADB 8B35[58E30000]      <1>         mov     esi, [u.fofp]
  5552 0000BAE1 8B3E                <1>         mov     edi, [esi]
  5553 0000BAE3 89F9                <1> 	mov	ecx, edi
  5554 0000BAE5 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  5555 0000BAEB 81E7FF010000        <1> 	and	edi, 1FFh
  5556 0000BAF1 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  5557 0000BAF3 F7D9                <1> 	neg	ecx
  5558 0000BAF5 3B0D[6CE30000]      <1> 	cmp	ecx, [u.count]
  5559 0000BAFB 7606                <1> 	jna	short sioreg_0
  5560 0000BAFD 8B0D[6CE30000]      <1> 	mov	ecx, [u.count]
  5561                              <1> sioreg_0:
  5562 0000BB03 803D[AFE30000]00    <1> 	cmp	byte [u.kcall], 0 
  5563 0000BB0A 7613                <1> 	jna	short sioreg_1
  5564                              <1> 	 ; the caller is 'mkdir' or 'namei'
  5565 0000BB0C A1[68E30000]        <1> 	mov	eax, [u.base]
  5566 0000BB11 A3[A9E30000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  5567 0000BB16 66890D[ADE30000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  5568 0000BB1D EB0B                <1> 	jmp	short sioreg_2
  5569                              <1> sioreg_1:
  5570 0000BB1F 0FB715[ADE30000]    <1> 	movzx	edx, word [u.pcount]
  5571 0000BB26 39D1                <1> 	cmp	ecx, edx	
  5572 0000BB28 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  5573                              <1> sioreg_2: ; 2:
  5574 0000BB2A 31C0                <1> 	xor 	eax, eax
  5575                              <1> sioreg_3:
  5576 0000BB2C 010D[70E30000]      <1> 	add 	[u.nread], ecx
  5577 0000BB32 290D[6CE30000]      <1> 	sub 	[u.count], ecx
  5578 0000BB38 010D[68E30000]      <1> 	add 	[u.base], ecx
  5579 0000BB3E 010E                <1>         add 	[esi], ecx 
  5580 0000BB40 8B35[A9E30000]      <1> 	mov	esi, [u.pbase]
  5581 0000BB46 66290D[ADE30000]    <1> 	sub	[u.pcount], cx
  5582 0000BB4D 010D[A9E30000]      <1> 	add	[u.pbase], ecx
  5583 0000BB53 C3                  <1>         retn
  5584                              <1> sioreg_4:
  5585                              <1> 	; transfer count > [u.pcount] 
  5586                              <1> 	; (ecx > edx)
  5587 0000BB54 89C8                <1> 	mov	eax, ecx
  5588 0000BB56 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  5589 0000BB58 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  5590 0000BB5A EBD0                <1> 	jmp	short sioreg_3
  5591                              <1> 
  5592                              <1> tswitch: ; Retro UNIX 386 v1
  5593                              <1> tswap:
  5594                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0)
  5595                              <1> 	; 10/05/2015 - 01/09/2015 (Retro UNIX 386 v1)
  5596                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  5597                              <1> 	; time out swap, called when a user times out.
  5598                              <1> 	; the user is put on the low priority queue.
  5599                              <1> 	; This is done by making a link from the last user
  5600                              <1> 	; on the low priority queue to him via a call to 'putlu'.
  5601                              <1> 	; then he is swapped out.
  5602                              <1> 
  5603                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 21/05/2016 **
  5604                              <1> 	;     * when a high priority (event) process will be stopped
  5605                              <1> 	;	(swapped out, swithched out/off), 'tswap/tswitch' will
  5606                              <1> 	;	not add it to a run queue. 
  5607                              <1> 	;	/// What for: Process may be already in a run queue, 
  5608                              <1> 	;	it is unspeficied state because process might be started
  5609                              <1> 	;	by a timer event which does not regard previous priority
  5610                              <1> 	;	level and run queue of the process (for fast executing!).
  5611                              <1> 	;	After the 'run for event', process will be sequenced
  5612                              <1> 	;	to run by it's actual run queue. ///
  5613                              <1> 	;
  5614                              <1> 	; Retro UNIX 386 v1 modification ->
  5615                              <1> 	;       swap (software task switch) is performed by changing
  5616                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  5617                              <1> 	;	as in Retro UNIX 8086 v1.
  5618                              <1> 	;
  5619                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5620                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5621                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5622                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5623                              <1> 	;	compatibles was using 1MB segmented memory 
  5624                              <1> 	;	in 8086/8088 times.
  5625                              <1> 	;
  5626                              <1> 	; INPUTS ->
  5627                              <1> 	;    u.uno - users process number
  5628                              <1> 	;    runq+4 - lowest priority queue
  5629                              <1> 	; OUTPUTS ->
  5630                              <1> 	;    r0 - users process number
  5631                              <1> 	;    r2 - lowest priority queue address
  5632                              <1> 	;
  5633                              <1> 	; ((AX = R0, BX = R2)) output
  5634                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
  5635                              <1> 	;
  5636                              <1> 
  5637                              <1> 	NOTE:
  5638                              <1> 	;* [u.pri] priority level is specified by run queue which is process 
  5639                              <1> 	;  comes to run from.
  5640                              <1> 	;* Initial [u.pri] is 1 ('normal/regular') for programs 
  5641                              <1> 	;  (which are launched by MainProg or 'sysexec'), it is changed
  5642                              <1> 	;  to 2 ('high') by timer event, if program uses 'systimer' system call.
  5643                              <1> 	;* Program (Process) also can change it's running priority 
  5644                              <1> 	;  from 1 to 0 or up to 2 by using 'syspri' system call; but,
  5645                              <1> 	;  if program selects priority level 2 (high) for running, next time 
  5646                              <1> 	;  it is reduced to 1 (normal/regular) because 'syspri' adds this
  5647                              <1> 	;  program to 'run for normal' queue while running duration is a bit
  5648                              <1> 	;  protected from swap/switch out immediate, behalf of other high 
  5649                              <1> 	;  priority process in sequence. Program (with high priority) will not 
  5650                              <1> 	;  be swapped/switched out (by timer event) before it's time quantum 
  5651                              <1> 	;  will be elapsed, but, this will be temporary if program is not using 
  5652                              <1> 	;  timer event function.	  			 	
  5653                              <1> 
  5654                              <1> 	;For example:
  5655                              <1> 	;If a process frequently gets a timer event, it runs at high priority
  5656                              <1> 	;level but when it returns from running it returns to actual run queue,
  5657                              <1> 	;not to 'run for event' queue again.
  5658                              <1> 	;'tswap' will not change the sequence at return/stop(swap out) stage.
  5659                              <1> 	;But if priority level not high (=2, 'run for event'), 'tswap/tswitch'
  5660                              <1> 	;will add the stopping process to relevant run queue according to
  5661                              <1> 	;[u.pri] priority level.
  5662                              <1> 
  5663                              <1> 	; 21/05/2016
  5664 0000BB5C 803D[8BE30000]02    <1> 	cmp	byte [u.pri], 2	; high priority (run for event) ?
  5665 0000BB63 731A                <1> 	jnb	short swap      ; yes, do not add process to the run queue   
  5666                              <1> 	
  5667 0000BB65 BB[38E30000]        <1> 	mov	ebx, runq+2 	; 'runq_normal' ; normal/regular priority
  5668 0000BB6A 803D[8BE30000]00    <1> 	cmp	byte [u.pri], 0
  5669 0000BB71 7702                <1> 	ja	short tswap_1	; normal priority
  5670                              <1> 
  5671 0000BB73 43                  <1> 	inc	ebx
  5672 0000BB74 43                  <1> 	inc	ebx		; runq+4, 'runq_background', low priority
  5673                              <1> tswap_1:
  5674 0000BB75 A0[97E30000]        <1> 	mov 	al, [u.uno]
  5675                              <1> 	       	; movb u.uno,r1 / move users process number to r1
  5676                              <1> 		; mov  $runq+4,r2 
  5677                              <1> 			; / move lowest priority queue address to r2
  5678                              <1>       	; ebx = run queue
  5679 0000BB7A E8F0000000          <1> 	call 	putlu
  5680                              <1> 		; jsr r0,putlu / create link from last user on Q to 
  5681                              <1> 		             ; / u.uno's user
  5682                              <1> 
  5683                              <1> switch: ; Retro UNIX 386 v1
  5684                              <1> swap:
  5685                              <1> 	; 21/05/2016
  5686                              <1> 	; 20/05/2016
  5687                              <1> 	; 02/05/2016
  5688                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5689                              <1> 	; 10/05/2015 - 02/09/2015 (Retro UNIX 386 v1)
  5690                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5691                              <1> 	;
  5692                              <1> 	; 'swap' is routine that controls the swapping of processes
  5693                              <1> 	; in and out of core.
  5694                              <1> 	;
  5695                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 20/05/2016 **
  5696                              <1> 	;     * 3 different priority level is applied 
  5697                              <1> 	;	(just as original unix v1)
  5698                              <1> 	;	1) high priority (event) run queue, 'runq_event'
  5699                              <1> 	;	2) normal priority (regular) run queue, 'runq_normal'
  5700                              <1> 	;	3) low priority (background) run queue, 'runq_backgroud'
  5701                              <1> 	;	'swap' code will run a process which has max. priority
  5702                              <1>         ;       (for earliest event at first)
  5703                              <1> 	;
  5704                              <1> 	; Retro UNIX 386 v1 modification ->
  5705                              <1> 	;       swap (software task switch) is performed by changing
  5706                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  5707                              <1> 	;	as in Retro UNIX 8086 v1.
  5708                              <1> 	;
  5709                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5710                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5711                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5712                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5713                              <1> 	;	compatibles was using 1MB segmented memory 
  5714                              <1> 	;	in 8086/8088 times.
  5715                              <1> 	;
  5716                              <1> 	; INPUTS ->
  5717                              <1> 	;    runq table - contains processes to run.
  5718                              <1> 	;    p.link - contains next process in line to be run.
  5719                              <1> 	;    u.uno - process number of process in core	
  5720                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
  5721                              <1> 	; OUTPUTS ->
  5722                              <1> 	;    (original unix v1 -> present process to its disk block)
  5723                              <1> 	;    (original unix v1 -> new process into core -> 
  5724                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
  5725                              <1> 	;	   for new process)
  5726                              <1> 	;    u.quant = 3 (Time quantum for a process)
  5727                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
  5728                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
  5729                              <1> 	;	 for now, it will swap the process if there is not
  5730                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
  5731                              <1> 	;	 or will count down from 3 to 0 even if there is a
  5732                              <1> 	;        keyboard event locking due to repetitive key strokes.
  5733                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
  5734                              <1> 	;
  5735                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
  5736                              <1> 
  5737                              <1> 	;NOTE:
  5738                              <1> 	;High priority queue is the first for selecting a process to run.
  5739                              <1> 	;If there is not a process in high priority level run queue,
  5740                              <1> 	;a process in normal priority run queue will be selected
  5741                              <1> 	;or a proces in low priority run queue will be selected if normal
  5742                              <1> 	;priority level run queue is empty.
  5743                              <1> 	
  5744                              <1> 	; 21/05/2016 -(3 priority levels, 3 run queues)
  5745 0000BB7F BE[36E30000]        <1> 	mov	esi, runq ; 'runq_event' ; high priority, 'run for event'
  5746 0000BB84 C605[08E00000]03    <1> 	mov	byte [priority], 3 ; high priority + 1
  5747                              <1> swap_0: ; 1: / search runq table for highest priority process
  5748 0000BB8B 66AD                <1> 	lodsw  ; mov ax, [esi], add esi+2
  5749 0000BB8D 31DB                <1> 	xor	ebx, ebx ; 02/05/2016
  5750 0000BB8F 6621C0              <1> 	and 	ax, ax ; are there any processes to run in this Q entry
  5751 0000BB92 750E                <1> 	jnz	short swap_2 
  5752                              <1> 	; 21/05/2026
  5753                              <1> 	; runq_normal = runq+2, runq_background = runq+4
  5754 0000BB94 FE0D[08E00000]      <1> 	dec	byte [priority] ; 3 -> 3, 2 -> 1, 1-> 0
  5755 0000BB9A 75EF                <1> 	jnz	short swap_0	
  5756                              <1> 	;cmp	esi, runq+6  ; if zero compare address to end of table
  5757                              <1> 	;jb	short swap_0 ; if not at end, go back
  5758                              <1> swap_1:
  5759                              <1> 	; 02/05/2016
  5760                              <1> 	; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
  5761                              <1> 	; No user process to run...
  5762                              <1> 	; Run the kernel process... MainProg: Internal Command Interpreter  
  5763 0000BB9C FEC0                <1> 	inc	al ; mov al, 1  ; process number of MainProg
  5764 0000BB9E FEC3                <1> 	inc	bl ; mov bl, al ; 1
  5765 0000BBA0 EB1E                <1> 	jmp	short swap_4
  5766                              <1> swap_2:
  5767                              <1> 	; 21/05/2016
  5768 0000BBA2 FE0D[08E00000]      <1> 	dec	byte [priority] ; priority level of present user/process
  5769                              <1> 			        ; 0, 1, 2	   
  5770 0000BBA8 4E                  <1> 	dec	esi
  5771 0000BBA9 4E                  <1>         dec     esi
  5772                              <1> 	;
  5773 0000BBAA 88C3                <1> 	mov	bl, al
  5774 0000BBAC 38E0                <1> 	cmp	al, ah ; is there only 1 process in the queue to be run
  5775 0000BBAE 740A                <1> 	je	short swap_3 ; yes
  5776 0000BBB0 8AA3[ABE00000]      <1> 	mov	ah, [ebx+p.link-1] 
  5777 0000BBB6 8826                <1>        	mov	[esi], ah ; move next process in line into run queue
  5778 0000BBB8 EB06                <1> 	jmp	short swap_4
  5779                              <1> swap_3: 
  5780 0000BBBA 6631D2              <1> 	xor	dx, dx
  5781 0000BBBD 668916              <1> 	mov	[esi], dx ; zero the entry; no processes on the Q
  5782                              <1> swap_4: 
  5783 0000BBC0 8A25[97E30000]      <1> 	mov 	ah, [u.uno]
  5784 0000BBC6 38C4                <1> 	cmp	ah, al ;is this process the same as the process in core?
  5785 0000BBC8 743B                <1>        	je	short swap_8 ; yes, don't have to swap
  5786 0000BBCA 08E4                <1> 	or	ah, ah  ; is the process # = 0
  5787 0000BBCC 740D                <1>        	jz	short swap_6 ; 'sysexit'
  5788 0000BBCE 8925[44E30000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  5789 0000BBD4 E834000000          <1> 	call	wswap   ; write out core to disk
  5790 0000BBD9 EB1C                <1> 	jmp 	short swap_7
  5791                              <1> swap_6:
  5792                              <1> 	; Deallocate memory pages belong to the process
  5793                              <1> 	; which is being terminated.
  5794                              <1> 	; (Retro UNIX 386 v1 modification !)
  5795                              <1> 	;
  5796 0000BBDB 53                  <1> 	push	ebx
  5797 0000BBDC A1[A1E30000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  5798 0000BBE1 8B1D[A5E30000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  5799 0000BBE7 E8AE76FFFF          <1> 	call	deallocate_page_dir
  5800 0000BBEC A1[98E30000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  5801 0000BBF1 E84377FFFF          <1> 	call	deallocate_page
  5802 0000BBF6 5B                  <1> 	pop	ebx
  5803                              <1> swap_7: 
  5804 0000BBF7 C0E302              <1> 	shl	bl, 2 ; * 4 
  5805 0000BBFA 8B83[C8E00000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  5806 0000BC00 E831000000          <1> 	call	rswap ; read new process into core
  5807                              <1> swap_8: 
  5808                              <1> 	; Retro UNIX  8086 v1 modification !
  5809 0000BC05 C605[8AE30000]04    <1> 	mov	byte [u.quant], time_count 
  5810 0000BC0C C3                  <1> 	retn
  5811                              <1> 
  5812                              <1> wswap:  ; < swap out, swap to disk >
  5813                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5814                              <1> 	; 09/05/2015 (Retro UNIX 386 v1)
  5815                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5816                              <1> 	; 'wswap' writes out the process that is in core onto its 
  5817                              <1> 	; appropriate disk area.
  5818                              <1> 	;
  5819                              <1> 	; Retro UNIX 386 v1 modification ->
  5820                              <1> 	;       User (u) structure content and the user's register content
  5821                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
  5822                              <1> 	;	saving 'u' structure and user registers for task switching).
  5823                              <1> 	;	u.usp - points to kernel stack address which contains
  5824                              <1> 	;		user's registers while entering system call.  
  5825                              <1> 	;	u.sp  - points to kernel stack address 
  5826                              <1> 	;		to return from system call -for IRET-.
  5827                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5828                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5829                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5830                              <1> 	;
  5831                              <1> 	; Retro UNIX 8086 v1 modification ->
  5832                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5833                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5834                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5835                              <1> 	;	compatibles was using 1MB segmented memory 
  5836                              <1> 	;	in 8086/8088 times.
  5837                              <1> 	;
  5838                              <1> 	; INPUTS ->
  5839                              <1> 	;    u.break - points to end of program
  5840                              <1> 	;    u.usp - stack pointer at the moment of swap
  5841                              <1> 	;    core - beginning of process program		
  5842                              <1> 	;    ecore - end of core 	
  5843                              <1> 	;    user - start of user parameter area		
  5844                              <1> 	;    u.uno - user process number	
  5845                              <1> 	;    p.dska - holds block number of process	
  5846                              <1> 	; OUTPUTS ->
  5847                              <1> 	;    swp I/O queue
  5848                              <1> 	;    p.break - negative word count of process 
  5849                              <1> 	;    r1 - process disk address	
  5850                              <1> 	;    r2 - negative word count
  5851                              <1> 	;
  5852                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5853                              <1> 	;
  5854                              <1> 	; INPUTS ->
  5855                              <1> 	;    u.uno - process number (to be swapped out)
  5856                              <1> 	; OUTPUTS ->
  5857                              <1> 	;    none
  5858                              <1> 	;
  5859                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
  5860                              <1> 	;
  5861 0000BC0D 8B3D[98E30000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  5862 0000BC13 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5863 0000BC18 BE[40E30000]        <1> 	mov	esi, user ; active user (u) structure	
  5864 0000BC1D F3A5                <1> 	rep	movsd
  5865                              <1> 	;
  5866 0000BC1F 8B35[44E30000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  5867                              <1> 			     ;      points to user registers)
  5868 0000BC25 8B0D[40E30000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5869                              <1> 			     ; (for IRET)
  5870                              <1> 			     ; [u.sp] -> EIP (user)
  5871                              <1> 			     ; [u.sp+4]-> CS (user)
  5872                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5873                              <1> 			     ; [u.sp+12] -> ESP (user)
  5874                              <1> 			     ; [u.sp+16] -> SS (user)	
  5875 0000BC2B 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  5876 0000BC2D 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5877                              <1> 			     ; (for IRET) 	
  5878 0000BC30 C1E902              <1> 	shr	ecx, 2	     		
  5879 0000BC33 F3A5                <1> 	rep	movsd
  5880 0000BC35 C3                  <1> 	retn
  5881                              <1> 
  5882                              <1> rswap:  ; < swap in, swap from disk >
  5883                              <1> 	; 21/05/2016
  5884                              <1> 	; 03/05/2016
  5885                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5886                              <1> 	; 09/05/2015 - 15/09/2015 (Retro UNIX 386 v1)
  5887                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5888                              <1> 	; 'rswap' reads a process whose number is in r1, 
  5889                              <1> 	; from disk into core.
  5890                              <1> 	;
  5891                              <1> 	; Retro UNIX 386 v1 modification ->
  5892                              <1> 	;       User (u) structure content and the user's register content
  5893                              <1> 	;	will be restored from process's/user's UPAGE (a page for
  5894                              <1> 	;	saving 'u' structure and user registers for task switching).
  5895                              <1> 	;	u.usp - points to kernel stack address which contains
  5896                              <1> 	;		user's registers while entering system call.  
  5897                              <1> 	;	u.sp  - points to kernel stack address 
  5898                              <1> 	;		to return from system call -for IRET-.
  5899                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5900                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5901                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5902                              <1> 	;
  5903                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5904                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5905                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5906                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5907                              <1> 	;	compatibles was using 1MB segmented memory 
  5908                              <1> 	;	in 8086/8088 times.
  5909                              <1> 	;
  5910                              <1> 	; INPUTS ->
  5911                              <1> 	;    r1 - process number of process to be read in
  5912                              <1> 	;    p.break - negative of word count of process 
  5913                              <1> 	;    p.dska - disk address of the process		
  5914                              <1> 	;    u.emt - determines handling of emt's 	
  5915                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5916                              <1> 	; OUTPUTS ->
  5917                              <1> 	;    8 = (u.ilgins)
  5918                              <1> 	;    24 = (u.emt)
  5919                              <1> 	;    swp - bit 10 is set to indicate read 
  5920                              <1> 	;		(bit 15=0 when reading is done)	
  5921                              <1> 	;    swp+2 - disk block address
  5922                              <1> 	;    swp+4 - negative word count 	
  5923                              <1> 	;      ((swp+6 - address of user structure)) 
  5924                              <1> 	;
  5925                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5926                              <1> 	;
  5927                              <1> 	; INPUTS ->
  5928                              <1> 	;    AL	- new process number (to be swapped in)	 
  5929                              <1> 	; OUTPUTS ->
  5930                              <1> 	;    none
  5931                              <1> 	;
  5932                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
  5933                              <1> 	;
  5934                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
  5935 0000BC36 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  5936 0000BC38 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5937 0000BC3D BF[40E30000]        <1> 	mov	edi, user ; active user (u) structure	
  5938 0000BC42 F3A5                <1> 	rep	movsd
  5939 0000BC44 58                  <1> 	pop	eax	; 'rswap' return address
  5940                              <1> 	; 
  5941                              <1> 	;; 21/05/2016
  5942 0000BC45 8A0D[08E00000]      <1> 	mov	cl, [priority]
  5943 0000BC4B 880D[8BE30000]      <1> 	mov	[u.pri], cl  ; running priority level 
  5944                              <1> 			     ; (specifies run queue which is 
  5945                              <1> 			     ; process comes from)
  5946                              <1> 	;cli
  5947 0000BC51 8B3D[44E30000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  5948                              <1> 			     ;     points to user registers)
  5949 0000BC57 8B0D[40E30000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5950                              <1> 			     ; (for IRET)
  5951                              <1> 			     ; [u.sp] -> EIP (user)
  5952                              <1> 			     ; [u.sp+4]-> CS (user)
  5953                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5954                              <1> 			     ; [u.sp+12] -> ESP (user)
  5955                              <1> 			     ; [u.sp+16] -> SS (user)		
  5956 0000BC5D 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  5957 0000BC5F 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5958                              <1> 			     ; (for IRET) 	
  5959 0000BC62 C1E902              <1> 	shr	ecx, 2	       		
  5960 0000BC65 F3A5                <1> 	rep	movsd
  5961 0000BC67 8B25[44E30000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
  5962                              <1> 	;sti
  5963 0000BC6D 50                  <1> 	push	eax	; 'rswap' return address
  5964 0000BC6E C3                  <1> 	retn
  5965                              <1> 
  5966                              <1> putlu: 
  5967                              <1> 	; 20/05/2016
  5968                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5969                              <1> 	; 10/05/2015 - 12/09/2015 (Retro UNIX 386 v1)
  5970                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  5971                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
  5972                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
  5973                              <1> 	; the last process on the queue to process in r1 by putting
  5974                              <1> 	; the process number in r1 into the last process's link.
  5975                              <1> 	;
  5976                              <1> 	; INPUTS ->
  5977                              <1> 	;    r1 - user process number
  5978                              <1> 	;    r2 - points to lowest priority queue 
  5979                              <1> 	;    p.dska - disk address of the process		
  5980                              <1> 	;    u.emt - determines handling of emt's 	
  5981                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5982                              <1> 	; OUTPUTS ->
  5983                              <1> 	;    r3 - process number of last process on the queue upon
  5984                              <1> 	;	  entering putlu
  5985                              <1> 	;    p.link-1 + r3 - process number in r1
  5986                              <1> 	;    r2 - points to lowest priority queue
  5987                              <1> 	;
  5988                              <1> 	; ((Modified registers: EDX, EBX)) 
  5989                              <1> 	;
  5990                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
  5991                              <1> 
  5992                              <1> 	; EBX = r2
  5993                              <1> 	; EAX = r1 (AL=r1b)
  5994                              <1> 
  5995                              <1> 	; 20/05/2016
  5996                              <1> 	; AL = process number (1 to 16) // Retro UNIX 8086, 386 v1 // 
  5997                              <1> 	;     (max. 16 processes available for current kernel version) 
  5998                              <1> 	; EBX = run queue address ; 20/05/2016 (TRDOS 386)
  5999                              <1> 		; which is one of following addresses:
  6000                              <1> 		;  1) 'runq_event' high priority run queue	 	
  6001                              <1> 		;  2) 'runq_normal' normal/regular priority run queue
  6002                              <1> 		;  3) 'runq_background' low priority run queue
  6003                              <1> 
  6004                              <1> 	;mov	ebx, runq
  6005 0000BC6F 0FB613              <1> 	movzx  	edx, byte [ebx]
  6006 0000BC72 43                  <1> 	inc	ebx
  6007 0000BC73 20D2                <1> 	and	dl, dl
  6008                              <1> 		; tstb (r2)+ / is queue empty?
  6009 0000BC75 740A                <1>        	jz	short putlu_1
  6010                              <1> 		; beq 1f / yes, branch
  6011 0000BC77 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
  6012                              <1> 		; movb (r2),r3 / no, save the "last user" process number
  6013                              <1> 			     ; / in r3
  6014 0000BC79 8882[ABE00000]      <1>        	mov	[edx+p.link-1], al
  6015                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
  6016                              <1> 			     ; / "last users" link
  6017 0000BC7F EB03                <1> 	jmp	short putlu_2
  6018                              <1> 		; br 2f /
  6019                              <1> putlu_1: ; 1:
  6020 0000BC81 8843FF              <1> 	mov	[ebx-1], al
  6021                              <1>        		; movb r1,-1(r2) / user is only user; 
  6022                              <1> 			    ; / put process no. at beginning and at end
  6023                              <1> putlu_2: ; 2: 
  6024 0000BC84 8803                <1> 	mov	[ebx], al
  6025                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
  6026                              <1> 			     ; / on the queue
  6027 0000BC86 88C2                <1> 	mov	dl, al
  6028 0000BC88 88B2[ABE00000]      <1>         mov     [edx+p.link-1], dh ; 0
  6029                              <1> 		; dec r2 / restore r2
  6030 0000BC8E C3                  <1>         retn
  6031                              <1> 		; rts r0
  6032                              <1> sysver:
  6033                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6034 0000BC8F C705[48E30000]0002- <1> 	mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  6034 0000BC97 0000                <1>
  6035 0000BC99 E909E4FFFF          <1> 	jmp	sysret
  6036                              <1> 
  6037                              <1> sysreserved1:
  6038                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  6039                              <1> 	; // name and contect will be changed later //
  6040 0000BC9E C705[48E30000]E007- <1> 	mov	dword [u.r0], 2016
  6040 0000BCA6 0000                <1>
  6041 0000BCA8 E9FAE3FFFF          <1> 	jmp	sysret
  6042                              <1> 
  6043                              <1> syspri: ; change running priority (of the process)
  6044                              <1> 	; 21/05/2016
  6045                              <1> 	; 20/05/2026 - TRDOS 386 (TRDOS v2.0)
  6046                              <1> 	; INPUT ->
  6047                              <1> 	;	BL = priority level
  6048                              <1> 	;	   0 = low running priority (running on background)
  6049                              <1> 	;	   1 = normal/regular priority (running as regular)
  6050                              <1> 	;	   2 = high/event priority (running for event)
  6051                              <1> 	;	   >2 = invalid, it will accepted as 2 (event)
  6052                              <1> 	;	   0FFh = get/return current running priority only	
  6053                              <1> 	; OUTPUT -> 	
  6054                              <1> 	;	* if current [u.pri] < 2
  6055                              <1> 	;	  if BL input < 0FFh ->
  6056                              <1> 	;	     [u.pri] is updated as in BL input (0,1,2)
  6057                              <1> 	;	  if BL input = 0FFh -> AL = [u.pri] (current)
  6058                              <1> 	;	      
  6059                              <1> 	;	* if current [u.pri] = 2
  6060                              <1> 	;	  if BL input < 0FFh -> cf = 1 & AL = 2
  6061                              <1> 	;	  if BL input = 0FFh -> cf = 0 & AL = 2  
  6062                              <1> 	;	
  6063                              <1> 	;	NOTE: 	
  6064                              <1> 	;	If [u.pri] = 2, it can not be changed to 1 or 0;
  6065                              <1> 	;	because, run queue of the running process is unspecified
  6066                              <1> 	;	at this	stage. Process might be started by a timer event
  6067                              <1> 	;	or priority might be changed to high by previous
  6068                              <1> 	;	'syspri' system	call. In both cases, the process is in
  6069                              <1> 	;	'runq_normal' or 'runq_background' queue.
  6070                              <1> 	;	As result of this fact, when the [u.quant] time quantum
  6071                              <1> 	;	of the process is elapsed or 'sysrele' system call is
  6072                              <1> 	;	instructed by the process, 'tswap' ('tswitch') procedure
  6073                              <1> 	;	will be called (to 'swap' or 'switch' out the procedure)
  6074                              <1> 	;	and it will not call 'putlu' to add the (stopping)
  6075                              <1> 	;	process to relevant run queue when [u.pri] = 2.
  6076                              <1> 	;	(Otherwise, it would be possible to add process to
  6077                              <1> 	;	a run queue while it is already in a run queue, wrongly.)
  6078                              <1>   	;
  6079                              <1> 	;	If [u.pri]< 2, 'tswap/tswitch' procedure will call 
  6080                              <1> 	;	'putlu' to add process to relevant run queue
  6081                              <1> 	;	according to [u.pri] value. ('runq_normal' for 1, 
  6082                              <1> 	;	'runq_background' for 0).
  6083                              <1> 	;
  6084                              <1> 	;	If BL input >= 2 and < 0FFh while [u.pri] < 2,
  6085                              <1> 	;	process will be added to 'runq_normal' queue and
  6086                              <1> 	;	[u.pri] will be set to 2. (in 'syspri' system call)
  6087                              <1> 	;
  6088                              <1> 
  6089 0000BCAD 29C0                <1> 	sub	eax, eax ; 0
  6090 0000BCAF A3[9DE30000]        <1> 	mov	[u.error], eax
  6091                              <1> 
  6092 0000BCB4 A0[8BE30000]        <1> 	mov	al, [u.pri]
  6093 0000BCB9 A3[48E30000]        <1> 	mov	[u.r0], eax
  6094                              <1> 
  6095 0000BCBE FEC3                <1> 	inc	bl
  6096 0000BCC0 0F84E1E3FFFF        <1> 	jz	sysret ; 0FFh -> 0, get priority level
  6097                              <1> 	
  6098 0000BCC6 3C02                <1> 	cmp	al, 2
  6099 0000BCC8 0F83B9E3FFFF        <1> 	jnb	error ; CF = 1 & AL = 2 (& last error = 0)
  6100                              <1> 
  6101 0000BCCE FECB                <1> 	dec	bl
  6102 0000BCD0 80FB02              <1> 	cmp	bl, 2
  6103 0000BCD3 7602                <1> 	jna	short syspri_1
  6104 0000BCD5 B302                <1> 	mov	bl, 2
  6105                              <1> syspri_1:
  6106 0000BCD7 881D[8BE30000]      <1> 	mov	[u.pri], bl
  6107 0000BCDD 80FB02              <1> 	cmp	bl, 2
  6108 0000BCE0 0F82C1E3FFFF        <1>         jb      sysret
  6109                              <1> 
  6110                              <1> 	; here...
  6111                              <1> 	; Priority of current process has been changed to high
  6112                              <1> 	; ('run for event') but current process will be added to
  6113                              <1> 	; 'run as normal' queue. ('run for event' high priority
  6114                              <1> 	; queue is under control of timer -& RTC- interrupt only!) 
  6115                              <1> 	;
  6116                              <1> 	; (Otherwise, process can fall into black hole!
  6117                              <1> 	; e.g. if it is not in waiting list and it has not got 
  6118                              <1> 	; a timer event and it is not in a run queue!
  6119                              <1> 	; Because, when [u.pri] is 2, 'tswap/tswitch' will not 
  6120                              <1> 	; add the stopping process to a run queue.)
  6121                              <1> 
  6122 0000BCE6 A0[97E30000]        <1> 	mov	al, [u.uno]
  6123 0000BCEB BB[38E30000]        <1> 	mov	ebx, runq_normal ; normal priority !
  6124                              <1> 				 ; [u.pri] is set to high
  6125                              <1> 				 ; but 'runq_event' queue is set
  6126                              <1> 				 ; only by the kernel's timer
  6127                              <1> 				 ; event function (timer interrupt). 
  6128 0000BCF0 E87AFFFFFF          <1> 	call	putlu
  6129 0000BCF5 E9ADE3FFFF          <1> 	jmp	sysret
  6130                              <1> 
  6131                              <1> cpass: ; / get next character from user area of core and put it in AL (r1)
  6132                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  6133                              <1> 	; 19/05/2015 - 18/10/2015 (Retro UNIX 386 v1)
  6134                              <1> 	; 14/08/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  6135                              <1> 	; INPUTS -> 
  6136                              <1> 	;     [u.base] = virtual address in user area
  6137                              <1> 	;     [u.count] = byte count (max.)
  6138                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
  6139                              <1> 	; OUTPUTS -> 
  6140                              <1> 	;     AL = the character which is pointed by [u.base]
  6141                              <1> 	;     zf = 1 -> transfer count has been completed	
  6142                              <1>         ;
  6143                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
  6144                              <1> 	;
  6145 0000BCFA 833D[6CE30000]00    <1> 	cmp 	dword [u.count], 0  ; have all the characters been transferred
  6146                              <1> 			    	    ; i.e., u.count, # of chars. left
  6147 0000BD01 763F                <1> 	jna	short cpass_3	    ; to be transferred = 0?) yes, branch
  6148 0000BD03 FF0D[6CE30000]      <1> 	dec	dword [u.count]	    ; no, decrement u.count
  6149                              <1>         ; 19/05/2015 
  6150                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
  6151                              <1> 	;		      to physical address
  6152 0000BD09 66833D[ADE30000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  6153                              <1> 			     ; 1-4095 --> use previous physical base address
  6154                              <1> 			     ; in [u.pbase]
  6155 0000BD11 770E                <1> 	ja	short cpass_1
  6156 0000BD13 833D[A5E30000]00    <1> 	cmp     dword [u.ppgdir], 0  ; is the caller os kernel
  6157 0000BD1A 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ?  (MainProg)
  6158 0000BD1C E858FDFFFF          <1> 	call	trans_addr_r
  6159                              <1> cpass_1:
  6160 0000BD21 66FF0D[ADE30000]    <1> 	dec	word [u.pcount]
  6161                              <1> cpass_2: 
  6162 0000BD28 8B15[A9E30000]      <1> 	mov	edx, [u.pbase]
  6163 0000BD2E 8A02                <1> 	mov	al, [edx]	; take the character pointed to 
  6164                              <1> 				; by u.base and put it in r1
  6165 0000BD30 FF05[70E30000]      <1> 	inc	dword [u.nread] ; increment no. of bytes transferred
  6166 0000BD36 FF05[68E30000]      <1> 	inc	dword [u.base]  ; increment the buffer address to point to the
  6167                              <1> 			        ; next byte
  6168 0000BD3C FF05[A9E30000]      <1> 	inc	dword [u.pbase]
  6169                              <1> cpass_3:
  6170 0000BD42 C3                  <1> 	retn
  6171                              <1> cpass_k:
  6172                              <1> 	; 02/07/2015
  6173                              <1> 	; The caller is os kernel 
  6174                              <1> 	; (get sysexec arguments from kernel's memory space)
  6175 0000BD43 8B1D[68E30000]      <1> 	mov	ebx, [u.base]
  6176 0000BD49 66C705[ADE30000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  6176 0000BD51 10                  <1>
  6177 0000BD52 891D[A9E30000]      <1> 	mov	[u.pbase], ebx
  6178 0000BD58 EBCE                <1> 	jmp	short cpass_2
  6179                              <1> 
  6180                              <1> transfer_to_user_buffer: ; fast transfer
  6181                              <1> 	; 27/05/2016
  6182                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6183                              <1> 	;
  6184                              <1> 	; INPUT ->
  6185                              <1> 	;	ESI = source address in system space
  6186                              <1> 	;	EDI = user's buffer address
  6187                              <1> 	;	ECX = transfer (byte) count
  6188                              <1> 	;	[u.pgdir] = user's page directory
  6189                              <1> 	; OUTPUT ->
  6190                              <1> 	;	ecx = actual transfer count
  6191                              <1> 	;	cf = 1 -> error
  6192                              <1> 	;	[u.count] = remain byte count
  6193                              <1> 	;
  6194                              <1> 	; Modified registers: eax, ecx
  6195                              <1> 	;
  6196                              <1> 
  6197 0000BD5A 21C9                <1> 	and	ecx, ecx
  6198 0000BD5C 743B                <1> 	jz	short ttub_4
  6199                              <1> 
  6200 0000BD5E 890D[6CE30000]      <1> 	mov	[u.count], ecx
  6201                              <1> 	
  6202 0000BD64 57                  <1> 	push	edi
  6203 0000BD65 56                  <1> 	push	esi
  6204 0000BD66 53                  <1> 	push	ebx
  6205 0000BD67 52                  <1> 	push	edx
  6206 0000BD68 51                  <1> 	push	ecx
  6207                              <1> 
  6208 0000BD69 89FB                <1> 	mov	ebx, edi
  6209 0000BD6B 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  6210                              <1> ttub_1:
  6211                              <1> 	; ebx = virtual (linear) address
  6212                              <1> 	; [u.pgdir] = user's page directory
  6213 0000BD71 E8BC7AFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6214 0000BD76 7222                <1> 	jc	short ttub_5
  6215                              <1> 	; eax = physical address 
  6216                              <1> 	; ecx = remain byte count in page (1-4096)
  6217 0000BD78 89C7                <1> 	mov	edi, eax
  6218 0000BD7A A1[6CE30000]        <1> 	mov	eax, [u.count]
  6219 0000BD7F 39C1                <1> 	cmp	ecx, eax
  6220 0000BD81 7602                <1> 	jna	short ttub_2
  6221 0000BD83 89C1                <1> 	mov	ecx, eax
  6222                              <1> ttub_2:	
  6223 0000BD85 29C8                <1> 	sub	eax, ecx
  6224 0000BD87 01CB                <1> 	add	ebx, ecx
  6225 0000BD89 F3A4                <1> 	rep	movsb
  6226 0000BD8B A3[6CE30000]        <1> 	mov	[u.count], eax
  6227 0000BD90 09C0                <1> 	or	eax, eax
  6228 0000BD92 75DD                <1> 	jnz	short ttub_1
  6229                              <1> ttub_retn:
  6230                              <1> tfub_retn:
  6231 0000BD94 59                  <1> 	pop	ecx ; transfer count = actual transfer count
  6232                              <1> ttub_3:
  6233 0000BD95 5A                  <1> 	pop	edx
  6234 0000BD96 5B                  <1> 	pop	ebx
  6235 0000BD97 5E                  <1> 	pop	esi
  6236 0000BD98 5F                  <1> 	pop	edi
  6237                              <1> ttub_4:
  6238 0000BD99 C3                  <1> 	retn
  6239                              <1> ttub_5:
  6240 0000BD9A 59                  <1> 	pop	ecx
  6241 0000BD9B 2B0D[6CE30000]      <1> 	sub	ecx, [u.count] ; actual transfer count
  6242 0000BDA1 F9                  <1> 	stc
  6243 0000BDA2 EBF1                <1> 	jmp	short ttub_3
  6244                              <1> 
  6245                              <1> transfer_from_user_buffer: ; fast transfer
  6246                              <1> 	; 27/05/2016
  6247                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6248                              <1> 	;
  6249                              <1> 	; INPUT ->
  6250                              <1> 	;	ESI = user's buffer address
  6251                              <1> 	;	EDI = destination address in system space
  6252                              <1> 	;	ECX = transfer (byte) count
  6253                              <1> 	;	[u.pgdir] = user's page directory
  6254                              <1> 	; OUTPUT ->
  6255                              <1> 	;	ecx = actual transfer count
  6256                              <1> 	;	cf = 1 -> error
  6257                              <1> 	;	[u.count] = remain byte count
  6258                              <1> 	;
  6259                              <1> 	; Modified registers: eax, ecx
  6260                              <1> 	;
  6261                              <1> 
  6262 0000BDA4 21C9                <1> 	and	ecx, ecx
  6263                              <1> 	;jz	short tfub_4
  6264 0000BDA6 74F1                <1> 	jz	short ttub_4
  6265                              <1> 
  6266 0000BDA8 890D[6CE30000]      <1> 	mov	[u.count], ecx
  6267                              <1> 	
  6268 0000BDAE 57                  <1> 	push	edi
  6269 0000BDAF 56                  <1> 	push	esi
  6270 0000BDB0 53                  <1> 	push	ebx
  6271 0000BDB1 52                  <1> 	push	edx
  6272 0000BDB2 51                  <1> 	push	ecx
  6273                              <1> 
  6274 0000BDB3 89F3                <1> 	mov	ebx, esi
  6275 0000BDB5 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  6276                              <1> tfub_1:
  6277                              <1> 	; ebx = virtual (linear) address
  6278                              <1> 	; [u.pgdir] = user's page directory
  6279 0000BDBB E8727AFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6280                              <1> 	;jc	short tfub_5
  6281 0000BDC0 72D8                <1> 	jc	short ttub_5
  6282                              <1> 	; eax = physical address 
  6283                              <1> 	; ecx = remain byte count in page (1-4096)
  6284 0000BDC2 89C6                <1> 	mov	esi, eax
  6285 0000BDC4 A1[6CE30000]        <1> 	mov	eax, [u.count]
  6286 0000BDC9 39C1                <1> 	cmp	ecx, eax
  6287 0000BDCB 7602                <1> 	jna	short tfub_2
  6288 0000BDCD 89C1                <1> 	mov	ecx, eax
  6289                              <1> tfub_2:	
  6290 0000BDCF 29C8                <1> 	sub	eax, ecx
  6291 0000BDD1 01CB                <1> 	add	ebx, ecx
  6292 0000BDD3 F3A4                <1> 	rep	movsb
  6293 0000BDD5 A3[6CE30000]        <1> 	mov	[u.count], eax
  6294 0000BDDA 09C0                <1> 	or	eax, eax
  6295 0000BDDC 75DD                <1> 	jnz	short tfub_1
  6296                              <1> 
  6297 0000BDDE EBB4                <1> 	jmp	short tfub_retn
  6298                              <1> 
  6299                              <1> ;tfub_retn:
  6300                              <1> ;	pop	ecx ; transfer count = actual transfer count
  6301                              <1> ;tfub_3:
  6302                              <1> ;	pop	edx
  6303                              <1> ;	pop	ebx
  6304                              <1> ;	pop	esi
  6305                              <1> ;	pop	edi
  6306                              <1> ;tfub_4:
  6307                              <1> ;	retn
  6308                              <1> ;tfub_5:
  6309                              <1> ;	pop	ecx
  6310                              <1> ;	sub	ecx, [u.count] ; actual transfer count
  6311                              <1> ;	stc
  6312                              <1> ;	jmp	short tfub_3
  6313                              <1> 	
  6314                              <1> ; temporary - 24/01/2016
  6315                              <1> 
  6316                              <1> iget:
  6317 0000BDE0 C3                  <1> 	retn
  6318                              <1> poke:
  6319 0000BDE1 C3                  <1> 	retn
  6320                              <1> isintr:
  6321 0000BDE2 C3                  <1> 	retn
  6322                              <1> writei:
  6323 0000BDE3 C3                  <1> 	retn
  6324                              <1> iopen:
  6325 0000BDE4 C3                  <1> 	retn
  6326                              <1> iclose:
  6327 0000BDE5 C3                  <1> 	retn
  6328                              <1> itrunc:
  6329 0000BDE6 C3                  <1> 	retn
  6330                              <1> setimod:
  6331 0000BDE7 C3                  <1> 	retn
  6332                              <1> ottyp:
  6333 0000BDE8 C3                  <1> 	retn
  6334                              <1> cttyp:
  6335 0000BDE9 C3                  <1> 	retn
  6336                              <1> sndc:
  6337 0000BDEA C3                  <1> 	retn
  6338                              <1> access:
  6339 0000BDEB C3                  <1> 	retn
  6340                              <1> passc:
  6341 0000BDEC C3                  <1> 	retn
  6342                              <1> epoch:
  6343 0000BDED C3                  <1> 	retn
  6344                              <1> set_date_time:
  6345 0000BDEE C3                  <1> 	retn
  6346                              <1> imap:
  6347 0000BDEF C3                  <1> 	retn
  6348                              <1> diskio:
  6349 0000BDF0 C3                  <1> 	retn
  6350                              <1> idle:
  6351 0000BDF1 C3                  <1> 	retn
  6352                              <1> sleep:
  6353 0000BDF2 C3                  <1> 	retn
  1883                                  %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 0000BDF3 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    20 0000BDF7 777B                <1>         ja      short lba_write
    21                              <1> 
    22                              <1> chs_write:
    23                              <1> 	; 25/02/2016
    24                              <1> 	; 23/02/2016
    25 0000BDF9 C605[41DC0000]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    26 0000BE00 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 0000BE02 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    47 0000BE06 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 0000BE08 C605[41DC0000]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 0000BE0F C605[42DC0000]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 0000BE16 50                  <1> 	push	eax			; Linear sector #
    80 0000BE17 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    81                              <1>                 
    82 0000BE18 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    83                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    84 0000BE1C 29D2                <1> 	sub	edx, edx
    85 0000BE1E 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 0000BE20 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    90 0000BE23 6641                <1> 	inc	cx			; To make it 1 based
    91 0000BE25 6651                <1> 	push	cx
    92 0000BE27 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    93 0000BE2B 6629D2              <1> 	sub	dx, dx
    94 0000BE2E F7F1                <1> 	div	ecx			; Convert track to head & cyl
    95                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    96 0000BE30 88D6                <1> 	mov	dh, dl
    97 0000BE32 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    98 0000BE34 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
    99                              <1> 
   100 0000BE37 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   101 0000BE39 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   102 0000BE3C 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 0000BE3E B001                <1> 	mov	al, 1 ; 25/02/2016
   113 0000BE40 8A25[41DC0000]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   114                              <1> 	;
   115 0000BE46 E8BB69FFFF          <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 0000BE4B 8825[43DC0000]      <1> 	mov	[disk_rw_err], ah
   122                              <1> 	
   123 0000BE51 59                  <1> 	pop	ecx
   124 0000BE52 58                  <1> 	pop	eax
   125 0000BE53 7314                <1> 	jnc	short chs_read_ok
   126                              <1> 
   127 0000BE55 803D[43DC0000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   128 0000BE5C 7408                <1> 	je	short chs_read_error_retn
   129                              <1>              
   130 0000BE5E FE0D[42DC0000]      <1> 	dec	byte [retry_count]
   131 0000BE64 75B0                <1> 	jnz	short chs_read_retry
   132                              <1> 
   133                              <1> chs_read_error_retn:
   134 0000BE66 F9                  <1> 	stc
   135                              <1> 	;retn
   136 0000BE67 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 0000BE69 40                  <1> 	inc	eax ; next sector
   154 0000BE6A 81C300020000        <1> 	add	ebx, 512
   155 0000BE70 E29D                <1> 	loop	chs_read_next_sector
   156 0000BE72 EB5E                <1> 	jmp	short update_drv_error_byte
   157                              <1> 
   158                              <1> lba_write:
   159                              <1> 	; 23/02/2016
   160 0000BE74 C605[41DC0000]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   161 0000BE7B 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 0000BE7D C605[41DC0000]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   185                              <1> 
   186                              <1> lba_rw:
   187                              <1> 	; 17/02/2016
   188 0000BE84 57                  <1> 	push	edi
   189                              <1> 
   190 0000BE85 890D[44DC0000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   191                              <1> 
   192 0000BE8B 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 0000BE8E 81F900010000        <1> 	cmp	ecx, 256
   197 0000BE94 7605                <1> 	jna	short lba_read_rsc
   198 0000BE96 B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   199                              <1> lba_read_rsc:
   200 0000BE9B 290D[44DC0000]      <1> 	sub	[sector_count], ecx ; remain sectors
   201                              <1> 
   202 0000BEA1 89CF                <1> 	mov	edi, ecx 
   203 0000BEA3 89C1                <1> 	mov	ecx, eax ; sector number/address
   204                              <1> 
   205 0000BEA5 C605[42DC0000]04    <1> 	mov	byte [retry_count], 4
   206                              <1> lba_read_retry:
   207 0000BEAC 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 0000BEAE 8A25[41DC0000]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   217 0000BEB4 E84D69FFFF          <1> 	call	int13h
   218                              <1> 	; al = ? (changed)
   219                              <1> 	; ah = error code
   220 0000BEB9 8825[43DC0000]      <1> 	mov	[disk_rw_err], ah
   221 0000BEBF 7334                <1> 	jnc	short lba_read_ok
   222 0000BEC1 80FC80              <1> 	cmp	ah, 80h ; time out?
   223 0000BEC4 740A                <1>         je      short lba_read_stc_retn
   224 0000BEC6 FE0D[42DC0000]      <1> 	dec	byte [retry_count]
   225 0000BECC 7FDE                <1> 	jg	short lba_read_retry
   226 0000BECE 743A                <1> 	jz	short lba_read_reset
   227                              <1> 	; sf =  1
   228                              <1> 
   229                              <1> lba_read_stc_retn:
   230 0000BED0 F9                  <1> 	stc
   231                              <1> lba_read_retn:
   232 0000BED1 5F                  <1> 	pop	edi
   233                              <1> 
   234                              <1> update_drv_error_byte:
   235 0000BED2 9C                  <1> 	pushf
   236 0000BED3 53                  <1> 	push	ebx
   237 0000BED4 6651                <1> 	push	cx
   238                              <1> 	;or	ecx, ecx
   239                              <1> 	;jz	short udrv_errb0
   240 0000BED6 8A0D[43DC0000]      <1> 	mov	cl, [disk_rw_err]
   241                              <1> udrv_errb0:
   242 0000BEDC 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   243 0000BEE0 80FB02              <1> 	cmp	bl, 2
   244 0000BEE3 7203                <1>         jb      short udrv_errb1
   245 0000BEE5 80EB7E              <1> 	sub	bl, 7Eh
   246                              <1> 	;cmp	bl, 5
   247                              <1> 	;ja	short udrv_errb2	
   248                              <1> udrv_errb1:
   249 0000BEE8 81C3[E1CD0000]      <1>         add     ebx, drv.error ; 13/02/2016
   250 0000BEEE 880B                <1> 	mov	[ebx], cl ; error code
   251                              <1> udrv_errb2:
   252 0000BEF0 6659                <1> 	pop	cx
   253 0000BEF2 5B                  <1> 	pop	ebx
   254 0000BEF3 9D                  <1> 	popf
   255 0000BEF4 C3                  <1> 	retn
   256                              <1> 
   257                              <1> lba_read_ok:
   258 0000BEF5 89C8                <1> 	mov	eax, ecx ; sector number
   259 0000BEF7 01F8                <1> 	add	eax, edi ; sector number (next)
   260 0000BEF9 C1E709              <1> 	shl	edi, 9 ; sector count * 512
   261 0000BEFC 01FB                <1> 	add	ebx, edi ; next buffer offset
   262                              <1> 
   263 0000BEFE 8B0D[44DC0000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   264 0000BF04 09C9                <1> 	or	ecx, ecx
   265 0000BF06 7586                <1> 	jnz	short lba_read_next
   266 0000BF08 EBC7                <1> 	jmp	short lba_read_retn
   267                              <1> 
   268                              <1> lba_read_reset:
   269 0000BF0A B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   270 0000BF0C E8F568FFFF          <1>         call	int13h
   271                              <1> 	; al = ? (changed)
   272                              <1> 	; ah = error code
   273 0000BF11 7399                <1> 	jnc	short lba_read_retry
   274 0000BF13 EBBC                <1> 	jmp	short lba_read_retn
  1884                                  %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: 23/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> ; u0.s (20/11/2015), u4.s (14/10/2015)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> set_run_sequence:
    15                              <1> 	; 22/05/2016
    16                              <1> 	; 20/05/2016
    17                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
    18                              <1> 	; TRDOS 386 feature only !
    19                              <1> 	;
    20                              <1> 	; INPUT ->
    21                              <1> 	;	AX = process ID (next process)
    22                              <1> 	;
    23                              <1> 	;	this process must be added to run sequence
    24                              <1> 	;
    25                              <1> 	;	[u.pri] = priority of present process
    26                              <1> 	;
    27                              <1> 	;	DL = priority (queue)
    28                              <1> 	;	     0 = background (low) ; run on background 
    29                              <1> 	;	     1 = regular (normal) ; run as regular
    30                              <1> 	;	     2 = event (high)     ; run for event
    31                              <1> 	;
    32                              <1> 	;	1) If the requested process is already running:
    33                              <1> 	;	   a) If present priority is high ([u.pri]=2)
    34                              <1> 	;	      and requested priority is also high,
    35                              <1> 	;	      the process will be added to 'runq_event'
    36                              <1> 	;	      high priority run queue for this new (timer)
    37                              <1> 	;	      event. There is nothing to do in addition.	 	
    38                              <1> 	;	   b) If present priority is high ([u.pri]=2)
    39                              <1> 	;	      and requested priority is not high, there is
    40                              <1> 	;	      nothing to do! Because, it's current
    41                              <1> 	;	      run queue is unspecified, here. (It may be in
    42                              <1> 	;	      a waiting list or in a run queue; if the new
    43                              <1> 	;	      priority would be used to add it to relavant
    44                              <1>         ;             run queue, this would be wrong, unnecessary
    45                              <1> 	;	      and destabilizing duplication!)
    46                              <1> 	;	   c) If present priority is not high ([u.pri]<2)
    47                              <1>         ;             and requested priority is high (event),
    48                              <1> 	;	      process will be added to present priority's
    49                              <1> 	;	      run queue and then, priority will be changed
    50                              <1> 	;	      to high ([u.pri]=2).
    51                              <1> 	;	   d) If present priority is not high ([u.pri]<2)
    52                              <1> 	;	      and requested priority is not high, [u.pri]
    53                              <1> 	;	      value will be changed. There is nothing to do
    54                              <1> 	;	      in addition. (The new priority value will be
    55                              <1> 	;	      used by 'tswap/tswitch' procedure at 'sysret'
    56                              <1> 	;	      or 'sysrele' stage.)
    57                              <1> 	;
    58                              <1> 	;	2) If the requested process is not running:
    59                              <1> 	;	   a) If requested priority of the requested
    60                              <1> 	;	      (next) process is high (event) and priority
    61                              <1> 	;	      of present process is not high, the requested
    62                              <1> 	;	      process will be added to ('runq_event') high
    63                              <1> 	;	      priority run queue and then present (running)
    64                              <1> 	;	      process will be stopped (swapped/switched out)
    65                              <1> 	;	      immediately if it is in user mode, or it's 
    66                              <1> 	;	      [u.quant] value will be reset to 0 and (then) 
    67                              <1> 	;	      it will be stopped at 'sysret' stage.			
    68                              <1> 	;	   b) If requested priority of the requested
    69                              <1> 	;	      (next) process is high (event) and priority
    70                              <1> 	;	      of present process is also high, the requested
    71                              <1> 	;	      process will be added to ('runq_event') high
    72                              <1> 	;	      priority run queue and present (running) 
    73                              <1> 	;	      process will be allowed to run until it's 
    74                              <1> 	;	      time quantum will be elapsed ([u.quant]=0).	
    75                              <1> 	;	   c) If requested priority of the requested
    76                              <1> 	;	      (next) process is not high ('run for event'), 
    77                              <1> 	;	      there is nothing to do. Because, it's current
    78                              <1> 	;	      run queue is unspecified, here. (It may be in
    79                              <1> 	;	      a waiting list or in a run queue; if the new
    80                              <1> 	;	      priority would be used to add it to relavant
    81                              <1>         ;             run queue, this would be wrong, unnecessary
    82                              <1> 	;	      and destabilizing duplication!) 
    83                              <1> 	;
    84                              <1> 	; OUTPUT ->
    85                              <1> 	;	none
    86                              <1> 	;
    87                              <1> 	;	[u.pri] = priority of present process
    88                              <1> 	;
    89                              <1> 	;	cf = 1, if the request could not be fulfilled.
    90                              <1> 	;			 	     	  
    91                              <1> 	;	NOTE: 
    92                              <1>         ;          * Processes in 'run as regular' queue can run
    93                              <1> 	;	     if there is no process in 'run for event' queue
    94                              <1> 	;	     ('run for event' processes have higher priority)	 		 
    95                              <1> 	;	   * When [u.quant] time quantum of a process is
    96                              <1> 	;	     elapsed, it's high priority ('run for event')
    97                              <1> 	;	     status will be disabled, it can be run in sequence
    98                              <1> 	;	     of it's actual run queue.
    99                              <1> 	;	   * A 'run on background' process will always be 
   100                              <1> 	;	     sequenced in 'run on background' (low priority)
   101                              <1> 	;	     queue, it can run only when other priority queues
   102                              <1> 	;	     are empty. (idle time processes, e.g. printing)  	 	
   103                              <1> 	;
   104                              <1> 	; Modified registers: eax, ebx, edx, edi
   105                              <1> 	;
   106                              <1> 
   107                              <1> srunseq_0:
   108 0000BF15 89C3                <1> 	mov	ebx, eax
   109 0000BF17 31C0                <1> 	xor	eax, eax
   110 0000BF19 BF[2CE00000]        <1> 	mov	edi, p.pid
   111                              <1> srunseq_1:
   112 0000BF1E FEC0                <1> 	inc	al
   113 0000BF20 663B1F              <1> 	cmp	bx, [edi]
   114 0000BF23 750E                <1> 	jne	short srunseq_3
   115                              <1> 
   116 0000BF25 3A05[97E30000]      <1>         cmp     al, [u.uno]     ; same process ?
   117 0000BF2B 740E                <1> 	je	short srunseq_4 ; yes
   118                              <1> 
   119                              <1> 	; dl = priority
   120 0000BF2D 80FA02              <1> 	cmp	dl, 2 		; event queue
   121 0000BF30 733D                <1> 	jnb	short srunseq_9
   122                              <1> 	
   123                              <1> 	; requested process is not present process
   124                              <1> 	; & priority of requested process is not high
   125                              <1> 	
   126                              <1> 	; there is nothing to do!
   127                              <1> 
   128                              <1> srunseq_2:
   129 0000BF32 C3                  <1> 	retn
   130                              <1> 
   131                              <1> srunseq_3:
   132 0000BF33 3C10                <1>         cmp     al, nproc       ; number of processes = 16 
   133 0000BF35 731E                <1> 	jnb	short srunseq_7 ; 'p.pid' values do not match !!!???
   134                              <1> 
   135 0000BF37 47                  <1> 	inc	edi
   136 0000BF38 47                  <1> 	inc	edi
   137 0000BF39 EBE3                <1> 	jmp	short srunseq_1
   138                              <1> 
   139                              <1> srunseq_4:
   140 0000BF3B 8A25[8BE30000]      <1> 	mov	ah, [u.pri] ; present/current priority
   141 0000BF41 80FC02              <1> 	cmp	ah, 2       ; 'run for event' priority level
   142 0000BF44 7211                <1> 	jb	short srunseq_8 ; no
   143                              <1> 	
   144                              <1> 	; present priority of the process is high
   145                              <1> 
   146 0000BF46 38E2                <1> 	cmp	dl, ah  ; both are 'run for event'? 
   147 0000BF48 72E8                <1> 	jb	short srunseq_2 ; requested priority is not high
   148                              <1> 	   			; while present priority is high!
   149                              <1> 		       		; There is nothing to do!	
   150                              <1> srunseq_5:
   151                              <1> 	; add process to 'runq_event' queue for new event
   152 0000BF4A BB[36E30000]        <1> 	mov	ebx, runq_event ; high priority run queue
   153                              <1> 
   154                              <1> srunseq_6:
   155                              <1> 	; al = process number
   156                              <1> 	; ebx = run queue
   157 0000BF4F E81BFDFFFF          <1> 	call	putlu
   158 0000BF54 C3                  <1> 	retn
   159                              <1> 
   160                              <1> srunseq_7:
   161 0000BF55 F5                  <1> 	cmc
   162 0000BF56 C3                  <1> 	retn	
   163                              <1> 
   164                              <1> srunseq_8:
   165                              <1> 	; present priority of the process is not high
   166                              <1> 	
   167 0000BF57 8815[8BE30000]      <1> 	mov	[u.pri], dl ; new priority 
   168                              <1> 			    ; (will be used by 'tswap')
   169                              <1> 
   170 0000BF5D 80FA02              <1> 	cmp	dl, 2 		; high priority ?
   171 0000BF60 72F3                <1> 	jb	short srunseq_7 ; no, there is nothing to do
   172                              <1> 				; in addition
   173                              <1> 
   174                              <1> 	; process must be added to relevant run que, here!
   175                              <1> 	; (new priority is high/event priority and process
   176                              <1> 	; will not be added to a run queue by 'tswap')
   177                              <1> 
   178 0000BF62 BB[38E30000]        <1> 	mov	ebx, runq_normal ; 'run as regular' queue
   179                              <1> 
   180 0000BF67 20E4                <1> 	and	ah, ah  ;  previous value of [u.pri]
   181 0000BF69 75E4                <1> 	jnz	short srunseq_6
   182                              <1> 
   183 0000BF6B 43                  <1> 	inc	ebx
   184 0000BF6C 43                  <1> 	inc	ebx
   185                              <1> 	; ebx = runq_background ; 'run on backgroud' queue 
   186                              <1> 
   187 0000BF6D EBE0                <1> 	jmp	short srunseq_6
   188                              <1> 
   189                              <1> srunseq_9:
   190                              <1> 	; requested process is not present process
   191                              <1> 	; & priority of requested process is high
   192 0000BF6F 3A25[8BE30000]      <1> 	cmp	ah, [u.pri] ; priority of present process
   193 0000BF75 76D3                <1> 	jna	short srunseq_5 ; is high, also
   194                              <1> 	;
   195                              <1> 	; present process will be swapped/switched out
   196 0000BF77 FE05[09E00000]      <1> 	inc	byte [p_change] ; 1
   197 0000BF7D EBCB                <1> 	jmp	short srunseq_5
   198                              <1> 
   199                              <1> clock:
   200                              <1> 	; 23/05/2016
   201                              <1> 	; 22/05/2016
   202                              <1> 	; 20/05/2016
   203                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   204                              <1> 	; 14/05/2015 - 14/10/2015 (Retro UNIX 386 v1)
   205                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
   206                              <1> 
   207 0000BF7F 803D[8AE30000]00    <1> 	cmp	byte [u.quant], 0
   208 0000BF86 772C                <1> 	ja	short clk_1
   209                              <1> 	;
   210 0000BF88 803D[97E30000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ? (for Retro UNIX 8086 & 386 v1)
   211                              <1> 				; MainProg (Kernel's Command Interpreter)
   212                              <1> 				; for TRDOS 386.
   213 0000BF8F 7623                <1> 	jna	short clk_1 ; yes, do not swap out
   214                              <1> 	;
   215 0000BF91 803D[3FE30000]FF    <1> 	cmp     byte [sysflg], 0FFh ; user or system space ?
   216 0000BF98 7520                <1> 	jne	short clk_2 	    ; system space (sysflg <> 0FFh)
   217                              <1> 	;
   218 0000BF9A 66833D[8CE30000]00  <1> 	cmp	word [u.intr], 0
   219 0000BFA2 7616                <1> 	jna	short clk_2
   220                              <1> 	;
   221                              <1> 	; 23/05/2016
   222 0000BFA4 803D[0AE00000]00    <1> 	cmp	byte [multi_tasking], 0
   223 0000BFAB 760D                <1> 	jna	short clk_2
   224                              <1> 	;
   225 0000BFAD FE05[09E00000]      <1> 	inc	byte [p_change] ; it is time to change running process	
   226 0000BFB3 C3                  <1> 	retn
   227                              <1> clk_1:
   228 0000BFB4 FE0D[8AE30000]      <1> 	dec	byte [u.quant]
   229                              <1> clk_2:
   230 0000BFBA C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
   231                              <1> 
   232                              <1> 
   233                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   234                              <1> int34h:  ; #IOCTL# (I/O port access support for ring 3)
   235 0000BFBB CF                  <1> 	iretd
   236                              <1> 
   237                              <1> INT4Ah:
   238                              <1> 	; 24/01/2016
   239                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
   240 0000BFBC C3                  <1> 	retn
   241                              <1> 
   242                              <1> ; u0.s
   243                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
   244                              <1> ; Last Modification: 20/11/2015
   245                              <1> 
   246                              <1> com2_int:
   247                              <1> 	; 07/11/2015 
   248                              <1> 	; 24/10/2015
   249                              <1> 	; 23/10/2015
   250                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   251                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   252                              <1> 	; < serial port 2 interrupt handler >
   253                              <1> 	;
   254 0000BFBD 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   255                              <1> 	;push	eax
   256 0000BFC0 66B80900            <1> 	mov	ax, 9
   257 0000BFC4 EB07                <1> 	jmp	short comm_int
   258                              <1> com1_int:
   259                              <1> 	; 07/11/2015
   260                              <1> 	; 24/10/2015
   261 0000BFC6 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   262                              <1> 	; 23/10/2015
   263                              <1> 	;push	eax
   264 0000BFC9 66B80800            <1> 	mov	ax, 8
   265                              <1> comm_int:
   266                              <1> 	; 20/11/2015
   267                              <1> 	; 18/11/2015
   268                              <1> 	; 17/11/2015
   269                              <1> 	; 16/11/2015
   270                              <1> 	; 09/11/2015
   271                              <1> 	; 08/11/2015
   272                              <1> 	; 07/11/2015
   273                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
   274                              <1> 	; 01/11/2015
   275                              <1> 	; 26/10/2015
   276                              <1> 	; 23/10/2015
   277 0000BFCD 53                  <1> 	push	ebx
   278 0000BFCE 56                  <1> 	push	esi
   279 0000BFCF 57                  <1> 	push	edi
   280 0000BFD0 1E                  <1> 	push 	ds
   281 0000BFD1 06                  <1> 	push 	es
   282                              <1> 	; 18/11/2015
   283 0000BFD2 0F20DB              <1> 	mov	ebx, cr3
   284 0000BFD5 53                  <1> 	push	ebx ; ****
   285                              <1> 	;
   286 0000BFD6 51                  <1> 	push	ecx ; ***
   287 0000BFD7 52                  <1> 	push	edx ; **
   288                              <1> 	;
   289 0000BFD8 BB10000000          <1> 	mov	ebx, KDATA
   290 0000BFDD 8EDB                <1> 	mov	ds, bx
   291 0000BFDF 8EC3                <1> 	mov	es, bx
   292                              <1> 	;
   293 0000BFE1 8B0D[88D20000]      <1> 	mov	ecx, [k_page_dir]
   294 0000BFE7 0F22D9              <1> 	mov	cr3, ecx
   295                              <1> 	; 20/11/2015
   296                              <1> 	; Interrupt identification register
   297 0000BFEA 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
   298                              <1> 	;
   299 0000BFEE 3C08                <1> 	cmp 	al, 8 
   300 0000BFF0 7702                <1> 	ja 	short com_i0
   301                              <1> 	;
   302                              <1> 	; 20/11/2015
   303                              <1> 	; 17/11/2015
   304                              <1> 	; 16/11/2015
   305                              <1> 	; 15/11/2015
   306                              <1> 	; 24/10/2015
   307                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   308                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   309                              <1> 	; < serial port 1 interrupt handler >
   310                              <1> 	;
   311 0000BFF2 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
   312                              <1> com_i0:
   313                              <1> 	;push	eax ; *
   314                              <1> 	; 07/11/2015
   315 0000BFF4 A2[F4D20000]        <1> 	mov 	byte [ccomport], al
   316                              <1> 	; 09/11/2015
   317 0000BFF9 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
   318                              <1> 	; 17/11/2015
   319                              <1>  	; reset request for response status
   320 0000BFFC 88A3[EAD20000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   321                              <1> 	;
   322                              <1> 	; 20/11/2015
   323 0000C002 EC                  <1> 	in	al, dx		; read interrupt id. register
   324 0000C003 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   325 0000C005 2404                <1> 	and	al, 4		; received data available?	
   326 0000C007 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   327                              <1> 	;
   328                              <1> 	; 20/11/2015
   329 0000C009 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   330 0000C00C EC                  <1> 	in	al, dx     	; read character
   331                              <1> 	;JMP	$+2	   	; I/O DELAY
   332                              <1> 	; 08/11/2015
   333                              <1> 	; 07/11/2015
   334 0000C00D 89DE                <1> 	mov	esi, ebx 
   335 0000C00F 89DF                <1> 	mov	edi, ebx
   336 0000C011 81C6[EED20000]      <1> 	add 	esi, rchar - 8 ; points to last received char
   337 0000C017 81C7[F0D20000]      <1> 	add	edi, schar - 8 ; points to last sent char
   338 0000C01D 8806                <1> 	mov	[esi], al ; received char (current char)
   339                              <1> 	; query
   340 0000C01F 20C0                <1> 	and	al, al
   341 0000C021 7527                <1> 	jnz	short com_i2
   342                              <1>    	; response
   343                              <1> 	; 17/11/2015
   344                              <1> 	; set request for response status
   345 0000C023 FE83[EAD20000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   346                              <1> 	;
   347 0000C029 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   348 0000C02D EC                  <1> 	in	al, dx	   	; read line status register 
   349 0000C02E EB00                <1> 	JMP	$+2	   	; I/O DELAY
   350 0000C030 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   351 0000C032 7445                <1> 	jz	short com_eoi 	; no
   352 0000C034 B0FF                <1> 	mov 	al, 0FFh   	; response			
   353 0000C036 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   354 0000C03A EE                  <1> 	out	dx, al	   	; send on serial port
   355                              <1> 	; 17/11/2015
   356 0000C03B 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   357 0000C03E 7502                <1> 	jne 	short com_i1    ; no
   358 0000C040 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
   359                              <1> com_i1:
   360                              <1> 	; 17/11/2015
   361                              <1> 	; reset request for response status (again)
   362 0000C042 FE8B[EAD20000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   363 0000C048 EB2F                <1> 	jmp	short com_eoi
   364                              <1> com_i2:	
   365                              <1> 	; 08/11/2015
   366 0000C04A 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   367 0000C04C 7417                <1> 	je	short com_i3	; (check for response signal)
   368                              <1> 	; 07/11/2015
   369 0000C04E 3C04                <1> 	cmp	al, 04h	; EOT
   370 0000C050 751C                <1> 	jne	short com_i4	
   371                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
   372                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
   373                              <1> 	; 08/11/2015
   374                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
   375 0000C052 861D[B8D20000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   376 0000C058 E8D07FFFFF          <1> 	call 	ctrlbrk
   377 0000C05D 861D[B8D20000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   378                              <1> 	;mov	al, 04h ; EOT
   379                              <1> 	; 08/11/2015
   380 0000C063 EB09                <1> 	jmp	short com_i4	
   381                              <1> com_i3:
   382                              <1> 	; 08/11/2015
   383                              <1> 	; If 0FFh has been received just after a query
   384                              <1> 	; (schar, ZERO), it is a response signal.
   385                              <1> 	; 17/11/2015
   386 0000C065 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   387 0000C068 7704                <1> 	ja	short com_i4 ; no
   388                              <1> 	; reset query status (schar)
   389 0000C06A 8807                <1> 	mov	[edi], al ; 0FFh
   390 0000C06C FEC0                <1> 	inc	al ; 0
   391                              <1> com_i4:
   392                              <1> 	; 27/07/2014
   393                              <1> 	; 09/07/2014
   394 0000C06E D0E3                <1> 	shl	bl, 1	
   395 0000C070 81C3[BAD20000]      <1> 	add	ebx, ttychr
   396                              <1> 	; 23/07/2014 (always overwrite)
   397                              <1> 	;;cmp	word [ebx], 0
   398                              <1> 	;;ja	short com_eoi
   399                              <1> 	;
   400 0000C076 668903              <1> 	mov	[ebx], ax   ; Save ascii code
   401                              <1> 			    ; scan code = 0
   402                              <1> com_eoi:
   403                              <1> 	;mov	al, 20h
   404                              <1> 	;out	20h, al	   ; end of interrupt
   405                              <1> 	;
   406                              <1> 	; 07/11/2015
   407                              <1>       	;pop	eax ; *
   408 0000C079 A0[F4D20000]        <1> 	mov	al, byte [ccomport] ; current COM port
   409                              <1> 	 ; al = tty number (8 or 9)
   410 0000C07E E85E010000          <1>         call	wakeup
   411                              <1> com_iret:
   412                              <1> 	; 23/10/2015
   413 0000C083 5A                  <1> 	pop	edx ; **
   414 0000C084 59                  <1> 	pop	ecx ; ***
   415                              <1> 	; 18/11/2015
   416                              <1> 	;pop	eax ; ****
   417                              <1> 	;mov	cr3, eax
   418                              <1> 	;jmp	iiret
   419 0000C085 E93349FFFF          <1> 	jmp	iiretp
   420                              <1> 
   421                              <1> ;iiretp: ; 01/09/2015
   422                              <1> ;	; 28/08/2015
   423                              <1> ;	pop	eax ; (*) page directory
   424                              <1> ;	mov	cr3, eax
   425                              <1> ;iiret:
   426                              <1> ;	; 22/08/2014
   427                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
   428                              <1> ;	out	20h, al	; 8259 PORT
   429                              <1> ;	;
   430                              <1> ;	pop	es
   431                              <1> ;	pop	ds
   432                              <1> ;	pop	edi
   433                              <1> ;	pop	esi
   434                              <1> ;	pop	ebx ; 29/08/2014
   435                              <1> ;	pop 	eax
   436                              <1> ;	iretd
   437                              <1> 
   438                              <1> sp_init:
   439                              <1> 	; 07/11/2015
   440                              <1> 	; 29/10/2015
   441                              <1> 	; 26/10/2015
   442                              <1> 	; 23/10/2015
   443                              <1> 	; 29/06/2015
   444                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
   445                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
   446                              <1> 	; Initialization of Serial Port Communication Parameters
   447                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   448                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   449                              <1> 	;
   450                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   451                              <1> 	;
   452                              <1> 	; INPUT:  (29/06/2015)
   453                              <1> 	;	AL = 0 for COM1
   454                              <1> 	;	     1 for COM2
   455                              <1> 	;	AH = Communication parameters	
   456                              <1> 	;
   457                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   458                              <1> 	;	Bit	4	3	2	1	0
   459                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   460                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   461                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   462                              <1> 	;		11 = even
   463                              <1> 	;  Baud rate setting bits: (29/06/2015)
   464                              <1> 	;		Retro UNIX 386 v1 feature only !
   465                              <1> 	;	Bit	7    6    5  | Baud rate
   466                              <1> 	;		------------------------
   467                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   468                              <1> 	;		0    0    1  | 9600 (12)
   469                              <1> 	;		0    1    0  | 19200 (6) 
   470                              <1> 	;		0    1	  1  | 38400 (3) 
   471                              <1> 	;		1    0	  0  | 14400 (8)
   472                              <1> 	;		1    0	  1  | 28800 (4)
   473                              <1> 	;		1    1    0  | 57600 (2)
   474                              <1> 	;		1    1    1  | 115200 (1) 	
   475                              <1> 	
   476                              <1> 	; References:	
   477                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
   478                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   479                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
   480                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
   481                              <1> 	;
   482                              <1> 	; Set communication parameters for COM1 (= 03h)	
   483                              <1> 	;
   484 0000C08A BB[F0D20000]        <1> 	mov	ebx, com1p		; COM1 parameters  
   485 0000C08F 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   486                              <1> 	 ; 29/10/2015
   487 0000C093 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   488 0000C097 E86F000000          <1> 	call	sp_i3	; call A4	
   489 0000C09C A880                <1> 	test	al, 80h
   490 0000C09E 7410                <1> 	jz	short sp_i0 ; OK..
   491                              <1> 		; Error !
   492                              <1> 	;mov	dx, 3F8h
   493 0000C0A0 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   494 0000C0A3 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   495 0000C0A7 E85F000000          <1> 	call	sp_i3	; call A4	
   496 0000C0AC A880                <1> 	test	al, 80h
   497 0000C0AE 7508                <1> 	jnz	short sp_i1
   498                              <1> sp_i0:
   499                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
   500                              <1>         ; (INT 14h initialization code disables interrupts.)
   501                              <1> 	;
   502 0000C0B0 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   503 0000C0B3 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   504                              <1> sp_i1:
   505 0000C0B8 43                  <1> 	inc	ebx
   506 0000C0B9 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   507                              <1> 	 ; 29/10/2015
   508 0000C0BD 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   509 0000C0C1 E845000000          <1> 	call	sp_i3	; call A4	
   510 0000C0C6 A880                <1> 	test	al, 80h
   511 0000C0C8 7410                <1> 	jz	short sp_i2 ; OK..
   512                              <1> 		; Error !
   513                              <1> 	;mov	dx, 2F8h
   514 0000C0CA 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   515 0000C0CD 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   516 0000C0D1 E835000000          <1> 	call	sp_i3	; call A4	
   517 0000C0D6 A880                <1> 	test	al, 80h
   518 0000C0D8 7530                <1> 	jnz	short sp_i7
   519                              <1> sp_i2:
   520 0000C0DA C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   521                              <1> sp_i6:
   522                              <1> 	;; COM2 - enabling IRQ 3
   523                              <1> 	; 07/11/2015
   524                              <1> 	; 26/10/2015
   525 0000C0DD 9C                  <1> 	pushf
   526 0000C0DE FA                  <1> 	cli
   527                              <1> 	;
   528 0000C0DF 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   529 0000C0E3 EC                  <1> 	in	al, dx 	   		; read register
   530 0000C0E4 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   531 0000C0E6 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   532 0000C0E8 EE                  <1> 	out	dx, al     		; write back to register
   533 0000C0E9 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   534 0000C0EB 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   535 0000C0EF EC                  <1> 	in	al, dx     		; read register
   536 0000C0F0 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   537                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   538 0000C0F2 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   539 0000C0F4 EE                  <1> 	out	dx, al 	   		; write back to register
   540 0000C0F5 EB00                <1> 	JMP	$+2        		; I/O DELAY
   541 0000C0F7 E421                <1> 	in	al, 21h    		; read interrupt mask register
   542 0000C0F9 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   543 0000C0FB 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   544 0000C0FD E621                <1> 	out	21h, al    		; write back to register
   545                              <1> 	;
   546                              <1> 	; 23/10/2015
   547 0000C0FF B8[BDBF0000]        <1> 	mov 	eax, com2_int
   548 0000C104 A3[DCC10000]        <1> 	mov	[com2_irq3], eax
   549                              <1> 	; 26/10/2015
   550 0000C109 9D                  <1> 	popf	
   551                              <1> sp_i7:
   552 0000C10A C3                  <1> 	retn
   553                              <1> 
   554                              <1> sp_i3:
   555                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   556                              <1> 	; 28/10/2015
   557 0000C10B FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   558 0000C10D B000                <1> 	mov	al, 0
   559 0000C10F EE                  <1> 	out	dx, al			; disable serial port interrupt
   560 0000C110 EB00                <1> 	JMP	$+2			; I/O DELAY
   561 0000C112 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   562 0000C115 B080                <1> 	mov	al, 80h			
   563 0000C117 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   564                              <1> 	;-----	SET BAUD RATE DIVISOR
   565                              <1> 	; 26/10/2015
   566 0000C118 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   567                              <1> 					; of the divisor value
   568 0000C11B 88C8                <1> 	mov	al, cl	; 1
   569 0000C11D EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   570                              <1> 					; 2 = 57600 baud
   571                              <1> 					; 3 = 38400 baud
   572                              <1> 					; 6 = 19200 baud
   573                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
   574 0000C11E EB00                <1> 	JMP	$+2			; I/O DELAY
   575 0000C120 28C0                <1> 	sub	al, al
   576 0000C122 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   577                              <1> 					; of the divisor value
   578 0000C124 EE                  <1> 	out	dx, al ; 0
   579 0000C125 EB00                <1> 	JMP	$+2			; I/O DELAY
   580                              <1> 	;	
   581 0000C127 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   582                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
   583 0000C129 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   584 0000C12C EE                  <1> 	out	dx, al			
   585 0000C12D EB00                <1> 	JMP	$+2			; I/O DELAY
   586                              <1> 	; 29/10/2015
   587 0000C12F FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   588 0000C131 30C0                <1> 	xor	al, al			; 0
   589 0000C133 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   590 0000C134 EB00                <1> 	JMP	$+2	
   591                              <1> sp_i4:
   592                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
   593                              <1> 	; 29/06/2015 (line status after modem status)
   594 0000C136 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   595                              <1> sp_i4s:
   596 0000C139 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   597 0000C13A EB00                <1> 	JMP	$+2			; I/O DELAY
   598 0000C13C 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   599 0000C13E FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   600                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   601 0000C140 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   602                              <1> 	; AL = Line status, AH = Modem status
   603 0000C141 C3                  <1> 	retn
   604                              <1> 
   605                              <1> sp_status:
   606                              <1> 	; 29/06/2015
   607                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
   608                              <1> 	; Get serial port status
   609 0000C142 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   610 0000C146 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   611                              <1> 					; dx = 2FEh for COM2
   612 0000C148 EBEF                <1> 	jmp	short sp_i4s
   613                              <1> 
   614                              <1> sp_setp: ; Set serial port communication parameters
   615                              <1> 	; 07/11/2015
   616                              <1> 	; 29/10/2015
   617                              <1> 	; 29/06/2015
   618                              <1> 	; Retro UNIX 386 v1 feature only !	
   619                              <1> 	;
   620                              <1> 	; INPUT:
   621                              <1> 	;	AL = 0 for COM1
   622                              <1> 	;	     1 for COM2
   623                              <1> 	;	AH = Communication parameters (*)
   624                              <1> 	; OUTPUT:
   625                              <1> 	;	CL = Line status
   626                              <1> 	;	CH = Modem status
   627                              <1> 	;   If cf = 1 -> Error code in [u.error]
   628                              <1> 	;		 'invalid parameter !' 
   629                              <1> 	;		 	 or
   630                              <1> 	;		 'device not ready !' error
   631                              <1> 	;	
   632                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   633                              <1> 	;	Bit	4	3	2	1	0
   634                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   635                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   636                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   637                              <1> 	;		11 = even
   638                              <1> 	;  Baud rate setting bits: (29/06/2015)
   639                              <1> 	;		Retro UNIX 386 v1 feature only !
   640                              <1> 	;	Bit	7    6    5  | Baud rate
   641                              <1> 	;		------------------------
   642                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   643                              <1> 	;		0    0    1  | 9600 (12)
   644                              <1> 	;		0    1    0  | 19200 (6) 
   645                              <1> 	;		0    1	  1  | 38400 (3) 
   646                              <1> 	;		1    0	  0  | 14400 (8)
   647                              <1> 	;		1    0	  1  | 28800 (4)
   648                              <1> 	;		1    1    0  | 57600 (2)
   649                              <1> 	;		1    1    1  | 115200 (1) 
   650                              <1> 	;
   651                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   652                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   653                              <1> 	;
   654                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   655                              <1> 	;
   656 0000C14A 66BAF803            <1> 	mov	dx, 3F8h
   657 0000C14E BB[F0D20000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   658 0000C153 3C01                <1> 	cmp	al, 1
   659 0000C155 776B                <1> 	ja 	short sp_invp_err
   660 0000C157 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   661 0000C159 FECE                <1> 	dec	dh ; 2F8h
   662 0000C15B 43                  <1> 	inc	ebx ; COM2 control byte offset
   663                              <1> sp_setp1:
   664                              <1> 	; 29/10/2015
   665 0000C15C 8823                <1> 	mov	[ebx], ah
   666 0000C15E 0FB6CC              <1> 	movzx 	ecx, ah
   667 0000C161 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   668 0000C164 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   669 0000C167 8A81[D1C10000]      <1> 	mov	al, [ecx+b_div_tbl]
   670 0000C16D 6689C1              <1> 	mov	cx, ax
   671 0000C170 E896FFFFFF          <1> 	call	sp_i3
   672 0000C175 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   673 0000C178 A880                <1> 	test	al, 80h
   674 0000C17A 740F                <1> 	jz	short sp_setp2
   675 0000C17C C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   676                              <1> stp_dnr_err:
   677 0000C17F C705[9DE30000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   677 0000C187 0000                <1>
   678                              <1> 	; CL = Line status, CH = Modem status
   679 0000C189 F9                  <1> 	stc
   680 0000C18A C3                  <1> 	retn
   681                              <1> sp_setp2:
   682 0000C18B 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   683 0000C18E 0F8649FFFFFF        <1>         jna     sp_i6 
   684                              <1> 		      ; COM1 (3F?h)
   685                              <1> sp_i5: 
   686                              <1> 	; 07/11/2015
   687                              <1> 	; 26/10/2015
   688                              <1> 	; 29/06/2015
   689                              <1> 	;
   690                              <1> 	;; COM1 - enabling IRQ 4
   691 0000C194 9C                  <1> 	pushf
   692 0000C195 FA                  <1> 	cli
   693 0000C196 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   694 0000C19A EC                  <1> 	in	al, dx 	   		; read register
   695 0000C19B EB00                <1> 	JMP	$+2			; I/O DELAY
   696 0000C19D 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   697 0000C19F EE                  <1> 	out	dx, al     		; write back to register
   698 0000C1A0 EB00                <1> 	JMP	$+2			; I/O DELAY
   699 0000C1A2 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   700 0000C1A6 EC                  <1> 	in	al, dx     		; read register
   701 0000C1A7 EB00                <1> 	JMP	$+2			; I/O DELAY
   702                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   703 0000C1A9 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   704 0000C1AB EE                  <1> 	out	dx, al 	   		; write back to register
   705 0000C1AC EB00                <1> 	JMP	$+2        		; I/O DELAY
   706 0000C1AE E421                <1> 	in	al, 21h    		; read interrupt mask register
   707 0000C1B0 EB00                <1> 	JMP	$+2			; I/O DELAY
   708 0000C1B2 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   709 0000C1B4 E621                <1> 	out	21h, al    		; write back to register
   710                              <1> 	;
   711                              <1> 	; 23/10/2015
   712 0000C1B6 B8[C6BF0000]        <1> 	mov 	eax, com1_int
   713 0000C1BB A3[D8C10000]        <1> 	mov	[com1_irq4], eax
   714                              <1> 	; 26/10/2015
   715 0000C1C0 9D                  <1> 	popf
   716 0000C1C1 C3                  <1> 	retn
   717                              <1> 
   718                              <1> sp_invp_err:
   719 0000C1C2 C705[9DE30000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   719 0000C1CA 0000                <1>
   720 0000C1CC 31C9                <1> 	xor	ecx, ecx
   721 0000C1CE 49                  <1> 	dec	ecx ; 0FFFFh
   722 0000C1CF F9                  <1> 	stc
   723 0000C1D0 C3                  <1> 	retn
   724                              <1> 
   725                              <1> ; 29/10/2015
   726                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   727 0000C1D1 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   728                              <1> 
   729                              <1> 
   730                              <1> ; 23/10/2015
   731                              <1> com1_irq4:
   732 0000C1D8 [E0C10000]          <1> 	dd dummy_retn
   733                              <1> com2_irq3:
   734 0000C1DC [E0C10000]          <1> 	dd dummy_retn
   735                              <1> 
   736                              <1> dummy_retn:
   737 0000C1E0 C3                  <1> 	retn
   738                              <1> 
   739                              <1> wakeup:
   740                              <1> 	; 24/01/2016
   741 0000C1E1 C3                  <1> 	retn
  1885                                  %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: 29/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 0000C1E2 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 0000C1E3 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 0000C1E4 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 0000C1E8 04                  <1> 		db 4
    31 0000C1E9 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 0000C1EA 07                  <1> 		db 7
    34 0000C1EB 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.290516"
    34 0000C1F4 61696E2050726F6772- <1>
    34 0000C1FD 616D2076322E302E32- <1>
    34 0000C206 3930353136          <1>
    35 0000C20B 0D0A                <1> 		db 0Dh, 0Ah
    36 0000C20D 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
    36 0000C216 616E2054616E203230- <1>
    36 0000C21F 30352D32303136      <1>
    37 0000C226 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile: ; 14/04/2016
    40 0000C229 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 0000C232 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 0000C236 5452444F53          <1> 		db "TRDOS"
    44 0000C23B 00                  <1> 		db 0
    45 0000C23C 00<rept>            <1>                 times 5 db 0
    46 0000C241 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 0000C242 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 0000C246 434400              <1> Cmd_Cd:		db "CD", 0
    52 0000C249 433A00              <1> Cmd_Drive:	db "C:", 0
    53 0000C24C 56455200            <1> Cmd_Ver:	db "VER", 0
    54 0000C250 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 0000C255 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 0000C25C 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 0000C263 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 0000C26C 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 0000C271 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 0000C276 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 0000C27A 53455400            <1> Cmd_Set:	db "SET", 0 
    62 0000C27E 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 0000C282 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 0000C287 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 0000C28B 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 0000C292 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 0000C299 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 0000C29F 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 0000C2A5 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 0000C2AA 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 0000C2AF 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 0000C2B4 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 0000C2B8 00                  <1> 		db 0
    74 0000C2B9 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 0000C2BE 5245414446494C4500  <1> Cmd_ReadFile:	db "READFILE", 0
    76 0000C2C7 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    77 0000C2CC 2A00                <1> Cmd_Remark:	db "*", 0
    78 0000C2CE 3F00                <1> Cmd_Help:	db "?", 0
    79 0000C2D0 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    80 0000C2D7 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    81 0000C2DF 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    82 0000C2E5 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    83                              <1> 		
    84 0000C2EA 00                  <1> 		db 0
    85                              <1> 
    86                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    87                              <1> invalid_fname_chars:
    88 0000C2EB 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    89 0000C2F3 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    90 0000C2FA 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 0000C2FF 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    95 0000C308 206461746520286464- <1>
    95 0000C311 2D6D6D2D7979293A20  <1>
    96 0000C31A 00                  <1>                 db 0
    97                              <1> Msg_Show_Date:
    98 0000C31B 43757272656E742064- <1>                 db   'Current date is '
    98 0000C324 61746520697320      <1>
    99 0000C32B 30                  <1> Day:            db   '0'
   100 0000C32C 30                  <1> 		db   '0'
   101 0000C32D 2F                  <1>                 db   '/'
   102 0000C32E 30                  <1> Month:          db   '0'
   103 0000C32F 30                  <1> 		db   '0'
   104 0000C330 2F                  <1>                 db   '/'
   105 0000C331 30                  <1> Century:        db   '0'
   106 0000C332 30                  <1>                 db   '0'
   107 0000C333 30                  <1> Year:           db   '0'
   108 0000C334 30                  <1> 		db   '0'
   109 0000C335 0D0A00              <1>                 db   0Dh, 0Ah, 0
   110                              <1> 
   111                              <1> Msg_Enter_Time:
   112 0000C338 456E746572206E6577- <1> 		db 'Enter new time: '
   112 0000C341 2074696D653A20      <1>
   113 0000C348 00                  <1> 		db 0
   114                              <1> Msg_Show_Time:
   115 0000C349 43757272656E742074- <1> 		db   'Current time is '
   115 0000C352 696D6520697320      <1>
   116 0000C359 30                  <1> Hour:           db   '0'
   117 0000C35A 30                  <1> 		db   '0'
   118 0000C35B 3A                  <1> 		db   ':'
   119 0000C35C 30                  <1> Minute:         db   '0'
   120 0000C35D 30                  <1> 		db   '0'
   121 0000C35E 3A                  <1> 		db   ':'
   122 0000C35F 30                  <1> Second:         db   '0'
   123 0000C360 30                  <1> 		db   '0'
   124 0000C361 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 0000C364 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   130 0000C36D 730D0A00            <1>
   131                              <1> VolSize_Bytes:
   132 0000C371 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   133                              <1> Volume_in_drive:
   134 0000C37A 0D0A                <1> 		db 0Dh, 0Ah
   135                              <1> Vol_FS_Name:
   136 0000C37C 54522046533120      <1> 		db "TR FS1 "
   137 0000C383 566F6C756D6520696E- <1> 		db "Volume in drive "
   137 0000C38C 20647269766520      <1>
   138 0000C393 30                  <1> Vol_Drv_Name:   db 30h
   139 0000C394 3A                  <1> 		db ":"
   140 0000C395 20697320            <1> 		db " is "
   141 0000C399 0D0A00              <1> 		db 0Dh, 0Ah, 0
   142                              <1> Dir_Drive_Str:
   143 0000C39C 54522D444F53204472- <1>                 db "TR-DOS Drive "
   143 0000C3A5 69766520            <1>
   144                              <1> Dir_Drive_Name:
   145 0000C3A9 303A                <1>                 db "0:"
   146 0000C3AB 0D0A                <1>                 db  0Dh, 0Ah
   147                              <1> Vol_Str_Header:
   148 0000C3AD 566F6C756D65204E61- <1>                 db "Volume Name: "
   148 0000C3B6 6D653A20            <1>
   149                              <1> Vol_Name:
   150 0000C3BA 00<rept>            <1> 		times 64 db 0
   151 0000C3FA 00                  <1> 		db 0
   152                              <1> Vol_Serial_Header:
   153 0000C3FB 0D0A                <1> 		db 0Dh, 0Ah
   154 0000C3FD 566F6C756D65205365- <1> 		db "Volume Serial No: "
   154 0000C406 7269616C204E6F3A20  <1>
   155                              <1> Vol_Serial1:
   156 0000C40F 30303030            <1> 		db "0000"
   157 0000C413 2D                  <1> 		db "-"
   158                              <1> Vol_Serial2:
   159 0000C414 30303030            <1> 		db "0000"
   160 0000C418 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 0000C41B 0D0A                <1> 		db 0Dh, 0Ah
   166 0000C41D 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   166 0000C426 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 0000C42C 467265652053706163- <1> 		db "Free Space  : ", 0
   174 0000C435 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 0000C43B 4469726563746F7279- <1>                 db "Directory: "
   181 0000C444 3A20                <1>
   182 0000C446 2F                  <1> Dir_Str_Root:   db "/"
   183 0000C447 00<rept>            <1> Dir_Str:        times 64 db 0
   184 0000C487 00000000            <1>                 dd 0
   185 0000C48B 00                  <1>                 db 0
   186                              <1> 
   187                              <1> Msg_Bad_Command:
   188 0000C48C 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   188 0000C495 6E64206F722066696C- <1>
   188 0000C49E 65206E616D6521      <1>
   189 0000C4A5 0D0A00              <1>                 db 0Dh, 0Ah, 0
   190                              <1> 
   191                              <1> msgl_drv_not_ready: 
   192 0000C4A8 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 0000C4AB 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   197 0000C4B4 207265616479206F72- <1>
   197 0000C4BD 207265616420657272- <1>
   197 0000C4C6 6F7221              <1>
   198 0000C4C9 0D0A00              <1>                 db 0Dh, 0Ah, 0
   199                              <1> 
   200                              <1> Msg_Not_Ready_Write_Err:
   201 0000C4CC 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   201 0000C4D5 207265616479206F72- <1>
   201 0000C4DE 207772697465206572- <1>
   201 0000C4E7 726F7221            <1>
   202 0000C4EB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   203                              <1> 
   204                              <1> Msg_Dir_Not_Found:
   205 0000C4EE 4469726563746F7279- <1>                 db "Directory not found!"
   205 0000C4F7 206E6F7420666F756E- <1>
   205 0000C500 6421                <1>
   206 0000C502 0D0A00              <1>                 db 0Dh, 0Ah, 0
   207                              <1> 
   208                              <1> Msg_File_Not_Found:
   209 0000C505 46696C65206E6F7420- <1>                 db "File not found!"
   209 0000C50E 666F756E6421        <1>
   210 0000C514 0D0A00              <1>                 db 0Dh, 0Ah, 0
   211                              <1> 
   212                              <1> Msg_File_Directory_Not_Found:
   213 0000C517 46696C65206F722064- <1>                 db "File or directory not found!"
   213 0000C520 69726563746F727920- <1>
   213 0000C529 6E6F7420666F756E64- <1>
   213 0000C532 21                  <1>
   214 0000C533 0D0A00              <1>                 db 0Dh, 0Ah, 0
   215                              <1> 
   216                              <1> Msg_LongName_Not_Found:
   217 0000C536 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   217 0000C53F 206E6F7420666F756E- <1>
   217 0000C548 6421                <1>
   218 0000C54A 0D0A00              <1>                 db 0Dh, 0Ah, 0
   219                              <1> 
   220                              <1> Msg_Insufficient_Memory:
   221 0000C54D 496E73756666696369- <1>                 db "Insufficient memory!"
   221 0000C556 656E74206D656D6F72- <1>
   221 0000C55F 7921                <1>
   222 0000C561 0D0A00              <1>                 db 0Dh, 0Ah, 0
   223                              <1> 
   224                              <1> Msg_Error_Code:
   225 0000C564 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   225 0000C56D 61696C656421204572- <1>
   225 0000C576 726F7220636F646520- <1>
   225 0000C57F 3A20                <1>
   226 0000C581 303068              <1> error_code_hex: db '00h'
   227 0000C584 0A0A00              <1>                 db 0Ah, 0Ah, 0
   228                              <1> 
   229 0000C587 90                  <1> align 2
   230                              <1> 
   231                              <1> ; 10/02/2016
   232                              <1> ; DIR.ASM - 09/10/2011
   233                              <1> 
   234 0000C588 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   234 0000C591 20                  <1>
   235                              <1> 
   236                              <1> File_Name:
   237 0000C592 20<rept>            <1>                 times 12 db 20h
   238 0000C59E 20                  <1> 		db 20h
   239                              <1> Dir_Or_FileSize:
   240 0000C59F 20<rept>            <1>                 times 10 db 20h
   241 0000C5A9 20                  <1> 		db 20h
   242                              <1> File_Attribute:
   243 0000C5AA 20202020            <1> 		dd 20202020h
   244 0000C5AE 20                  <1> 		db 20h
   245                              <1> File_Day:
   246 0000C5AF 3030                <1>                 db '0','0'
   247 0000C5B1 2F                  <1> 		db '/'
   248                              <1> File_Month:
   249 0000C5B2 3030                <1>                 db '0','0'
   250 0000C5B4 2F                  <1> 		db '/'
   251                              <1> File_Year:
   252 0000C5B5 30303030            <1>                 db '0','0','0','0'
   253 0000C5B9 20                  <1> 		db 20h
   254                              <1> File_Hour:
   255 0000C5BA 3030                <1>                 db '0','0'
   256 0000C5BC 3A                  <1> 		db ':'
   257                              <1> File_Minute:
   258 0000C5BD 3030                <1>                 db '0','0'
   259 0000C5BF 00                  <1> 		db 0
   260                              <1> 
   261                              <1> Decimal_File_Count_Header:
   262 0000C5C0 0D0A                <1> 		db 0Dh, 0Ah
   263                              <1> Decimal_File_Count:
   264 0000C5C2 00<rept>            <1> 		times 6 db 0
   265                              <1> 
   266 0000C5C8 2066696C6528732920- <1> str_files:	db " file(s) & "
   266 0000C5D1 2620                <1>
   267                              <1> Decimal_Dir_Count: 
   268 0000C5D3 00<rept>            <1> 		times 6 db 0
   269                              <1> str_dirs:       
   270 0000C5D9 206469726563746F72- <1> 		db " directory(s) "
   270 0000C5E2 7928732920          <1>
   271 0000C5E7 0D0A00              <1> 		db 0Dh, 0Ah, 0
   272                              <1> 
   273 0000C5EA 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   273 0000C5F3 696E2066696C652873- <1>
   273 0000C5FC 29                  <1>
   274 0000C5FD 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 0000C600 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   279 0000C609 696C65206F72206469- <1>
   279 0000C612 726563746F7279206E- <1>
   279 0000C61B 616D65206368617261- <1>
   279 0000C624 637465727321        <1>
   280 0000C62A 0D0A00              <1>         	db 0Dh, 0Ah, 0
   281                              <1> ; 21/02/2016
   282 0000C62D 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   282 0000C636 69726563746F727920- <1>
   282 0000C63F 6E616D652065786973- <1>
   282 0000C648 747321              <1>
   283 0000C64B 0D0A00              <1>                 db 0Dh, 0Ah, 0
   284                              <1> Msg_DoYouWantMkdir:
   285 0000C64E 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   285 0000C657 6E7420746F206D616B- <1>
   285 0000C660 65206469726563746F- <1>
   285 0000C669 72792000            <1>
   286 0000C66D 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   286 0000C676 00                  <1>
   287 0000C677 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   288 0000C67B 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   289                              <1> 
   290                              <1> ; 27/02/2016
   291                              <1> Msg_DoYouWantRmDir:
   292 0000C681 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   292 0000C68A 6E7420746F2064656C- <1>
   292 0000C693 657465206469726563- <1>
   292 0000C69C 746F72792000        <1>
   293                              <1> Msg_Dir_Not_Empty:
   294 0000C6A2 4469726563746F7279- <1>                 db "Directory not empty!"
   294 0000C6AB 206E6F7420656D7074- <1>
   294 0000C6B4 7921                <1>
   295 0000C6B6 0D0A00              <1>                 db 0Dh, 0Ah, 0
   296                              <1> 
   297                              <1> Msg_DoYouWantDelete:
   298 0000C6B9 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   298 0000C6C2 6E7420746F2064656C- <1>
   298 0000C6CB 6574652066696C6520- <1>
   298 0000C6D4 00                  <1>
   299                              <1> 
   300 0000C6D5 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   300 0000C6DE 2E0D0A00            <1>
   301                              <1> 
   302                              <1> Msg_Permission_Denied:
   303 0000C6E2 07                  <1>                 db 7
   304 0000C6E3 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   304 0000C6EC 6E2064656E69656421- <1>
   304 0000C6F5 0D0A00              <1>
   305                              <1> 
   306                              <1> ; 04/03/2016
   307 0000C6F8 4E657720            <1> Msg_New:        db "New "
   308 0000C6FC 00                  <1>                 db 0
   309                              <1> Str_Attributes:
   310 0000C6FD 417474726962757465- <1>                 db "Attributes : "
   310 0000C706 73203A20            <1>
   311 0000C70A 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   312 0000C710 00                  <1>                 db 0
   313                              <1> 
   314                              <1> ; 06/03/2016
   315                              <1> ; CMD_INTR.ASM - 16/11/2010 
   316                              <1> Msg_DoYouWantRename:
   317 0000C711 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   317 0000C71A 6E7420746F2072656E- <1>
   317 0000C723 616D652000          <1>
   318 0000C728 66696C652000        <1> Rename_File:    db "file ", 0
   319 0000C72E 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   319 0000C737 2000                <1>
   320 0000C739 00<rept>            <1> Rename_OldName: times 13 db 0
   321 0000C746 20617320            <1> Msg_File_rename_as: db " as "
   322 0000C74A 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 0000C757 4E6F742073616D6520- <1>                 db "Not same drive!" 
   327 0000C760 647269766521        <1>
   328 0000C766 0D0A00              <1>                 db 0Dh, 0Ah, 0 
   329                              <1> 
   330                              <1> Msg_DoYouWantMoveFile:
   331 0000C769 446F20796F75207761- <1>                 db "Do you want to move file", 0
   331 0000C772 6E7420746F206D6F76- <1>
   331 0000C77B 652066696C6500      <1>
   332                              <1> 
   333                              <1> msg_insufficient_disk_space:
   334 0000C782 496E73756666696369- <1>                 db "Insufficient disk space!" 
   334 0000C78B 656E74206469736B20- <1>
   334 0000C794 737061636521        <1>
   335 0000C79A 0D0A00              <1>                 db 0Dh, 0Ah, 0
   336                              <1> 
   337                              <1> ; 01/08/2010
   338                              <1> msg_source_file: 
   339 0000C79D 0D0A536F7572636520- <1> 		db 0Dh, 0Ah, "Source file name      :   "
   339 0000C7A6 66696C65206E616D65- <1>
   339 0000C7AF 2020202020203A2020- <1>
   339 0000C7B8 20                  <1>
   340                              <1> msg_source_file_drv: 
   341 0000C7B9 203A00              <1> 		db " :", 0
   342                              <1> msg_destination_file: 
   343 0000C7BC 0D0A44657374696E61- <1> 		db 0Dh, 0Ah, "Destination file name :   "
   343 0000C7C5 74696F6E2066696C65- <1>
   343 0000C7CE 206E616D65203A2020- <1>
   343 0000C7D7 20                  <1>
   344                              <1> msg_destination_file_drv: 
   345 0000C7D8 203A00              <1> 		db " :", 0
   346                              <1> msg_copy_nextline: 
   347 0000C7DB 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 0000C7DE 446F20796F75207761- <1>                 db "Do you want to overwrite file ",0
   353 0000C7E7 6E7420746F206F7665- <1>
   353 0000C7F0 727772697465206669- <1>
   353 0000C7F9 6C652000            <1>
   354                              <1>   
   355                              <1> Msg_DoYouWantCopyFile:
   356 0000C7FD 446F20796F75207761- <1>                 db "Do you want to copy file",0
   356 0000C806 6E7420746F20636F70- <1>
   356 0000C80F 792066696C6500      <1>
   357                              <1> 
   358                              <1> Msg_read_file_error_before_EOF:
   359 0000C816 46696C652072656164- <1> 		db "File reading error! (before EOF)"
   359 0000C81F 696E67206572726F72- <1>
   359 0000C828 2120286265666F7265- <1>
   359 0000C831 20454F4629          <1>
   360 0000C836 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 0000C839 52656164696E672E2E- <1> 		db "Reading... ", 0
   365 0000C842 2E2000              <1>
   366                              <1> msg_writing:
   367 0000C845 57726974696E672E2E- <1> 		db "Writing... ", 0
   367 0000C84E 2E2000              <1>
   368                              <1> percentagestr:
   369 0000C851 2020202500          <1> 		db "   %", 0  ; "  0%" .. "100%"
   370                              <1> ; 11/04/2016
   371                              <1> Msg_No_Set_Space:
   372 0000C856 496E73756666696369- <1>                 db "Insufficient environment space!"
   372 0000C85F 656E7420656E766972- <1>
   372 0000C868 6F6E6D656E74207370- <1>
   372 0000C871 61636521            <1>
   373 0000C875 0D0A00              <1>                 db 0Dh, 0Ah, 0
   374                              <1> ; 18/04/2016
   375                              <1> isc_msg:	
   376 0000C878 0D0A                <1> 		db 0Dh, 0Ah
   377 0000C87A 494E56414C49442053- <1> 		db "INVALID SYSTEM CALL", 0
   377 0000C883 595354454D2043414C- <1>
   377 0000C88C 4C00                <1>
   378                              <1> usi_msg:
   379 0000C88E 0D0A                <1> 		db 0Dh, 0Ah
   380 0000C890 554E444546494E4544- <1> 		db "UNDEFINED SOFTWARE INTERRUPT", 0
   380 0000C899 20534F465457415245- <1>
   380 0000C8A2 20494E544552525550- <1>
   380 0000C8AB 5400                <1>
   381                              <1> ifc_msg:
   382 0000C8AD 0D0A                <1> 		db 0Dh, 0Ah
   383 0000C8AF 494E56414C49442046- <1> 		db "INVALID FUNCTION CALL"
   383 0000C8B8 554E4354494F4E2043- <1>
   383 0000C8C1 414C4C              <1>
   384                              <1> inv_msg_for_trdos_v2:
   385 0000C8C4 20                  <1> 		db 20h
   386 0000C8C5 666F72205452444F53- <1> 		db "for TRDOS v2!"
   386 0000C8CE 20763221            <1>
   387 0000C8D2 07                  <1> 		db 07h
   388 0000C8D3 0D0A                <1> 		db 0Dh, 0Ah
   389 0000C8D5 0D0A                <1> 		db 0Dh, 0Ah
   390 0000C8D7 494E5420            <1> 		db "INT "
   391 0000C8DB 303068              <1> int_num_str:	db "00h"
   392 0000C8DE 0D0A                <1> 		db 0Dh, 0Ah
   393 0000C8E0 454158203A20        <1> 		db "EAX : "
   394 0000C8E6 303030303030303068- <1> eax_str:	db "00000000h", 0Dh, 0Ah
   394 0000C8EF 0D0A                <1>
   395 0000C8F1 454950203A20        <1> 		db "EIP : "
   396 0000C8F7 303030303030303068- <1> eip_str:	db "00000000h", 0Dh, 0Ah, 0
   396 0000C900 0D0A00              <1>
   397                              <1> 		
  1886                                  
  1887                                  ; 15/04/2016
  1888                                  ; TRDOS 386 (TRDOS v2.0)
  1889                                  
  1890                                  ; 29/04/2016
  1891                                  int30h:
  1892                                  trdos_isc_routine:
  1893                                  	; 02/05/2016
  1894                                  	; 01/05/2016
  1895                                  	; 29/04/2016
  1896                                  	; 18/04/2016
  1897                                  	; 15/04/2016 (TRDOS 386 = TRDOS v2.0)
  1898                                  	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
  1899                                  	; 03/02/2011 ('trdos_ifc_routine')
  1900                                  	;
  1901 0000C903 8B1C24                  	mov	ebx, [esp] ; EIP (next)
  1902 0000C906 83EB02                  	sub	ebx, 2 ; EIP (CD ##h)
  1903                                  
  1904 0000C909 89C1                    	mov	ecx, eax
  1905 0000C90B 8A4301                  	mov	al, [ebx+1] ; CDh ##h
  1906                                  
  1907 0000C90E 66BA1000                	mov	dx, KDATA
  1908 0000C912 8EDA                    	mov	ds, dx
  1909 0000C914 8EC2                    	mov	es, dx
  1910                                  
  1911 0000C916 FC                      	cld
  1912 0000C917 8B15[88D20000]          	mov	edx, [k_page_dir]
  1913 0000C91D 0F22DA                  	mov	cr3, edx
  1914                                  
  1915 0000C920 E8A94FFFFF              	call	bytetohex
  1916 0000C925 66A3[DBC80000]          	mov	[int_num_str], ax
  1917                                  
  1918 0000C92B 89D8                    	mov	eax, ebx ; EIP
  1919 0000C92D E8DC4FFFFF              	call	dwordtohex
  1920 0000C932 8915[F7C80000]          	mov	[eip_str], edx
  1921 0000C938 A3[FBC80000]            	mov	[eip_str+4], eax
  1922                                  
  1923 0000C93D 89C8                    	mov	eax, ecx
  1924 0000C93F E8CA4FFFFF              	call	dwordtohex
  1925 0000C944 8915[E6C80000]          	mov	[eax_str], edx
  1926 0000C94A A3[EAC80000]            	mov	[eax_str+4], eax 	
  1927                                  
  1928 0000C94F 43                      	inc	ebx
  1929 0000C950 8A03                    	mov	al, [ebx] ; Interrupt number
  1930                                  
  1931                                  trdos_isc_handler:
  1932 0000C952 80FE30                  	cmp	dh, 30h ; Retro UNIX, SINGLIX System calls
  1933 0000C955 7507                    	jne	short trdos_usi_handler
  1934 0000C957 BE[78C80000]            	mov	esi, isc_msg
  1935 0000C95C EB05                    	jmp	short loc_write_inv_system_call_msg
  1936                                  
  1937                                  trdos_usi_handler:
  1938 0000C95E BE[8EC80000]            	mov	esi, usi_msg
  1939                                  
  1940                                  loc_write_inv_system_call_msg:
  1941 0000C963 E84C76FFFF              	call	print_msg
  1942                                  	; 29/04/2016
  1943 0000C968 BE[C4C80000]            	mov	esi, inv_msg_for_trdos_v2
  1944 0000C96D E84276FFFF              	call	print_msg
  1945                                  
  1946                                  loc_ifc_terminate_process:
  1947                                  	; u.uno = process number
  1948                                  	; 29/04/2016
  1949                                  
  1950                                  	; 02/05/2016
  1951 0000C972 FE05[3FE30000]          	inc	byte [sysflg] ; 0FFh -> 0
  1952                                  
  1953 0000C978 B801000000              	mov	eax, 1
  1954 0000C97D E90ED8FFFF              	jmp	sysexit
  1955                                  
  1956                                  ; 07/03/2015
  1957                                  ; Temporary Code
  1958                                  display_disks:
  1959 0000C982 803D[8ECD0000]00        	cmp 	byte [fd0_type], 0
  1960 0000C989 7605                    	jna 	short ddsks1
  1961 0000C98B E87D000000              	call	pdskm
  1962                                  ddsks1:
  1963 0000C990 803D[8FCD0000]00        	cmp	byte [fd1_type], 0
  1964 0000C997 760C                    	jna	short ddsks2
  1965 0000C999 C605[0FCF0000]31        	mov	byte [dskx], '1'
  1966 0000C9A0 E868000000              	call	pdskm
  1967                                  ddsks2:
  1968 0000C9A5 803D[90CD0000]00        	cmp	byte [hd0_type], 0
  1969 0000C9AC 7654                    	jna	short ddsk6
  1970 0000C9AE 66C705[0DCF0000]68-     	mov	word [dsktype], 'hd'
  1970 0000C9B6 64                 
  1971 0000C9B7 C605[0FCF0000]30        	mov	byte [dskx], '0'
  1972 0000C9BE E84A000000              	call	pdskm
  1973                                  ddsks3:
  1974 0000C9C3 803D[91CD0000]00        	cmp	byte [hd1_type], 0
  1975 0000C9CA 7636                    	jna	short ddsk6
  1976 0000C9CC C605[0FCF0000]31        	mov	byte [dskx], '1'
  1977 0000C9D3 E835000000              	call	pdskm
  1978                                  ddsks4:
  1979 0000C9D8 803D[92CD0000]00        	cmp	byte [hd2_type], 0
  1980 0000C9DF 7621                    	jna	short ddsk6
  1981 0000C9E1 C605[0FCF0000]32        	mov	byte [dskx], '2'
  1982 0000C9E8 E820000000              	call	pdskm
  1983                                  ddsks5:
  1984 0000C9ED 803D[93CD0000]00        	cmp	byte [hd3_type], 0
  1985 0000C9F4 760C                    	jna	short ddsk6
  1986 0000C9F6 C605[0FCF0000]33        	mov	byte [dskx], '3'
  1987 0000C9FD E80B000000              	call	pdskm
  1988                                  ddsk6:
  1989 0000CA02 BE[20CF0000]            	mov	esi, nextline
  1990 0000CA07 E806000000              	call	pdskml
  1991                                  pdskm_ok:
  1992 0000CA0C C3                      	retn
  1993                                  pdskm:
  1994 0000CA0D BE[0BCF0000]            	mov	esi, dsk_ready_msg
  1995                                  pdskml:	
  1996 0000CA12 AC                      	lodsb
  1997 0000CA13 08C0                    	or	al, al
  1998 0000CA15 74F5                    	jz	short pdskm_ok
  1999 0000CA17 56                      	push	esi
  2000                                  	; 13/05/2016
  2001 0000CA18 BB07000000                      mov     ebx, 7  ; Black background, 
  2002                                  			; light gray forecolor
  2003                                  			; Video page 0 (bh=0)
  2004 0000CA1D E8C64CFFFF              	call	_write_tty
  2005 0000CA22 5E                      	pop	esi
  2006 0000CA23 EBED                    	jmp	short pdskml
  2007                                  
  2008 0000CA25 90<rept>                align 16
  2009                                  
  2010                                  gdt:	; Global Descriptor Table
  2011                                  	; (30/07/2015, conforming cs)
  2012                                  	; (26/03/2015)
  2013                                  	; (24/03/2015, tss)
  2014                                  	; (19/03/2015)
  2015                                  	; (29/12/2013)
  2016                                  	;
  2017 0000CA30 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  2018                                  	; 18/08/2014
  2019                                  			; 8h kernel code segment, base = 00000000h		
  2020 0000CA38 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2021                                  			; 10h kernel data segment, base = 00000000h	
  2022 0000CA40 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2023                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2024 0000CA48 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  2025                                  			; 23h user data segment, base address = 400000h ; CORE
  2026 0000CA50 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2027                                  			; Task State Segment
  2028 0000CA58 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2029                                  			       ;  no IO permission in ring 3)
  2030                                  gdt_tss0:
  2031 0000CA5A 0000                    	dw 0  ; TSS base address, bits 0-15 
  2032                                  gdt_tss1:
  2033 0000CA5C 00                      	db 0  ; TSS base address, bits 16-23 
  2034                                  	      		; 49h	
  2035 0000CA5D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2036 0000CA5E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2037                                  gdt_tss2:
  2038 0000CA5F 00                      	db 0  ; TSS base address, bits 24-31 
  2039                                  
  2040                                  gdt_end:
  2041                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2042                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2043                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2044                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2045                                  
  2046                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2047                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2048                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2049                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2050                                  		; W= Writeable, A= Accessed
  2051                                  	
  2052                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2053                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2054                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2055                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2056                                  
  2057                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2058                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2059                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2060                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2061                                  	
  2062                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2063                                  
  2064                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2065                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2066                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2067                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2068                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2069                                  		; AVL= Available to programmers	
  2070                                  
  2071                                  gdtd:
  2072 0000CA60 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2073 0000CA62 [30CA0000]                      dd gdt			; Address of the GDT
  2074                                  
  2075                                  	; 20/08/2014
  2076                                  idtd:
  2077 0000CA66 7F02                            dw idt_end - idt - 1    ; Limit (size)
  2078 0000CA68 [A0CF0000]                      dd idt			; Address of the IDT
  2079                                  
  2080                                  Align 4
  2081                                  	; 15/04/2016
  2082                                  	; TRDOS 386 (TRDOS v2.0)
  2083                                  
  2084                                  	; 21/08/2014
  2085                                  ilist:
  2086                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  2087                                  	;
  2088                                  	; Exception list
  2089                                  	; 25/08/2014	
  2090 0000CA6C [35080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2091 0000CA70 [3C080000]              	dd	exc1	
  2092 0000CA74 [43080000]              	dd 	exc2	
  2093 0000CA78 [4A080000]              	dd	exc3	
  2094 0000CA7C [4E080000]              	dd	exc4	
  2095 0000CA80 [52080000]              	dd	exc5	
  2096 0000CA84 [56080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2097 0000CA88 [5A080000]              	dd	exc7	
  2098 0000CA8C [5E080000]              	dd	exc8	
  2099 0000CA90 [62080000]              	dd	exc9	
  2100 0000CA94 [66080000]              	dd 	exc10	
  2101 0000CA98 [6A080000]              	dd	exc11
  2102 0000CA9C [6E080000]              	dd	exc12
  2103 0000CAA0 [72080000]              	dd	exc13	; 0Dh, General Protection Fault
  2104 0000CAA4 [76080000]              	dd 	exc14	; 0Eh, Page Fault
  2105 0000CAA8 [7A080000]              	dd	exc15
  2106 0000CAAC [7E080000]              	dd	exc16
  2107 0000CAB0 [82080000]              	dd	exc17
  2108 0000CAB4 [86080000]              	dd 	exc18
  2109 0000CAB8 [8A080000]              	dd	exc19
  2110 0000CABC [8E080000]              	dd 	exc20
  2111 0000CAC0 [92080000]              	dd	exc21
  2112 0000CAC4 [96080000]              	dd	exc22
  2113 0000CAC8 [9A080000]              	dd	exc23
  2114 0000CACC [9E080000]              	dd 	exc24
  2115 0000CAD0 [A2080000]              	dd	exc25
  2116 0000CAD4 [A6080000]              	dd	exc26
  2117 0000CAD8 [AA080000]              	dd	exc27
  2118 0000CADC [AE080000]              	dd 	exc28
  2119 0000CAE0 [B2080000]              	dd	exc29
  2120 0000CAE4 [B6080000]              	dd 	exc30
  2121 0000CAE8 [BA080000]              	dd	exc31
  2122                                  	; Interrupt list
  2123 0000CAEC [2A060000]              	dd	timer_int	; INT 20h
  2124                                  		;dd	irq0	
  2125 0000CAF0 [7C0C0000]              	dd	kb_int		; 24/01/2016
  2126                                  		;dd	irq1
  2127 0000CAF4 [8B070000]              	dd	irq2
  2128                                  		; COM2 int
  2129 0000CAF8 [8F070000]              	dd	irq3
  2130                                  		; COM1 int
  2131 0000CAFC [9A070000]              	dd	irq4
  2132 0000CB00 [A5070000]              	dd	irq5
  2133                                  ;DISKETTE_INT: ;06/02/2015
  2134 0000CB04 [B0270000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  2135                                  		;dd	irq6
  2136                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2137                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2138 0000CB08 [7C0A0000]              	dd	default_irq7	; 25/02/2015
  2139                                  		;dd	irq7
  2140                                  ; Real Time Clock Interrupt
  2141 0000CB0C [06070000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2142                                  		;dd	irq8	; INT 28h
  2143 0000CB10 [B5070000]              	dd	irq9
  2144 0000CB14 [B9070000]              	dd	irq10
  2145 0000CB18 [BD070000]              	dd	irq11
  2146 0000CB1C [C1070000]              	dd	irq12
  2147 0000CB20 [C5070000]              	dd	irq13
  2148                                  ;HDISK_INT1:  ;06/02/2015 	
  2149 0000CB24 [14310000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2150                                  		;dd	irq14
  2151                                  ;HDISK_INT2:  ;06/02/2015
  2152 0000CB28 [3B310000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  2153                                  		;dd	irq15	; INT 2Fh
  2154                                  		; 14/08/2015
  2155                                  	;dd	sysent		; INT 30h (system calls)
  2156                                  
  2157                                  	; 15/04/2016
  2158                                  	; TRDOS 386(TRDOS v2.0) Software Interrupts
  2159                                  
  2160 0000CB2C [03C90000]              	dd	int30h		; Reserved for
  2161                                  				; !!! Retro UNIX (RUNIX) !!!
  2162                                  				; !!! SINGLIX !!! System Calls
  2163 0000CB30 [6F130000]              	dd	int31h		; Video BIOS (IBM PC/AT, Int 10h)
  2164 0000CB34 [A40A0000]              	dd	int32h		; Keyboard Functions (IBM PC/AT, Int 16h)
  2165 0000CB38 [66280000]              	dd	int33h		; DISK I/O (IBM PC/AT, Int 13h)
  2166 0000CB3C [BBBF0000]              	dd	int34h		; #IOCTL# (I/O port access support for ring 3)
  2167 0000CB40 [FE3B0000]              	dd	int35h		; Time/Date Functions (IBM PC/AT, Int 1Ah)
  2168 0000CB44 [8B090000]              	dd	ignore_int	; INT 36h : Timer Functions	
  2169 0000CB48 [8B090000]              	dd	ignore_int	; INT 37h	
  2170 0000CB4C [8B090000]              	dd	ignore_int	; INT 38h
  2171 0000CB50 [8B090000]              	dd	ignore_int	; INT 39h
  2172 0000CB54 [8B090000]              	dd	ignore_int	; INT 3Ah	
  2173 0000CB58 [8B090000]              	dd	ignore_int	; INT 3Bh
  2174 0000CB5C [8B090000]              	dd	ignore_int	; INT 3Ch
  2175 0000CB60 [8B090000]              	dd	ignore_int	; INT 3Dh	
  2176 0000CB64 [8B090000]              	dd	ignore_int	; INT 3Eh
  2177 0000CB68 [8B090000]              	dd	ignore_int	; INT 3Fh
  2178 0000CB6C [7F9F0000]              	dd	sysent		; INT 40h : !!! TRDOS 386 System Calls !!!
  2179                                  	;dd	ignore_int
  2180 0000CB70 00000000                	dd	0
  2181                                  ;;;
  2182                                  ;;; 11/03/2015
  2183                                  %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 0000CB74 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000CB79 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 0000CB7E 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 0000CB84 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000CB8A 202122232425        <1> 	db	32,33,34,35,36,37
    41 0000CB90 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000CB96 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000CB98 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000CB99 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 0000CB9E 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 0000CBA0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 0000CBA1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000CBA6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000CBA8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 0000CBAE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 0000CBB4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000CBBA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 0000CBC0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000CBC6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 0000CBCC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 0000CBD2 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000CBD8 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 0000CBDE 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 0000CBE2 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000CBE8 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 0000CBEE 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 0000CBF4 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 0000CBFA 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 0000CC00 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 0000CC09 39302D3D0809        <1>
    76 0000CC0F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 0000CC18 705B5D0DFF61736466- <1>
    76 0000CC21 67686A6B6C3B27      <1>
    77 0000CC28 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 0000CC31 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 0000CC3A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 0000CC3F 4041424344          <1> 	db	64,65,66,67,68
    81 0000CC44 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 0000CC46 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 0000CC4C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 0000CC53 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000CC58 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 0000CC61 28295F2B0800        <1>
    90 0000CC67 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 0000CC70 507B7D0DFF41534446- <1>
    90 0000CC79 47484A4B4C3A22      <1>
    91 0000CC80 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000CC89 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 0000CC92 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000CC97 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 0000CC9C FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 0000CC9E 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000CCA7 3233302E            <1>
    99                              <1> 	;
   100 0000CCAB 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 0000CCB0 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 0000CCB1 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 0000CCB2 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 0000CCB3 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 0000CCB4 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 0000CCB5 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000CCB6 [C6CC0000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000CCBA [E6CC0000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 0000CCBE [C6CC0000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 0000CCC2 [C6CC0000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000CCC6 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
   128                              <1> 
   129                              <1> ; /// End Of KEYBOARD DATA ///
  2184                                  %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 0000CCE6 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
    37 0000CCE7 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 0000CCE8 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
    63 0000CCEF 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
    64 0000CCF4 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 0000CCF8 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    69                              <1> ; 30/01/2016
    70                              <1> vmode:
    71 0000CD00 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    72                              <1> 
    73                              <1> ; /// End Of VIDEO DATA ///
  2185                                  %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 0000CD08 [6BCD0000]          <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 0000CD0C 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 0000CD0D [2ACD0000]          <1> 		dd	MD_TBL1
   115 0000CD11 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000CD12 [37CD0000]          <1>                 dd      MD_TBL2
   118 0000CD16 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 0000CD17 [44CD0000]          <1> 		dd      MD_TBL3
   121 0000CD1B 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 0000CD1C [51CD0000]          <1> 		dd      MD_TBL4
   124 0000CD20 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000CD21 [5ECD0000]          <1> 		dd      MD_TBL5
   127 0000CD25 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 0000CD26 [6BCD0000]          <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 0000CD2A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 0000CD2B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 0000CD2C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 0000CD2D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000CD2E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000CD2F 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000CD30 FF                  <1> 	DB	0FFH		; DTL
   147 0000CD31 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000CD32 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000CD33 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 0000CD34 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 0000CD35 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 0000CD36 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 0000CD37 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 0000CD38 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 0000CD39 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 0000CD3A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 0000CD3B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 0000CD3C 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 0000CD3D FF                  <1> 	DB	0FFH		; DTL
   164 0000CD3E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000CD3F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000CD40 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000CD41 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000CD42 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000CD43 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 0000CD44 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 0000CD45 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 0000CD46 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 0000CD47 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 0000CD48 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 0000CD49 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 0000CD4A FF                  <1> 	DB	0FFH		; DTL
   181 0000CD4B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 0000CD4C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 0000CD4D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000CD4E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000CD4F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000CD50 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 0000CD51 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000CD52 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000CD53 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 0000CD54 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 0000CD55 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 0000CD56 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 0000CD57 FF                  <1> 	DB	0FFH		; DTL
   198 0000CD58 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 0000CD59 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 0000CD5A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 0000CD5B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 0000CD5C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 0000CD5D 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 0000CD5E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000CD5F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000CD60 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000CD61 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000CD62 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000CD63 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 0000CD64 FF                  <1> 	DB	0FFH		; DTL
   215 0000CD65 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 0000CD66 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 0000CD67 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 0000CD68 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 0000CD69 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 0000CD6A 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 0000CD6B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 0000CD6C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 0000CD6D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 0000CD6E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 0000CD6F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 0000CD70 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 0000CD71 FF                  <1> 	DB	0FFH		; DTL
   232 0000CD72 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 0000CD73 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 0000CD74 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 0000CD75 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 0000CD76 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 0000CD77 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 0000CD78 E0                  <1> 	db	NO_ERR
   280 0000CD79 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 0000CD7D 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 0000CD81 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 0000CD82 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 0000CD83 90                  <1> align 2
   293                              <1> 
   294 0000CD84 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 0000CD86 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 0000CD88 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2186                                  ;;;
  2187                                  
  2188 0000CD89 90                      Align 2
  2189                                  
  2190                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2191 0000CD8A 00                      boot_drv:    db 0 ; boot drive number (physical)
  2192                                  ; 24/11/2014
  2193 0000CD8B 00                      drv:	     db 0 
  2194 0000CD8C 00                      last_drv:    db 0 ; last hdd
  2195 0000CD8D 00                      hdc:         db 0  ; number of hard disk drives
  2196                                  		     ; (present/detected)
  2197                                  ;
  2198                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2199                                  ; Physical drive type & flags
  2200 0000CD8E 00                      fd0_type:    db 0  ; floppy drive type
  2201 0000CD8F 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2202                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2203                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2204                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2205                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2206 0000CD90 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  2207 0000CD91 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  2208 0000CD92 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  2209 0000CD93 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
  2210                                  		     ; bit 0 - Fixed disk access subset supported
  2211                                  		     ; bit 1 - Drive locking and ejecting
  2212                                  		     ; bit 2 - Enhanced disk drive support
  2213                                  		     ; bit 3 = Reserved (64 bit EDD support)
  2214                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  2215                                  		     ; will interpret it as 'LBA ready'!)		
  2216                                  
  2217                                  ; 11/03/2015 - 10/07/2015
  2218 0000CD94 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  2218 0000CD9D 0000000000         
  2219 0000CDA2 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  2219 0000CDAB 0000000000         
  2220 0000CDB0 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  2220 0000CDB9 0000000000         
  2221 0000CDBE 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2221 0000CDC7 000000000000000000-
  2221 0000CDD0 000000000000000000-
  2221 0000CDD9 00                 
  2222 0000CDDA 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2223 0000CDE1 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
  2224                                  ;
  2225                                  
  2226                                  ; 27/08/2014
  2227                                  scr_row:
  2228 0000CDE8 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2229                                  scr_col:
  2230 0000CDEC 00000000                	dd 0
  2231                                  
  2232                                  ; 20/08/2014
  2233                                    ; /* This is the default interrupt "handler" :-) */ 
  2234                                    ; Linux v0.12 (head.s)
  2235                                  int_msg:
  2236 0000CDF0 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2236 0000CDF9 6E7465727275707420-
  2236 0000CE02 212000             
  2237                                  
  2238 0000CE05 90                      Align 2
  2239                                  	; 21/08/2014
  2240                                  exc_msg:
  2241 0000CE06 435055206578636570-     	db "CPU exception ! "
  2241 0000CE0F 74696F6E202120     
  2242                                  excnstr: 		; 25/08/2014
  2243 0000CE16 3F3F68202045495020-     	db "??h", "  EIP : "
  2243 0000CE1F 3A20               
  2244                                  EIPstr: ; 29/08/2014
  2245 0000CE21 00<rept>                	times 12 db 0
  2246                                  
  2247                                  	; 23/02/2015
  2248                                  	; 25/08/2014
  2249                                  ;scounter:
  2250                                  ;	db 5
  2251                                  ;	db 19
  2252                                  
  2253                                  ; 05/11/2014
  2254                                  msg_out_of_memory:
  2255 0000CE2D 070D0A                  	db 	07h, 0Dh, 0Ah
  2256 0000CE30 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2256 0000CE39 656E74206D656D6F72-
  2256 0000CE42 79202120284D696E69-
  2256 0000CE4B 6D756D2032204D4220-
  2256 0000CE54 6D656D6F7279206973-
  2256 0000CE5D 206E65656465642E29 
  2257 0000CE66 0D0A00                   	db	0Dh, 0Ah, 0
  2258                                  	;
  2259                                  setup_error_msg:
  2260 0000CE69 0D0A                    	db 0Dh, 0Ah
  2261 0000CE6B 4469736B2053657475-     	db 'Disk Setup Error!' 
  2261 0000CE74 70204572726F7221   
  2262 0000CE7C 0D0A00                  	db 0Dh, 0Ah,0
  2263                                  
  2264                                  ; 06/11/2014
  2265                                  ; Memory Information message
  2266                                  ; 14/08/2015
  2267                                  msg_memory_info:
  2268 0000CE7F 07                      	db	07h
  2269 0000CE80 0D0A                    	db	0Dh, 0Ah
  2270                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2271 0000CE82 546F74616C206D656D-     	db	"Total memory : "
  2271 0000CE8B 6F7279203A20       
  2272                                  mem_total_b_str: ; 10 digits
  2273 0000CE91 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2273 0000CE9A 302062797465730D0A 
  2274 0000CEA3 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2274 0000CEAC 202020202020202020 
  2275                                  mem_total_p_str: ; 7 digits
  2276 0000CEB5 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2276 0000CEBE 616765730D0A       
  2277 0000CEC4 0D0A                    	db 	0Dh, 0Ah
  2278 0000CEC6 46726565206D656D6F-     	db	"Free memory  : "
  2278 0000CECF 727920203A20       
  2279                                  free_mem_b_str:  ; 10 digits
  2280 0000CED5 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2280 0000CEDE 3F2062797465730D0A 
  2281 0000CEE7 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2281 0000CEF0 202020202020202020 
  2282                                  free_mem_p_str:  ; 7 digits
  2283 0000CEF9 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2283 0000CF02 616765730D0A       
  2284 0000CF08 0D0A00                  	db	0Dh, 0Ah, 0
  2285                                  
  2286                                  dsk_ready_msg:
  2287 0000CF0B 0D0A                    	db 	0Dh, 0Ah
  2288                                  dsktype:
  2289 0000CF0D 6664                    	db	'fd'
  2290                                  dskx:
  2291 0000CF0F 30                      	db	'0'
  2292 0000CF10 20                      	db	20h
  2293 0000CF11 697320524541445920-     	db 	'is READY ...'
  2293 0000CF1A 2E2E2E             
  2294 0000CF1D 00                      	db 	0
  2295                                  
  2296                                  next2line: ; 08/02/2016
  2297 0000CF1E 0D0A                    	db	0Dh, 0Ah
  2298                                  nextline:
  2299 0000CF20 0D0A00                  	db 	0Dh, 0Ah, 0
  2300                                  
  2301                                  ; KERNEL - SYSINIT Messages
  2302                                  ; 24/08/2015
  2303                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  2304                                  ; 14/07/2013
  2305                                  ;kernel_init_err_msg:
  2306                                  ;	db 0Dh, 0Ah
  2307                                  ;	db 07h
  2308                                  ;	db 'Kernel initialization ERROR !'
  2309                                  ;	db 0Dh, 0Ah, 0 
  2310                                  
  2311                                  ;welcome_msg: 
  2312                                  ;	db 0Dh, 0Ah
  2313                                  ;	db 07h
  2314                                  ;	db 'Welcome to TRDOS 386 Operating System !'
  2315                                  ;	db 0Dh, 0Ah
  2316                                  ;	db 'by Erdogan Tan - 29/05/2016 (v2.0.0)'
  2317                                  ;	db 0Dh, 0Ah, 0
  2318                                  
  2319                                  panic_msg:
  2320 0000CF23 0D0A07                  	db 0Dh, 0Ah, 07h
  2321 0000CF26 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2321 0000CF2F 726E656C2050616E69-
  2321 0000CF38 632021             
  2322 0000CF3B 0D0A00                  	db 0Dh, 0Ah, 0
  2323                                  
  2324                                  align 2
  2325                                  
  2326                                  ; EPOCH Variables
  2327                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  2328                                  ; 09/04/2013 epoch variables
  2329                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  2330                                  ;
  2331 0000CF3E B207                    year: 	dw 1970
  2332 0000CF40 0100                    month: 	dw 1
  2333 0000CF42 0100                    day: 	dw 1
  2334 0000CF44 0000                    hour: 	dw 0
  2335 0000CF46 0000                    minute: dw 0
  2336 0000CF48 0000                    second: dw 0
  2337                                  
  2338                                  DMonth:
  2339 0000CF4A 0000                    	dw 0
  2340 0000CF4C 1F00                    	dw 31
  2341 0000CF4E 3B00                    	dw 59
  2342 0000CF50 5A00                    	dw 90
  2343 0000CF52 7800                    	dw 120
  2344 0000CF54 9700                    	dw 151
  2345 0000CF56 B500                    	dw 181
  2346 0000CF58 D400                    	dw 212
  2347 0000CF5A F300                    	dw 243
  2348 0000CF5C 1101                    	dw 273
  2349 0000CF5E 3001                    	dw 304
  2350 0000CF60 4E01                    	dw 334
  2351                                  
  2352                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2353 0000CF62 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2354                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2355 0000CF64 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2356                                  		   ;   between 16 MB and 4 GB.
  2357                                  
  2358                                  starting_msg:
  2359 0000CF66 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [29/05/2016] ...", 0
  2359 0000CF6F 6174696F6E616C2044-
  2359 0000CF78 4F532076322E30205B-
  2359 0000CF81 32392F30352F323031-
  2359 0000CF8A 365D202E2E2E00     
  2360                                  NextLine:
  2361 0000CF91 0D0A00                  	db 0Dh, 0Ah, 0
  2362                                  
  2363                                  ;msgl_drv_not_ready: 
  2364                                  ;	db 07h, 0Dh, 0Ah
  2365                                  ;       db 'Drive not ready or read error !'
  2366                                  ;       db 0Dh, 0Ah, 0
  2367                                  
  2368 0000CF94 90<rept>                align 16
  2369                                  
  2370                                  bss_start:
  2371                                  
  2372                                  ABSOLUTE bss_start
  2373                                  
  2374                                  	; 15/04/2016
  2375                                  	; TRDOS 386 (TRDOS v2.0)
  2376                                  	; 	80 interrupts 	
  2377                                  	; 11/03/2015
  2378                                  	; Interrupt Descriptor Table (20/08/2014)
  2379                                  idt:
  2380                                  	;resb	64*8 ; INT 0 to INT 3Fh
  2381                                  	; 15/04/2016
  2382 0000CFA0 <res 00000280>          	resb	80*8 ; INT 0 to INT 4Fh
  2383                                  
  2384                                  idt_end:
  2385                                  
  2386                                  ;alignb 4
  2387                                  
  2388                                  task_state_segment:
  2389                                  	; 24/03/2015
  2390 0000D220 <res 00000002>          tss.link:   resw 1
  2391 0000D222 <res 00000002>          	    resw 1
  2392                                  ; tss offset 4	
  2393 0000D224 <res 00000004>          tss.esp0:   resd 1
  2394 0000D228 <res 00000002>          tss.ss0:    resw 1
  2395 0000D22A <res 00000002>          	    resw 1	
  2396 0000D22C <res 00000004>          tss.esp1:   resd 1
  2397 0000D230 <res 00000002>          tss.ss1:    resw 1
  2398 0000D232 <res 00000002>          	    resw 1 	
  2399 0000D234 <res 00000004>          tss.esp2:   resd 1
  2400 0000D238 <res 00000002>          tss.ss2:    resw 1
  2401 0000D23A <res 00000002>          	    resw 1
  2402                                  ; tss offset 28
  2403 0000D23C <res 00000004>          tss.CR3:    resd 1
  2404 0000D240 <res 00000004>          tss.eip:    resd 1
  2405 0000D244 <res 00000004>          tss.eflags: resd 1
  2406                                  ; tss offset 40
  2407 0000D248 <res 00000004>          tss.eax:    resd 1		 		
  2408 0000D24C <res 00000004>          tss.ecx:    resd 1
  2409 0000D250 <res 00000004>          tss.edx:    resd 1
  2410 0000D254 <res 00000004>          tss.ebx:    resd 1
  2411 0000D258 <res 00000004>          tss.esp:    resd 1
  2412 0000D25C <res 00000004>          tss.ebp:    resd 1
  2413 0000D260 <res 00000004>          tss.esi:    resd 1
  2414 0000D264 <res 00000004>          tss.edi:    resd 1
  2415                                  ; tss offset 72
  2416 0000D268 <res 00000002>          tss.ES:     resw 1
  2417 0000D26A <res 00000002>          	    resw 1	
  2418 0000D26C <res 00000002>          tss.CS:	    resw 1
  2419 0000D26E <res 00000002>          	    resw 1
  2420 0000D270 <res 00000002>          tss.SS:	    resw 1
  2421 0000D272 <res 00000002>          	    resw 1
  2422 0000D274 <res 00000002>          tss.DS:	    resw 1
  2423 0000D276 <res 00000002>          	    resw 1
  2424 0000D278 <res 00000002>          tss.FS:	    resw 1
  2425 0000D27A <res 00000002>          	    resw 1
  2426 0000D27C <res 00000002>          tss.GS:	    resw 1
  2427 0000D27E <res 00000002>          	    resw 1		
  2428 0000D280 <res 00000002>          tss.LDTR:   resw 1
  2429 0000D282 <res 00000002>          	    resw 1
  2430                                  ; tss offset 100		
  2431 0000D284 <res 00000002>          	    resw 1		
  2432 0000D286 <res 00000002>          tss.IOPB:   resw 1
  2433                                  ; tss offset 104 
  2434                                  tss_end:
  2435                                  
  2436 0000D288 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2437                                  		    ; (Physical address = Virtual address)	 	
  2438 0000D28C <res 00000004>          memory_size: resd 1 ; memory size in pages
  2439 0000D290 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  2440 0000D294 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  2441                                  		    ; first free page search
  2442 0000D298 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
  2443                                  		    ; next free page search will be
  2444                                  		    ; stopped after it. (end of M.A.T.)
  2445 0000D29C <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
  2446                                  		    ; first free page search
  2447                                  		    ; will be started on it. (for user)
  2448 0000D2A0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
  2449                                  
  2450                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2451                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  2452 0000D2A4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  2453                                  			  ; NOTE: active page only	
  2454 0000D2A6 <res 00000002>          CURSOR_MODE: resw 1 ; 24/01/2016
  2455 0000D2A8 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  2456                                  ACTIVE_PAGE: 
  2457 0000D2B8 <res 00000001>          ptty: 	     resb 1 ; current tty
  2458                                  ; 01/07/2015 - 29/01/2016
  2459 0000D2B9 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  2460                                  ; 26/10/2015
  2461                                  ; 07/09/2014
  2462 0000D2BA <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  2463                                  
  2464                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2465 0000D2CE <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
  2466                                  
  2467                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  2468                                  ; (open mode locks for pseudo TTYs)
  2469                                  ; [ major tty locks (return error in any conflicts) ]
  2470 0000D2D2 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
  2471                                  
  2472                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2473                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  2474 0000D2E6 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  2475                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2476                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  2477                                  ;; 0 means serial port is not available 
  2478                                  ;;comprm: ; 25/06/2014
  2479 0000D2F0 <res 00000001>          com1p:       resb 1  ;;0E3h
  2480 0000D2F1 <res 00000001>          com2p:       resb 1  ;;0E3h
  2481                                  
  2482                                  ; 17/11/2015
  2483                                  ; request for response (from the terminal)	
  2484 0000D2F2 <res 00000002>          req_resp:    resw 1 			
  2485                                  ; 07/11/2015
  2486 0000D2F4 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  2487                                  		    ; (0= COM1, 1= COM2)
  2488                                  ; 09/11/2015
  2489 0000D2F5 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2490                                  ; 07/11/2015
  2491 0000D2F6 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2492 0000D2F8 <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2493                                  
  2494                                  ; 22/08/2014 (RTC)
  2495                                  ; (Packed BCD)
  2496 0000D2FA <res 00000001>          time_seconds: resb 1
  2497 0000D2FB <res 00000001>          time_minutes: resb 1
  2498 0000D2FC <res 00000001>          time_hours:   resb 1
  2499 0000D2FD <res 00000001>          date_wday:    resb 1
  2500 0000D2FE <res 00000001>          date_day:     resb 1
  2501 0000D2FF <res 00000001>          date_month:   resb 1			
  2502 0000D300 <res 00000001>          date_year:    resb 1
  2503 0000D301 <res 00000001>          date_century: resb 1
  2504                                  
  2505                                  ; 24/01/2016
  2506 0000D302 <res 00000004>          RTC_LH:	       resd 1
  2507 0000D306 <res 00000001>          RTC_WAIT_FLAG: resb 1
  2508 0000D307 <res 00000001>          USER_FLAG:     resb 1
  2509                                  ; 19/05/2016
  2510                                  ;RTC_second:
  2511 0000D308 <res 00000001>          RTC_2Hz:       resb 1 ;  from 2Hz interrupt to 1Hz timer event function	
  2512                                  
  2513                                  %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 0000D309 <res 00000001>      <1> alignb 2
    24                              <1> 
    25                              <1> ;----------------------------------------
    26                              <1> ;	TIMER DATA AREA 		:
    27                              <1> ;----------------------------------------
    28                              <1> 
    29                              <1> TIMER_LH:	; 16/02/205
    30 0000D30A <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0000D30C <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0000D30E <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 0000D30F <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0000D310 <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0000D311 <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 0000D312 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 0000D313 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 0000D31A <res 00000001>      <1> LASTRATE:	resb 	1
    49 0000D31B <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0000D31C <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0000D31D <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0000D31E <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0000D31F <res 00000004>      <1> DSK_STATE:	resb 	4
    54 0000D323 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 0000D325 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 0000D326 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 0000D327 <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                              <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 0000D328 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0000D32C <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 0000D330 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 0000D334 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 0000D338 <res 00000001>      <1> LBAMode:     	resb	1
    79                              <1> 
    80                              <1> ; *****************************************************************************
  2514                                  
  2515                                  ;;; Real Mode Data (10/07/2015 - BSS)
  2516                                  
  2517                                  ;alignb 2
  2518                                  
  2519                                  ; 10/01/2016
  2520                                  %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: 29/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 0000D339 <res 00000003>      <1> alignb 4
    20                              <1> 
    21                              <1> ; MAINPROG.ASM
    22 0000D33C <res 00000004>      <1> MainProgCfg_FileSize:   resd 1 ; 14/04/2016
    23 0000D340 <res 00000004>      <1> MainProgCfg_LineOffset: resd 1 ; 14/04/2016
    24                              <1> 
    25 0000D344 <res 00000004>      <1> Current_VolSerial: resd 1
    26                              <1> 
    27 0000D348 <res 00000004>      <1> Current_Dir_FCluster: resd 1
    28                              <1> 
    29 0000D34C <res 00000001>      <1> Current_Dir_Level: resb 1
    30 0000D34D <res 00000001>      <1> Current_FATType: resb 1
    31 0000D34E <res 00000001>      <1> Current_Drv: resb 1
    32 0000D34F <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    33 0000D350 <res 00000001>      <1>                    resb 1 ; ':'
    34 0000D351 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    35 0000D352 <res 0000005A>      <1> Current_Directory: resb 90
    36 0000D3AC <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    37 0000D3AD <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    38                              <1> 
    39 0000D3AE <res 00000001>      <1> CursorColumn: 	resb 1
    40 0000D3AF <res 00000001>      <1> CmdArgStart:    resb 1
    41                              <1> 
    42                              <1> ; 03/02/2016
    43 0000D3B0 <res 0000004E>      <1> Remark:		resb 78
    44                              <1> 
    45 0000D3FE <res 00000050>      <1> CommandBuffer: 	resb 80
    46                              <1> 
    47 0000D44E <res 00000100>      <1> TextBuffer:	resb 256
    48                              <1> 
    49                              <1> MasterBootBuff:
    50 0000D54E <res 000001BE>      <1> MasterBootCode: resb 1BEh
    51 0000D70C <res 00000040>      <1> PartitionTable: resb 64
    52 0000D74C <res 00000002>      <1> MBIDCode: resw 1
    53                              <1> 
    54                              <1> PTable_Buffer:
    55 0000D74E <res 00000040>      <1> PTable_hd0: resb 64
    56 0000D78E <res 00000040>      <1> PTable_hd1: resb 64
    57 0000D7CE <res 00000040>      <1> PTable_hd2: resb 64
    58 0000D80E <res 00000040>      <1> PTable_hd3: resb 64
    59 0000D84E <res 00000040>      <1> PTable_ep0: resb 64
    60 0000D88E <res 00000040>      <1> PTable_ep1: resb 64
    61 0000D8CE <res 00000040>      <1> PTable_ep2: resb 64
    62 0000D90E <res 00000040>      <1> PTable_ep3: resb 64
    63                              <1> 
    64 0000D94E <res 00000001>      <1> scount:	resb 1 ; 16/05/2016 (diskio.s, 'int33h:')	
    65 0000D94F <res 00000001>      <1> HD_LBA_yes: resb 1
    66 0000D950 <res 00000001>      <1> PP_Counter: resb 1
    67 0000D951 <res 00000001>      <1> EP_Counter: resb 1
    68                              <1> 
    69 0000D952 <res 00000004>      <1> EP_StartSector: resd 1
    70 0000D956 <res 00000004>      <1>                 resd 1
    71 0000D95A <res 00000004>      <1>                 resd 1
    72 0000D95E <res 00000004>      <1>                 resd 1
    73                              <1> 
    74 0000D962 <res 00000200>      <1> DOSBootSectorBuff: resb 512
    75                              <1> 
    76                              <1> FAT_BuffDescriptor:
    77 0000DB62 <res 00000004>      <1> FAT_CurrentCluster: resd 1
    78 0000DB66 <res 00000001>      <1> FAT_BuffValidData: resb 1
    79 0000DB67 <res 00000001>      <1> FAT_BuffDrvName: resb 1
    80 0000DB68 <res 00000002>      <1> FAT_BuffOffset: resw 1
    81 0000DB6A <res 00000004>      <1> FAT_BuffSector: resd 1
    82                              <1> 
    83 0000DB6E <res 00000004>      <1> FAT_ClusterCounter: resd 1
    84 0000DB72 <res 00000004>      <1> LastCluster: resd 1
    85                              <1> 
    86                              <1> ; 16/05/2016
    87                              <1> ;; 18/03/2016 (TRDOS v2.0)
    88                              <1> ;ClusterBuffer_Valid: resb 1
    89                              <1> 
    90                              <1> Dir_BuffDescriptor:
    91 0000DB76 <res 00000001>      <1> DirBuff_DRV: resb 1
    92 0000DB77 <res 00000001>      <1> DirBuff_FATType: resb 1
    93 0000DB78 <res 00000001>      <1> DirBuff_ValidData: resb 1
    94 0000DB79 <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
    95 0000DB7B <res 00000002>      <1> DirBuff_LastEntry: resw 1
    96 0000DB7D <res 00000004>      <1> DirBuff_Cluster: resd 1 
    97 0000DB81 <res 00000002>      <1> DirBuffer_Size: resw 1
    98                              <1> ;DirBuff_EntryCounter: resw 1
    99                              <1> 
   100                              <1> ; 01/02/2016
   101                              <1> ; these are on (real mode) segment 8000h and later
   102                              <1> ; FAT_Buffer:	resb 1536 ; 3 sectors
   103                              <1> ; Dir_Buffer:	resb 512*32
   104                              <1> ; Logical_DOSDisks:  resb 6656 ; 26 * 256 bytes
   105                              <1> 
   106                              <1> ; 18/01/2016
   107                              <1> 
   108 0000DB83 <res 00000004>      <1> FreeClusterCount: resd 1
   109                              <1> 
   110 0000DB87 <res 00000004>      <1> VolSize_Unit1:   resd 1
   111 0000DB8B <res 00000004>      <1> VolSize_Unit2:   resd 1
   112                              <1> 
   113 0000DB8F <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   114 0000DB93 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   115 0000DB9D <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   116 0000DB9E <res 00000001>      <1> resb 1
   117 0000DB9F <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   118 0000DBA3 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   119 0000DBAD <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   120                              <1> 
   121                              <1> ; 10/02/2016
   122 0000DBAE <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   123                              <1> 
   124                              <1> ; 24/01/2016
   125 0000DBAF <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   126                              <1> ; 06/02/2016
   127 0000DC2F <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   128 0000DC33 <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   129 0000DC34 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   130                              <1> ;
   131 0000DC35 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   132 0000DC37 <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   133 0000DC3B <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   134                              <1> ;
   135 0000DC3D <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   136                              <1> 
   137 0000DC3E <res 00000002>      <1> alignb 4
   138                              <1> 
   139                              <1> ; 29/01/2016
   140 0000DC40 <res 00000001>      <1> Program_Exit:	resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   141                              <1> 
   142                              <1> ;alignb 4
   143                              <1> ; 23/02/2016
   144 0000DC41 <res 00000001>      <1> disk_rw_op:	resb 1 ;  0 = disk read, 1 = disk write
   145                              <1> ;disk_rw_spt:	resb 1 ; sectors per track (<= 63) /// (<256)
   146                              <1> ; 31/01/2016
   147 0000DC42 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   148 0000DC43 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   149 0000DC44 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   150                              <1> 
   151                              <1> ; 06/02/2016 (long name)
   152 0000DC48 <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   153 0000DC4A <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   154 0000DC4C <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   155                              <1> ;	
   156 0000DC4D <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   157 0000DC4E <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   158 0000DC4F <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   159 0000DC50 <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   160                              <1> 
   161                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   162 0000DCD4 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   163 0000DCD5 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   164                              <1> 
   165                              <1> ; 07/02/2016
   166 0000DCD6 <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   167                              <1> 
   168                              <1> ; 10/02/2016
   169 0000DCE3 <res 0000000D>      <1> Dir_Entry_Name:	resb 13 ; DIR.ASM
   170                              <1> 
   171                              <1> alignb 2
   172                              <1> 
   173 0000DCF0 <res 00000002>      <1> AttributesMask: resw 1 ; CMD_INTR.ASM ; 09/11/2011
   174                              <1> 
   175                              <1> ; 10/02/2016 (128 bytes -> 126 bytes)
   176                              <1> ; 08/02/2016
   177                              <1> ;FFF Structure (128 bytes) ; DIR.ASM ; 09/10/2011
   178 0000DCF2 <res 00000001>      <1> FindFile_Drv:		  resb 1
   179 0000DCF3 <res 00000041>      <1> FindFile_Directory:	  resb 65
   180 0000DD34 <res 0000000D>      <1> FindFile_Name:		  resb 13
   181                              <1> FindFile_LongNameEntryLength:
   182 0000DD41 <res 00000001>      <1> FindFile_LongNameYes: 	  resb 1 ; Sign for longname procedures
   183                              <1> ;Above 80 bytes form
   184                              <1> ;TR-DOS Source/Destination File FullName Format/Structure
   185 0000DD42 <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   186 0000DD44 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   187 0000DD64 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   188 0000DD68 <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   189 0000DD6C <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   190 0000DD6E <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   191 0000DD70 <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   192                              <1> 
   193 0000DD72 <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   194 0000DD76 <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   195                              <1> 
   196                              <1> ; 10/02/2016
   197 0000DD7A <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   198 0000DD7C <res 00000002>      <1> Dir_Count:      resw 1
   199 0000DD7E <res 00000004>      <1> Total_FSize:    resd 1
   200 0000DD82 <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   201 0000DD86 <res 0000000A>      <1>                 resb 10
   202 0000DD90 <res 00000001>      <1> TFS_Dec_End:    resb 1
   203                              <1> 
   204 0000DD91 <res 00000001>      <1> PrintDir_RowCounter: resb 1
   205                              <1> 
   206 0000DD92 <res 00000002>      <1> alignb 4
   207                              <1> ; 15/02/2015 ('show' command variables)
   208 0000DD94 <res 00000004>      <1> Show_FDT:	resd 1
   209 0000DD98 <res 00000004>      <1> Show_LDDDT:	resd 1
   210 0000DD9C <res 00000004>      <1> Show_Cluster:	resd 1
   211 0000DDA0 <res 00000004>      <1> Show_FileSize:	resd 1
   212 0000DDA4 <res 00000004>      <1> Show_FilePointer: resd 1
   213 0000DDA8 <res 00000002>      <1> Show_ClusterPointer: resw 1
   214 0000DDAA <res 00000002>      <1> Show_ClusterSize: resw 1
   215 0000DDAC <res 00000001>      <1> Show_RowCount:	resb 1
   216                              <1> 
   217 0000DDAD <res 00000003>      <1> alignb 4
   218                              <1> ; 21/02/2016
   219 0000DDB0 <res 00000004>      <1> DelFile_FNPointer:	resd 1 ; ; CMD_INTR.ASM (word) ; 09/11/2011
   220                              <1> ; 27/02/2016
   221                              <1> ; DIR.ASM (09/10/2011)
   222 0000DDB4 <res 00000004>      <1> DelFile_FCluster:	resd 1
   223 0000DDB8 <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   224 0000DDBA <res 00000001>      <1> DelFile_LNEL:		resb 1
   225 0000DDBB <res 00000001>      <1> resb 1
   226                              <1> 
   227                              <1> ; DIR.ASM
   228 0000DDBC <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   229 0000DDC0 <res 00000004>      <1> mkdir_FFCluster:	resd 1
   230 0000DDC4 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   231 0000DDC8 <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   232 0000DDCC <res 00000002>      <1> mkdir_attrib:		resw 1 
   233 0000DDCE <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   234 0000DDCF <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   235 0000DDD0 <res 0000000D>      <1> mkdir_Name:		resb 13
   236 0000DDDD <res 00000002>      <1> resw 1 ; 01/03/2016
   237                              <1> ; 27/02/2016
   238 0000DDDF <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   239 0000DDE0 <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   240 0000DDE4 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   241 0000DDE8 <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   242 0000DDEC <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   243                              <1> ; 22/02/2016
   244 0000DDF0 <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   245 0000DDF1 <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   246                              <1> 	
   247 0000DDF5 <res 00000003>      <1> alignb 4
   248                              <1> ; DRV_FAT.ASM ; 21/08/2011
   249 0000DDF8 <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   250 0000DDFC <res 00000004>      <1> gffc_first_free_cluster: resd 1
   251 0000DE00 <res 00000004>      <1> gffc_last_free_cluster:  resd 1
   252                              <1> 
   253                              <1> ;29/04/2016
   254                              <1> Cluster_Index: ; resd 1
   255                              <1> ; 22/02/2016
   256 0000DE04 <res 00000004>      <1> ClusterValue:	resd 1
   257                              <1> ; 04/03/2016
   258 0000DE08 <res 00000001>      <1> Attributes:	resb 1 
   259                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   260 0000DE09 <res 00000001>      <1> resb 1
   261 0000DE0A <res 00000001>      <1> CFS_OPType: resb 1
   262 0000DE0B <res 00000001>      <1> CFS_Drv:    resb 1
   263 0000DE0C <res 00000004>      <1> CFS_CC:	    resd 1
   264 0000DE10 <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   265 0000DE14 <res 00000004>      <1> CFS_FAT32FC: resd 1
   266                              <1> 
   267                              <1> ; 27/02/2016
   268                              <1> ;alignb 4
   269 0000DE18 <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   270                              <1> 
   271                              <1> ; DIR.ASM
   272 0000DE1C <res 00000002>      <1> DLN_EntryNumber: resw 1
   273 0000DE1E <res 00000001>      <1> DLN_40h:	 resb 1
   274                              <1> ; 28/02/2016
   275 0000DE1F <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   276                              <1> 
   277                              <1> alignb 4
   278                              <1> ; DIR.ASM (09/10/2011)
   279 0000DE20 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   280 0000DE22 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   281 0000DE24 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   282 0000DE28 <res 00000004>      <1> LCDE_ByteOffset: resd 1
   283                              <1> 
   284                              <1> ;alignb4
   285                              <1> ; 06/03/2016 (word -> dword)
   286                              <1> ; CMD_INTR.ASM (01/08/2010)
   287 0000DE2C <res 00000004>      <1> SourceFilePath:	     resd 1
   288 0000DE30 <res 00000004>      <1> DestinationFilePath: resd 1
   289                              <1> 
   290                              <1> ;alignb 4
   291                              <1> ; 06/03/2016
   292                              <1> ; FILE.ASM (09/10/2011)
   293                              <1> ;Source File Structure (same with 'Find File' Structure)
   294 0000DE34 <res 00000001>      <1> SourceFile_Drv:			resb 1
   295 0000DE35 <res 00000041>      <1> SourceFile_Directory:		resb 65
   296 0000DE76 <res 0000000D>      <1> SourceFile_Name:		resb 13
   297                              <1> SourceFile_LongNameEntryLength: 
   298 0000DE83 <res 00000001>      <1> SourceFile_LongNameYes:		resb 1 ; Sign for longname procedures
   299                              <1> ;Above 80 bytes
   300                              <1> ;is TR-DOS Source File FullName Format/Structure
   301 0000DE84 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   302 0000DE86 <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   303 0000DEA6 <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   304 0000DEAA <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   305 0000DEAE <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   306 0000DEB0 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   307                              <1> ; 16/03/2016
   308 0000DEB2 <res 00000001>      <1> SourceFile_SecPerClust:		resb 1
   309 0000DEB3 <res 00000001>      <1> SourceFile_Reserved:		resb 1
   310                              <1> ; Above is 128 bytes
   311                              <1> 
   312                              <1> ;Destination File Structure (same with 'Find File' Structure)
   313 0000DEB4 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   314 0000DEB5 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   315 0000DEF6 <res 0000000D>      <1> DestinationFile_Name:		resb 13
   316                              <1> DestinationFile_LongNameEntryLength:
   317 0000DF03 <res 00000001>      <1> DestinationFile_LongNameYes:	resb 1 ; Sign for longname procedures
   318                              <1> ;Above 80 bytes
   319                              <1> ;is TR-DOS Destination File FullName Format/Structure
   320 0000DF04 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   321 0000DF06 <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   322 0000DF26 <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   323 0000DF2A <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   324 0000DF2E <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   325 0000DF30 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   326                              <1> ; 16/03/2016
   327 0000DF32 <res 00000001>      <1> DestinationFile_SecPerClust:	resb 1
   328 0000DF33 <res 00000001>      <1> DestinationFile_Reserved:	resb 1
   329                              <1> ; Above is 128 bytes
   330                              <1> 
   331                              <1> ; 24/04/2016
   332 0000DF34 <res 00000002>      <1> resw 1
   333                              <1> 
   334                              <1> ; 10/03/2016
   335                              <1> ; FILE.ASM
   336 0000DF36 <res 00000001>      <1> move_cmd_phase:	   resb 1
   337 0000DF37 <res 00000001>      <1> msftdf_sf_df_drv:  resb 1
   338 0000DF38 <res 00000004>      <1> msftdf_drv_offset: resd 1
   339                              <1> 
   340                              <1> ; 11/03/2016
   341                              <1> ; DRV_FAT.ASM (21/08/2011)
   342 0000DF3C <res 00000004>      <1> FAT_anc_LCluster:  resd 1
   343 0000DF40 <res 00000004>      <1> FAT_anc_FFCluster: resd 1
   344                              <1> 
   345                              <1> ;alignb 4
   346                              <1> 
   347                              <1> ; 14/03/2016
   348                              <1> ; TRDOS 386 = TRDOS v2.0 feature only !
   349                              <1> ; 'allocate_memory_block' in 'memory.s'
   350 0000DF44 <res 00000004>      <1> mem_ipg_count:	resd 1 ; page count (for contiguous allocation)
   351 0000DF48 <res 00000004>      <1> mem_pg_count:	resd 1 ; page count (for count down)
   352 0000DF4C <res 00000004>      <1> mem_aperture:	resd 1 ; contiguous free pages (current)
   353 0000DF50 <res 00000004>      <1> mem_max_aperture: resd 1 ; maximum value of contiguous free pages
   354 0000DF54 <res 00000004>      <1> mem_pg_pos:	resd 1 ; mem. position (page #) of current aperture
   355 0000DF58 <res 00000004>      <1> mem_max_pg_pos: resd 1 ; mem. position (page #) of max. aperture
   356                              <1> 
   357                              <1> ; 15/03/2016
   358                              <1> ; FILE.ASM ('copy_source_file_to_destination_file')
   359 0000DF5C <res 00000001>      <1> copy_cmd_phase:       resb 1
   360 0000DF5D <res 00000001>      <1> csftdf_rw_err:	      resb 1
   361 0000DF5E <res 00000001>      <1> DestinationFileFound: resb 1
   362 0000DF5F <res 00000001>      <1> csftdf_cdrv: 	      resb 1
   363 0000DF60 <res 00000004>      <1> csftdf_filesize:      resd 1
   364                              <1> ; TRDOS386 (TRDOS v2.0)
   365 0000DF64 <res 00000004>      <1> csftdf_sf_mem_addr:   resd 1
   366 0000DF68 <res 00000004>      <1> csftdf_sf_mem_bsize:  resd 1
   367                              <1> ;
   368                              <1> 
   369 0000DF6C <res 00000004>      <1> csftdf_sf_cluster:    resd 1 ; 16/03/2016
   370 0000DF70 <res 00000004>      <1> csftdf_df_cluster:    resd 1
   371                              <1> ; 16/03/2016
   372 0000DF74 <res 00000004>      <1> csftdf_r_size:        resd 1
   373 0000DF78 <res 00000004>      <1> csftdf_w_size:        resd 1
   374 0000DF7C <res 00000004>      <1> csftdf_sf_rbytes:     resd 1
   375 0000DF80 <res 00000004>      <1> csftdf_df_wbytes:     resd 1
   376 0000DF84 <res 00000001>      <1> csftdf_percentage:    resb 1
   377                              <1> ; 17/03/2016
   378 0000DF85 <res 00000001>      <1> csftdf_videopage:     resb 1
   379 0000DF86 <res 00000002>      <1> csftdf_cursorpos:     resw 1
   380 0000DF88 <res 00000004>      <1> csftdf_sf_drv_dt:     resd 1
   381 0000DF8C <res 00000004>      <1> csftdf_df_drv_dt:     resd 1
   382                              <1> 
   383                              <1> ; 21/03/2016
   384                              <1> ; 20/03/2016
   385                              <1> ; FILE.ASM
   386 0000DF90 <res 00000004>      <1> createfile_Name_Offset:  resd 1
   387 0000DF94 <res 00000004>      <1> createfile_FreeSectors:  resd 1 
   388 0000DF98 <res 00000004>      <1> createfile_size:         resd 1
   389 0000DF9C <res 00000004>      <1> createfile_FFCluster:    resd 1 ; 11/03/2016
   390 0000DFA0 <res 00000004>      <1> createfile_LastDirCluster: resd 1
   391 0000DFA4 <res 00000004>      <1> createfile_Cluster:      resd 1
   392 0000DFA8 <res 00000004>      <1> createfile_PCluster:     resd 1
   393 0000DFAC <res 00000001>      <1> createfile_attrib:	 resb 1
   394 0000DFAD <res 00000001>      <1> createfile_SecPerClust:  resb 1
   395 0000DFAE <res 00000002>      <1> createfile_DirIndex:     resw 1
   396 0000DFB0 <res 00000004>      <1> createfile_CCount:	 resd 1
   397 0000DFB4 <res 00000002>      <1> createfile_BytesPerSec:	 resw 1 ; 23/03/2016
   398 0000DFB6 <res 00000001>      <1> createfile_wfc:	         resb 1
   399 0000DFB7 <res 00000001>      <1> createfile_UpdatePDir:	 resb 1 ; 31/03/2016
   400                              <1> 
   401                              <1> ;alignb 4
   402                              <1> 
   403                              <1> ; 11/04/2016
   404 0000DFB8 <res 00000002>      <1> env_var_length:	   resw 1
   405                              <1> 
   406 0000DFBA <res 00000002>      <1> alignb 4
   407                              <1> 
   408                              <1> ; 25/04/2016
   409 0000DFBC <res 00000001>      <1> readi.valid:	resb 1 ; valid data (>0 = valid for readi)
   410 0000DFBD <res 00000001>      <1> readi.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   411 0000DFBE <res 00000001>      <1> readi.spc:	resb 1 ; sectors per cluster for 'readi' drive
   412 0000DFBF <res 00000001>      <1> readi.s_index:  resb 1 ; sector index in current cluster (buffer)
   413 0000DFC0 <res 00000004>      <1> readi.sector:	resd 1 ; current disk sector
   414 0000DFC4 <res 00000002>      <1> readi.bpc:	resw 1 ; bytes per cluster - 1
   415 0000DFC6 <res 00000002>      <1> readi.offset:	resw 1 ; byte offset in cluster buffer
   416 0000DFC8 <res 00000004>      <1> readi.cluster:  resd 1 ; current cluster number
   417 0000DFCC <res 00000004>      <1> readi.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   418 0000DFD0 <res 00000004>      <1> readi.fclust:	resd 1 ; first cluster of the current cluster
   419 0000DFD4 <res 00000004>      <1> readi.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   420                              <1> ;readi.buffer:	resd 1 ; readi sector buffer address
   421                              <1> 
   422 0000DFD8 <res 00000001>      <1> writei.valid:	resb 1 ; valid data (>0 = valid for writei)
   423 0000DFD9 <res 00000001>      <1> writei.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   424 0000DFDA <res 00000001>      <1> writei.spc:	resb 1 ; sectors per cluster for 'writei' drive
   425 0000DFDB <res 00000001>      <1> writei.s_index: resb 1 ; sector index in current cluster (buffer)
   426 0000DFDC <res 00000004>      <1> writei.sector:	resd 1 ; current disk sector
   427 0000DFE0 <res 00000002>      <1> writei.bpc:	resw 1 ; bytes per cluster - 1
   428 0000DFE2 <res 00000002>      <1> writei.offset:	resw 1 ; byte offset in cluster buffer
   429 0000DFE4 <res 00000004>      <1> writei.cluster: resd 1 ; current cluster number
   430 0000DFE8 <res 00000004>      <1> writei.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   431 0000DFEC <res 00000004>      <1> writei.fclust:  resd 1 ; first cluster of the current cluster
   432 0000DFF0 <res 00000004>      <1> writei.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   433                              <1> ;writei.buffer:	resd 1 ; writei sector buffer address
   434                              <1> 
   435                              <1> ; 29/04/2016
   436 0000DFF4 <res 00000004>      <1> Run_CDirFC:	resd 1
   437 0000DFF8 <res 00000001>      <1> Run_Auto_Path:	resb 1
   438 0000DFF9 <res 00000001>      <1> Run_Manual_Path: resb 1 ; 0 -> auto path sequence needed
   439 0000DFFA <res 00000001>      <1> EXE_ID:		resb 1	
   440 0000DFFB <res 00000001>      <1> EXE_dot:	resb 1
   441                              <1> 
   442                              <1> ; 06/05/2016
   443 0000DFFC <res 00000004>      <1> mainprog_return_addr: resd 1
   444 0000E000 <res 00000004>      <1> last_error:	resd 1  ; this will be used to return error code to MainProg
   445                              <1> 			; 'lasterror' keyword will be used later to get the
   446                              <1> 			; last error code/number/status.
   447                              <1> ; 12/05/2016
   448 0000E004 <res 00000004>      <1> video_eax:	resd 1  ; eax return value of video function
   449                              <1> 
   450                              <1> ; 21/05/2016 - TRDOS 386 ('swap/switch', 'rswap', [u.pri])
   451 0000E008 <res 00000001>      <1> priority:	resb 1  ; running priority level of process (0,1,2)
   452                              <1> 			; (run queue which is process comes from)
   453                              <1> ; 22/05/2016 - TRDOS 386 ('set_run_sequence', 'rtc_int', 'u_timer')
   454 0000E009 <res 00000001>      <1> p_change:	resb 1  ; process change status (for timer events)
   455                              <1> ; 23/05/2016 - TRDOS 386 ('clock')
   456 0000E00A <res 00000001>      <1> multi_tasking: resb 1   ; Multi Tasking status (0 = disabled, >0 = enabled)
   457                              <1> ; 29/05/2016
   458 0000E00B <res 00000001>      <1> set_mode_clear:	resb 1  ; >0 = clear video page  (internal variable)
   459                              <1> 			; 0 = 'set_mode_3' for 'write_tty' (do not clear)
   460                              <1> 			; > 0 = 'SET_MODE' video function, clear video page  
   461                              <1> 			
  2521                                  ; 24/01/2016
  2522                                  %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: 21/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> ; 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 0000E00C <res 00000002>      <1> 	i.flgs:	 resw 1
    37 0000E00E <res 00000001>      <1> 	i.nlks:	 resb 1
    38 0000E00F <res 00000001>      <1> 	i.uid:	 resb 1
    39                              <1>         ;i.size:  resw 1 ; size
    40 0000E010 <res 00000002>      <1> 	resw 1 ; 29/04/2016
    41 0000E012 <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    42 0000E022 <res 00000004>      <1> 	i.ctim:	 resd 1
    43 0000E026 <res 00000004>      <1> 	i.mtim:	 resd 1
    44 0000E02A <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> 	; 21/05/2016
    50                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
    51                              <1> 	; 06/05/2015 - Retro UNIX 386 v1
    52                              <1> 	; 11/03/2013 - 05/02/2014 (Retro UNIX 8086 v1)
    53                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
    54                              <1> 	;p.
    55                              <1> 	
    56 0000E02C <res 00000020>      <1>         p.pid:   resw nproc
    57 0000E04C <res 00000020>      <1>         p.ppid:  resw nproc
    58 0000E06C <res 00000020>      <1>         p.break: resw nproc
    59 0000E08C <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    60 0000E09C <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    61 0000E0AC <res 00000010>      <1> 	p.link:	 resb nproc
    62 0000E0BC <res 00000010>      <1> 	p.stat:	 resb nproc
    63                              <1> 
    64                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
    65 0000E0CC <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
    66                              <1> 			    ; 'user' structure
    67                              <1> 	; 21/05/2016	
    68                              <1> 	; 19/05/2016 (TRDOS 386 feature only!)
    69 0000E10C <res 00000010>      <1> 	p.timer: resb nproc ; number of timer events of the processs
    70                              <1> 			  		 			 	  
    71                              <1> P_SIZE	equ $ - process
    72                              <1> 
    73                              <1> 
    74                              <1> ; fsp table (original UNIX v1)
    75                              <1> ;
    76                              <1> ;Entry
    77                              <1> ;          15                                      0
    78                              <1> ;  1     |---|---------------------------------------|
    79                              <1> ;        |r/w|       i-number of open file           |
    80                              <1> ;        |---|---------------------------------------| 
    81                              <1> ;        |               device number               |
    82                              <1> ;        |-------------------------------------------|
    83                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
    84                              <1> ;        |-------------------------------------------| 
    85                              <1> ;        |  flag that says    | number of processes  |
    86                              <1> ;        |   file deleted     | that have file open  |
    87                              <1> ;        |-------------------------------------------| 
    88                              <1> ;  2     |                                           |
    89                              <1> ;        |-------------------------------------------| 
    90                              <1> ;        |                                           |
    91                              <1> ;        |-------------------------------------------|
    92                              <1> ;        |                                           |
    93                              <1> ;        |-------------------------------------------|
    94                              <1> ;        |                                           |
    95                              <1> ;        |-------------------------------------------| 
    96                              <1> ;  3     |                                           | 
    97                              <1> ;        |                                           |  
    98                              <1> ;
    99                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
   100                              <1> 
   101                              <1> 
   102                              <1> ; 15/04/2015
   103 0000E11C <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
   104 0000E310 <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
   105 0000E328 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   106 0000E32A <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   107                              <1> ; 18/05/2015
   108                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
   109                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
   110                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
   111                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
   112                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
   113                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
   114                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
   115                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
   116                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
   117                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
   118                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
   119 0000E32C <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
   120                              <1> 	        ; as above, for physical drives numbers in following table
   121 0000E32D <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   122                              <1> ; 15/04/2015
   123 0000E32E <res 00000001>      <1> active:	 resb 1 
   124 0000E32F <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   125 0000E330 <res 00000002>      <1> mnti:	 resw 1
   126 0000E332 <res 00000002>      <1> mpid:	 resw 1
   127 0000E334 <res 00000002>      <1> rootdir: resw 1
   128                              <1> 
   129                              <1> ; 21/05/2016 - TRDOS 386 (TRDOS v2.0) - priority levels, 3 run queues 
   130                              <1> runq:
   131 0000E336 <res 00000002>      <1> runq_event:	 resw 1 ; high priority, 'run for event'            ; 2
   132 0000E338 <res 00000002>      <1> runq_normal:	 resw 1 ; normal/regular priority, 'run as reqular' ; 1
   133 0000E33A <res 00000002>      <1> runq_background: resw 1 ; low priority, 'run on background'         ; 0
   134                              <1> ;
   135 0000E33C <res 00000001>      <1> imod:	 resb 1
   136 0000E33D <res 00000001>      <1> smod:	 resb 1
   137 0000E33E <res 00000001>      <1> mmod:	 resb 1
   138 0000E33F <res 00000001>      <1> sysflg:	 resb 1
   139                              <1> 
   140                              <1> alignb 4
   141                              <1> 
   142                              <1> user:
   143                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
   144                              <1> 	; 	       [u.pri] usage method modification
   145                              <1> 	; 04/12/2015 
   146                              <1> 	; 18/10/2015
   147                              <1> 	; 12/10/2015
   148                              <1> 	; 21/09/2015
   149                              <1> 	; 24/07/2015
   150                              <1> 	; 16/06/2015
   151                              <1> 	; 09/06/2015
   152                              <1> 	; 11/05/2015
   153                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
   154                              <1> 	; 10/10/2013
   155                              <1> 	; 11/03/2013. 
   156                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
   157                              <1> 	;u.
   158                              <1> 
   159 0000E340 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   160 0000E344 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   161 0000E348 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   162 0000E34C <res 00000002>      <1> 	u.cdir:	  resw 1
   163 0000E34E <res 0000000A>      <1> 	u.fp:	  resb 10
   164 0000E358 <res 00000004>      <1> 	u.fofp:	  resd 1
   165 0000E35C <res 00000004>      <1> 	u.dirp:	  resd 1
   166 0000E360 <res 00000004>      <1> 	u.namep:  resd 1
   167 0000E364 <res 00000004>      <1> 	u.off:	  resd 1
   168 0000E368 <res 00000004>      <1> 	u.base:	  resd 1
   169 0000E36C <res 00000004>      <1> 	u.count:  resd 1
   170 0000E370 <res 00000004>      <1> 	u.nread:  resd 1
   171 0000E374 <res 00000004>      <1> 	u.break:  resd 1 ; break
   172 0000E378 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   173 0000E37A <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   174                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   175 0000E38A <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   176 0000E38B <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
   177 0000E38C <res 00000002>      <1> 	u.intr:	  resw 1
   178 0000E38E <res 00000002>      <1> 	u.quit:	  resw 1
   179                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   180 0000E390 <res 00000002>      <1> 	u.ilgins: resw 1
   181 0000E392 <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   182 0000E394 <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   183 0000E395 <res 00000001>      <1> 	u.ruid:	  resb 1
   184 0000E396 <res 00000001>      <1> 	u.bsys:	  resb 1
   185 0000E397 <res 00000001>      <1> 	u.uno:	  resb 1
   186 0000E398 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   187                              <1> 	; tty number (rtty, rcvt, wtty)
   188 0000E39C <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   189                              <1> 	; last error number
   190 0000E39D <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   191                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   192 0000E3A1 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   193 0000E3A5 <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   194 0000E3A9 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   195 0000E3AD <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
   196                              <1> 	;u.pncount: resw 1 
   197                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
   198                              <1> 	;u.pnbase:  resd 1 
   199                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
   200                              <1> 			 ; 09/06/2015
   201 0000E3AF <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   202 0000E3B0 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
   203                              <1> 			 ; 24/07/2015 - 24/06/2015
   204                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
   205                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
   206                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
   207                              <1>  			 ; 24/06/2015	  	
   208                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
   209                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
   210                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
   211 0000E3B1 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   212                              <1> 
   213 0000E3B5 <res 00000003>      <1> alignb 4
   214                              <1> 
   215                              <1> U_SIZE	equ $ - user
   216                              <1> 
   217                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
   218 0000E3B8 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
   219 0000E3BC <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
   220 0000E3C0 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   221 0000E3C4 <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   222 0000E3C6 <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   223 0000E3C8 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
   224                              <1> 
   225                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
   226                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
   227 0000E3CC <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   228                              <1> 
   229                              <1> ;alignb 4
   230                              <1> 
   231                              <1> ; 24/04/2016
   232 0000E3CD <res 00000004>      <1> ii:		resd 1 ; first cluster of the program file
   233 0000E3D1 <res 00000004>      <1> i.size:		resd 1 ; size of the program file
   234                              <1> 
   235                              <1> ; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
   236                              <1> ; 22/08/2015 (Retro UNIX 386 v1)
   237                              <1> buffer: 
   238 0000E3D5 <res 00000008>      <1> 	resb	8 
   239                              <1> readi_buffer:
   240 0000E3DD <res 00000200>      <1> 	resb 	512
   241 0000E5DD <res 00000008>      <1> 	resb	8
   242                              <1> writei_buffer:
   243 0000E5E5 <res 00000200>      <1> 	resb	512	
   244 0000E7E5 <res 00000410>      <1> 	resb (nbuf-2) * 520
   245                              <1> 
   246 0000EBF5 <res 00000008>      <1> sb0:	resd 2
   247                              <1> ;s:
   248                              <1> ; (root disk) super block buffer
   249                              <1> systm:
   250                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
   251                              <1> 	; 11/03/2013. 
   252                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
   253                              <1> 	;s.
   254                              <1> 
   255 0000EBFD <res 00000002>      <1> 	resw 1
   256 0000EBFF <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
   257 0000ED67 <res 00000002>      <1> 	resw 1
   258 0000ED69 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
   259 0000ED89 <res 00000004>      <1> 	s.time:	 resd 1
   260 0000ED8D <res 00000004>      <1> 	s.syst:	 resd 1
   261 0000ED91 <res 00000004>      <1>         s.wait_: resd 1 ; wait
   262 0000ED95 <res 00000004>      <1> 	s.idlet: resd 1
   263 0000ED99 <res 00000004>      <1> 	s.chrgt: resd 1
   264 0000ED9D <res 00000002>      <1> 	s.drerr: resw 1
   265                              <1> 
   266                              <1> S_SIZE	equ $ - systm
   267                              <1> 
   268 0000ED9F <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
   269                              <1> 
   270 0000EDFD <res 00000008>      <1> sb1:	resd 2
   271                              <1> ; (mounted disk) super block buffer
   272                              <1> mount:	
   273 0000EE05 <res 00000200>      <1> 	resb 512  ; 03/06/2015
  2523                                  
  2524 0000F005 <res 00000003>          alignb 4
  2525                                  
  2526                                  ; 23/05/2016 (TRDOS 386)
  2527                                  ; 14/10/2015 (Retro UNIX 386 v1, 'unix386.s')
  2528 0000F008 <res 00000004>          cr3reg:	 resd 1  ; cr3 register content at the beginning of the timer
  2529                                  		 ; (or RTC) interrupt handler.
  2530                                  
  2531                                  ; 19/05/2016
  2532                                  ; 18/05/2016 - TRDOS 386 feature only !
  2533 0000F00C <res 00000100>          timer_set: resd 16*4   ; 256 bytes memory space for 16 timer events
  2534                                  	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  2535                                  	;       Owner:	        resw 1 ; 0 = free
  2536                                  	;		  	       ;>0 = process ID (p.pid)
  2537                                  	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  2538                                  	;		   	       ; 1 = Real Time Clock interrupt 
  2539                                  	;	Response:       resb 1 ; 0 to 255, signal return value
  2540                                  	;	Count Limit:	resd 1 ; count of ticks (total/set)
  2541                                  	;	Current Count: 	resd 1 ; count of ticks (current)
  2542                                  	;	Response Addr:  resd 1 ; response byte (pointer) address
  2543                                  
  2544                                  ;; Memory (swap) Data (11/03/2015)
  2545                                  ; 09/03/2015
  2546 0000F10C <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  2547 0000F10E <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2548 0000F112 <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2549 0000F116 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2550 0000F11A <res 00000004>          swpd_next:  resd 1 ; next free page block
  2551 0000F11E <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  2552                                  
  2553 0000F122 <res 00000002>          alignb 4
  2554                                  
  2555                                  ; 10/07/2015
  2556                                  ; 28/08/2014
  2557 0000F124 <res 00000004>          error_code:	resd 1
  2558                                  ; 29/08/2014
  2559 0000F128 <res 00000004>          FaultOffset: 	resd 1
  2560                                  ; 21/09/2015
  2561 0000F12C <res 00000004>          PF_Count:	resd 1	; total page fault count
  2562                                  		       	; (for debugging - page fault analyze)
  2563                                  		 	; 'page_fault_handler' (memory.inc)
  2564                                  			; 'sysgeterr' (u9.s)
  2565                                  ;; 21/08/2015
  2566                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
  2567                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
  2568                                  
  2569                                  bss_end:
  2570                                  
  2571                                  ; 27/12/2013
  2572                                  _end:  ; end of kernel code
