     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 20/06/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[BCCD]              	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[94CF]              	mov	[mem_1m_1k], cx
   160 00000017 8916[96CF]              	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[5FCE]                	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[BFCD]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    42 0000004E 8816[BECD]          <1>         mov     [last_drv], dl  ; last hard disk number
    43 00000052 BB[42CD]            <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[C0CD]            <1> 	mov	si, fd0_type
    61                              <1> L3:
    62                              <1> 	; 14/01/2015
    63 00000063 8816[BDCD]          <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[C0CD]          <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[BFCD]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[BDCD]          <1>         mov     [drv], dl
    94 0000008E 8816[BECD]          <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[BFCD]          <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[BDCD]          <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[BDCD]          <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[BDCD]          <1> 	inc	byte [drv]
   148 000000FD BB[42CD]            <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[BFCD]            <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[BDCD]          <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[BDCD]          <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[68F1]            <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[C2CD]          <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[C0CD]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   188 00000155 81C3[0CCE]          <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[0CCE]          <1> 	sub	bx, drv.status
   197 00000167 C1E302              <1> 	shl	bx, 2
   198 0000016A 81C3[F0CD]          <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[C2CD]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   301 000001F4 808F[0ECE]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[0ECE]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[BECD]          <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[BDCD]          <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[0CCE]          <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[0CCE]          <1> 	sub	bx, drv.status
   353 0000024A D0E3                <1> 	shl	bl, 1
   354 0000024C 81C3[C6CD]          <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[C6CD]          <1> 	sub	bx, drv.cylinders
   359 00000258 81C3[D4CD]          <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[D4CD]          <1>         sub     bx, drv.heads
   365 00000267 81C3[E2CD]          <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[E2CD]          <1>         sub     bx, drv.spt
   370 00000276 D1E3                <1> 	shl	bx, 1
   371 00000278 81C3[F0CD]          <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[90CA]                  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 B966080000              	mov  ecx, (bss_end - bss_start)/4
   276                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   277 000002EA BF[D0CF0000]            	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[94CF0000]        	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[C0D20000]          	mov	[free_pages], ecx
   301 0000030B 668B15[96CF0000]        	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[C0D20000]          	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[BCD20000]            	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[D0D20000]          	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[B8D20000]          	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[C8D20000]            	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[D0D20000]        	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[C0D20000]          	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[BCD20000]          	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[C0D20000]          	sub	[free_pages], ecx ; 07/11/2014
   430                                  	;
   431 000003F0 8B35[B8D20000]          	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[B8D20000]          	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[BCD20000]          	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[CCD20000]            	mov	[first_page], eax
   502 0000045F A3[C4D20000]            	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[B8D20000]                    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[98CF0000]            	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[9CCA0000]            	mov	esi, ilist
   594 000004C1 8D3D[D0CF0000]          	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[96CA0000]        	lidt 	[idtd]
   641                                  	;
   642                                  	; TSS descriptor setup ; 24/03/2015
   643 0000051A B8[50D20000]            	mov	eax, task_state_segment
   644 0000051F 66A3[8ACA0000]          	mov	[gdt_tss0], ax
   645 00000525 C1C010                  	rol	eax, 16
   646 00000528 A2[8CCA0000]            	mov	[gdt_tss1], al
   647 0000052D 8825[8FCA0000]          	mov	[gdt_tss2], ah
   648 00000533 66C705[B6D20000]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[BCD20000]          	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[54D20000]          	mov	[tss.esp0], esp
   682 00000561 66C705[58D20000]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 E808120000              	call	_set_cpos	; 24/01/2016
   709                                  	;
   710                                  	; 06/11/2014
   711 00000585 E8E9120000              	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[C2CD0000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   718 00000591 668B1D[C0CD0000]        	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[9BCE0000]            	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 E84C110000              	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[A1060000]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 E820220000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   756                                  	;
   757 000005C7 09D2                    	or	edx, edx
   758 000005C9 7407                            jz      short di3
   759                                  di2:
   760 000005CB E85E220000              	call   	DISK_SETUP	; Initialize Fixed Disks
   761 000005D0 72CF                            jc      short setup_error
   762                                  di3:
   763 000005D2 E870120000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   764                                  	;
   765 000005D7 E8DCC30000              	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 E848390000              	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[E6D20000]          	mov	bl, [ptty]	; active_page
   814 000005EA 89DE                    	mov	esi, ebx
   815 000005EC 66D1E6                  	shl 	si, 1
   816 000005EF 81C6[E8D20000]          	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 E8EE100000              	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                                  ; 06/06/2016
   869                                  ; 23/05/2016
   870                                  ; 22/05/2016 - TRDOS 386 (TRDOS v2.0) Timer Event Modifications
   871                                  ; 25/07/2015
   872                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
   873                                  ; 17/02/2015
   874                                  ; 06/02/2015 (unix386.s)
   875                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
   876                                  ;
   877                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
   878                                  ;
   879                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
   880                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
   881                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
   882                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
   883                                  ;									       :
   884                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
   885                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
   886                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
   887                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
   888                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
   889                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
   890                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
   891                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
   892                                  ;-------------------------------------------------------------------------------
   893                                  ;
   894                                  
   895                                  timer_int:	; IRQ 0
   896                                  ;int_08h:	; Timer
   897                                  	; 14/10/2015
   898                                  	; Here, we are simulating system call entry (for task switch)
   899                                  	; (If multitasking is enabled, 
   900                                  	; 'clock' procedure may jump to 'sysrelease')
   901 0000062A 1E                      	push	ds
   902 0000062B 06                      	push	es
   903 0000062C 0FA0                    	push	fs
   904 0000062E 0FA8                    	push	gs
   905 00000630 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
   906 00000631 66B91000                	mov     cx, KDATA
   907 00000635 8ED9                            mov     ds, cx
   908 00000637 8EC1                            mov     es, cx
   909 00000639 8EE1                            mov     fs, cx
   910 0000063B 8EE9                            mov     gs, cx
   911                                  	;
   912 0000063D 0F20D9                  	mov	ecx, cr3
   913 00000640 890D[40F00000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   914                                  	;
   915 00000646 3B0D[B8D20000]          	cmp 	ecx, [k_page_dir]
   916 0000064C 7420                    	je	short T3
   917                                  	;
   918                                  	; timer interrupt has been occurred while OS is in user mode
   919 0000064E FC                      	cld	; 06/06/2016
   920 0000064F A3[80E30000]            	mov 	[u.r0], eax
   921 00000654 89E1                    	mov	ecx, esp
   922 00000656 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   923 00000659 890D[78E30000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   924 0000065F 8925[7CE30000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   925                                  	;
   926 00000665 8B0D[B8D20000]          	mov	ecx, [k_page_dir]
   927 0000066B 0F22D9                  	mov	cr3, ecx
   928                                  T3:
   929                                  	;sti				; INTERRUPTS BACK ON
   930 0000066E 66FF05[38D30000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   931 00000675 7507                    	JNZ	short T4		; GO TO TEST_DAY
   932 00000677 66FF05[3AD30000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   933                                  T4:					; TEST_DAY
   934 0000067E 66833D[3AD30000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
   935 00000686 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
   936 00000688 66813D[38D30000]B0-     	CMP	word [TIMER_LOW],0B0H
   936 00000690 00                 
   937 00000691 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
   938                                  
   939                                  ;-----	TIMER HAS GONE 24 HOURS
   940                                  	;;SUB	AX,AX
   941                                  	;MOV	[TIMER_HIGH],AX
   942                                  	;MOV	[TIMER_LOW],AX
   943 00000693 29C0                    	sub	eax, eax
   944 00000695 A3[38D30000]            	mov	[TIMER_LH], eax
   945                                  	;	
   946 0000069A C605[3CD30000]01        	MOV	byte [TIMER_OFL],1
   947                                  
   948                                  ;-----	TEST FOR DISKETTE TIME OUT
   949                                  
   950                                  T5:
   951                                  	; 23/12/2014
   952 000006A1 EB1D                    	jmp	short T6		; will be replaced with nop, nop
   953                                  					; (9090h) if a floppy disk
   954                                  					; is detected.
   955                                  	;mov	al,[CS:MOTOR_COUNT]
   956 000006A3 A0[3FD30000]            	mov	al, [MOTOR_COUNT]
   957 000006A8 FEC8                    	dec	al
   958                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
   959 000006AA A2[3FD30000]            	mov	[MOTOR_COUNT], al
   960                                  	;mov	[ORG_MOTOR_COUNT], al
   961 000006AF 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
   962 000006B1 B0F0                    	mov 	al,0F0h
   963                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
   964 000006B3 2005[3ED30000]          	and	[MOTOR_STATUS], al
   965                                  	;and	[ORG_MOTOR_STATUS], al
   966 000006B9 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
   967                                  					; bit 2 = enable controller
   968                                  					;	1 = normal operation
   969                                  					;	0 = reset	
   970                                  					; bit 0, 1 = drive select
   971                                  					; bit 4-7 = motor running bits 
   972 000006BB 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
   973 000006BF EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
   974                                  T6:	
   975                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
   976                                  					; TIMER TICK INTERRUPT
   977                                  	;;inc	word [wait_count] ;;27/02/2015
   978                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
   979                                  	;cli
   980 000006C0 E87E030000              	call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
   981                                  	; 23/05/2016
   982 000006C5 E8D3B80000              	call	clock			; Multi Tasking control procedure
   983                                  T7:
   984                                  	; 14/10/2015
   985 000006CA B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
   986                                  	;CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
   987 000006CC E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
   988                                  	;
   989                                  	; 23/05/2016
   990                                  rtc_int_2:
   991                                  	; 22/05/2016
   992 000006CE 803D[39E00000]00        	cmp	byte [p_change], 0 ; in 'set_run_sequence', in 'rtc_p'
   993 000006D5 7615                    	jna	short timer_int_return ; 23/05/2016	
   994                                  	; present process must be changed with high priority process	
   995 000006D7 30C0                    	xor	al, al
   996 000006D9 A2[39E00000]            	mov	[p_change], al ; 0
   997                                  	;
   998 000006DE 803D[75E30000]FF        	cmp     byte [sysflg], 0FFh ; user or system space ?
   999 000006E5 7415                    	je	short rtc_int_3     ; user space ([sysflg]= 0FFh)
  1000                                  
  1001                                  	; system space, wait for 'sysret'
  1002                                  	; to change running process 	
  1003                                  	; with high priority (event) process
  1004                                  
  1005 000006E7 A2[C2E30000]            	mov	[u.quant], al ; 0
  1006                                  
  1007                                  timer_int_return: ; 23/05/2016 - jump from 'rtc_int' ('rtc_int_2')
  1008 000006EC A1[40F00000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
  1009 000006F1 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
  1010                                  	;
  1011 000006F4 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1012                                  	;
  1013 000006F5 0FA9                    	pop	gs
  1014 000006F7 0FA1                    	pop	fs
  1015 000006F9 07                      	pop	es
  1016 000006FA 1F                      	pop	ds
  1017 000006FB CF                      	iretd	; return from interrupt
  1018                                  
  1019                                  rtc_int_3:
  1020 000006FC FE05[75E30000]          	inc	byte [sysflg] 	; now, we are in system space
  1021                                  	;
  1022 00000702 E9789A0000                      jmp     sysrelease ; change running process immediatelly 
  1023                                  
  1024                                  	; 06/06/2016
  1025                                  	; 23/05/2016
  1026                                  	; 22/05/2016
  1027                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1028                                  	; 26/02/2015
  1029                                  	; 07/09/2014
  1030                                  	; 25/08/2014
  1031                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1032                                  	; 22/05/2016
  1033 00000707 1E                      	push	ds ; ** ; 23/05/2016
  1034 00000708 50                      	push	eax ; *
  1035 00000709 66B81000                	mov	ax, KDATA
  1036 0000070D 8ED8                    	mov	ds, ax
  1037                                  	;
  1038 0000070F 8A25[36D30000]          	mov	ah, [RTC_2Hz] ;  2 Hz interrupt to 1 Hz function
  1039 00000715 80F401                  	xor	ah, 1
  1040 00000718 8825[36D30000]          	mov	[RTC_2Hz], ah ; 1 = 0.5 second, 0 = 1 second
  1041 0000071E 7549                    	jnz	short rtc_int_return ; half second
  1042                                  	; 1 second
  1043                                  rtc_int_0:
  1044                                  	; 22/05/2016
  1045 00000720 58                      	pop	eax ; *
  1046                                  	;
  1047                                  	; 14/10/2015 ('timer_int')
  1048                                  	; Here, we are simulating system call entry (for task switch)
  1049                                  	; (If multitasking is enabled, 
  1050                                  	; 'clock' procedure may jump to 'sysrelease')
  1051                                  	;push	ds ; ** ; 23/05/2016
  1052 00000721 06                      	push	es
  1053 00000722 0FA0                    	push	fs
  1054 00000724 0FA8                    	push	gs
  1055 00000726 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1056 00000727 66B91000                	mov     cx, KDATA
  1057                                          ;mov    ds, cx ; 06/06/2016
  1058 0000072B 8EC1                            mov     es, cx
  1059 0000072D 8EE1                            mov     fs, cx
  1060 0000072F 8EE9                            mov     gs, cx
  1061                                  	;
  1062 00000731 0F20D9                  	mov	ecx, cr3
  1063 00000734 890D[40F00000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1064                                  	;
  1065 0000073A 3B0D[B8D20000]          	cmp 	ecx, [k_page_dir]
  1066 00000740 7420                    	je	short rtc_int_1
  1067                                  	;
  1068                                  	; timer interrupt has been occurred while OS is in user mode
  1069 00000742 FC                      	cld 	; 06/06/2016
  1070 00000743 A3[80E30000]            	mov 	[u.r0], eax
  1071 00000748 89E1                    	mov	ecx, esp
  1072 0000074A 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1073 0000074D 890D[78E30000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1074 00000753 8925[7CE30000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1075                                  	;
  1076 00000759 8B0D[B8D20000]          	mov	ecx, [k_page_dir]
  1077 0000075F 0F22D9                  	mov	cr3, ecx
  1078                                  
  1079                                  rtc_int_1:
  1080                                  	; Timer event (kernel) functions must be performed with
  1081                                  	; 1 second intervals - TRDOS 386 (TRDOS v2.0) feature ! -
  1082                                   	;	
  1083                                  	; 25/08/2014
  1084 00000762 E8DC020000              	call	rtc_p  ; 19/05/2016 - major modification 
  1085                                  	; 23/05/2016
  1086 00000767 28E4                    	sub	ah, ah ; 0
  1087                                  	; 22/05/2016 - TRDOS 386 timer event modifications
  1088                                  rtc_int_return: ; 19/05/2016
  1089                                  	; 22/02/2015 - dsectpm.s
  1090                                  	; [ source: http://wiki.osdev.org/RTC ]
  1091                                  	; read status register C to complete procedure
  1092                                  	;(it is needed to get a next IRQ 8) 
  1093 00000769 B00C                    	mov	al, 0Ch ; 
  1094 0000076B E670                    	out	70h, al ; select register C
  1095 0000076D 90                      	nop
  1096 0000076E E471                    	in	al, 71h ; just throw away contents
  1097                                  	; 22/02/2015
  1098 00000770 B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1099                                  	;CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1100 00000772 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1101                                  
  1102                                  	; 23/05/2016
  1103 00000774 B020                    	MOV	AL,EOI		; GET END OF INTERRUPT MASK
  1104                                  	;CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1105 00000776 E620                    	OUT	INTA00,AL	; END OF INTERRUPT TO 8259 - 1	
  1106                                  	;
  1107                                  	; 23/05/2016
  1108 00000778 20E4                    	and	ah, ah
  1109 0000077A 0F844EFFFFFF                    jz      rtc_int_2
  1110                                  	
  1111                                  	; ah = 1 (half second)
  1112 00000780 58                      	pop	eax ; *
  1113 00000781 1F                      	pop	ds  ; **
  1114 00000782 CF                      	iretd
  1115                                  
  1116                                  ; ////////////////
  1117                                  
  1118                                  	; 28/08/2014
  1119                                  irq0:
  1120 00000783 6A00                            push 	dword 0
  1121 00000785 EB48                    	jmp	short which_irq
  1122                                  irq1:
  1123 00000787 6A01                            push 	dword 1
  1124 00000789 EB44                    	jmp	short which_irq
  1125                                  irq2:
  1126 0000078B 6A02                            push 	dword 2
  1127 0000078D EB40                    	jmp	short which_irq
  1128                                  irq3:
  1129                                  	; 20/11/2015
  1130                                  	; 24/10/2015
  1131 0000078F 2EFF15[12C20000]        	call	dword [cs:com2_irq3]
  1132 00000796 6A03                    	push 	dword 3
  1133 00000798 EB35                    	jmp	short which_irq
  1134                                  irq4:
  1135                                  	; 20/11/2015
  1136                                  	; 24/10/2015
  1137 0000079A 2EFF15[0EC20000]        	call	dword [cs:com1_irq4]
  1138 000007A1 6A04                            push 	dword 4
  1139 000007A3 EB2A                    	jmp	short which_irq
  1140                                  irq5:
  1141 000007A5 6A05                            push 	dword 5
  1142 000007A7 EB26                    	jmp	short which_irq
  1143                                  irq6:
  1144 000007A9 6A06                            push 	dword 6
  1145 000007AB EB22                    	jmp	short which_irq
  1146                                  irq7:
  1147 000007AD 6A07                            push 	dword 7
  1148 000007AF EB1E                    	jmp	short which_irq
  1149                                  irq8:
  1150 000007B1 6A08                            push 	dword 8
  1151 000007B3 EB1A                    	jmp	short which_irq
  1152                                  irq9:
  1153 000007B5 6A09                            push 	dword 9
  1154 000007B7 EB16                    	jmp	short which_irq
  1155                                  irq10:
  1156 000007B9 6A0A                            push 	dword 10
  1157 000007BB EB12                    	jmp	short which_irq
  1158                                  irq11:
  1159 000007BD 6A0B                            push 	dword 11
  1160 000007BF EB0E                    	jmp	short which_irq
  1161                                  irq12:
  1162 000007C1 6A0C                            push 	dword 12
  1163 000007C3 EB0A                    	jmp	short which_irq
  1164                                  irq13:
  1165 000007C5 6A0D                            push 	dword 13
  1166 000007C7 EB06                    	jmp	short which_irq
  1167                                  irq14:
  1168 000007C9 6A0E                            push 	dword 14
  1169 000007CB EB02                    	jmp	short which_irq
  1170                                  irq15:
  1171 000007CD 6A0F                            push 	dword 15
  1172                                  	;jmp	short which_irq
  1173                                  
  1174                                  	; 19/10/2015
  1175                                  	; 29/08/2014
  1176                                  	; 21/08/2014
  1177                                  which_irq:
  1178 000007CF 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1179 000007D2 53                      	push	ebx
  1180 000007D3 56                      	push	esi
  1181 000007D4 57                      	push	edi
  1182 000007D5 1E                      	push 	ds
  1183 000007D6 06                      	push 	es
  1184                                  	;
  1185 000007D7 88C3                    	mov	bl, al
  1186                                  	;
  1187 000007D9 B810000000              	mov	eax, KDATA
  1188 000007DE 8ED8                    	mov	ds, ax
  1189 000007E0 8EC0                    	mov	es, ax
  1190                                  	; 19/10/2015
  1191 000007E2 FC                      	cld
  1192                                          ; 27/08/2014
  1193 000007E3 8105[1ACE0000]A000-             add     dword [scr_row], 0A0h
  1193 000007EB 0000               
  1194                                  	;
  1195 000007ED B417                    	mov	ah, 17h	; blue (1) background, 
  1196                                  			; light gray (7) forecolor
  1197 000007EF 8B3D[1ACE0000]                  mov     edi, [scr_row]
  1198 000007F5 B049                    	mov	al, 'I'
  1199 000007F7 66AB                    	stosw
  1200 000007F9 B052                    	mov	al, 'R'
  1201 000007FB 66AB                    	stosw
  1202 000007FD B051                    	mov	al, 'Q'
  1203 000007FF 66AB                    	stosw
  1204 00000801 B020                    	mov	al, ' '
  1205 00000803 66AB                    	stosw
  1206 00000805 88D8                    	mov	al, bl
  1207 00000807 3C0A                    	cmp	al, 10
  1208 00000809 7208                    	jb	short iix
  1209 0000080B B031                    	mov	al, '1'
  1210 0000080D 66AB                    	stosw
  1211 0000080F 88D8                    	mov	al, bl
  1212 00000811 2C0A                    	sub	al, 10
  1213                                  iix:
  1214 00000813 0430                    	add	al, '0'
  1215 00000815 66AB                    	stosw
  1216 00000817 B020                    	mov	al, ' '
  1217 00000819 66AB                    	stosw
  1218 0000081B B021                    	mov	al, '!'
  1219 0000081D 66AB                    	stosw
  1220 0000081F B020                    	mov	al, ' '
  1221 00000821 66AB                    	stosw
  1222                                  	; 23/02/2015
  1223 00000823 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1224 00000826 0F8695010000            	jna	iiret
  1225 0000082C B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1226 0000082E E6A0                    	out	0A0h, al ; the 2nd 8259
  1227 00000830 E98C010000              	jmp     iiret
  1228                                  	;
  1229                                  	; 22/08/2014
  1230                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1231                                  	;out	20h, al	; 8259 PORT
  1232                                  	;
  1233                                  	;pop	es
  1234                                  	;pop	ds
  1235                                  	;pop	edi
  1236                                  	;pop	esi
  1237                                  	;pop	ebx
  1238                                  	;pop 	eax
  1239                                  	;iret
  1240                                  
  1241                                  	; 02/04/2015
  1242                                  	; 25/08/2014
  1243                                  exc0:
  1244 00000835 6A00                            push 	dword 0
  1245 00000837 E990000000                      jmp     cpu_except
  1246                                  exc1:
  1247 0000083C 6A01                            push 	dword 1
  1248 0000083E E989000000                      jmp     cpu_except
  1249                                  exc2:
  1250 00000843 6A02                            push 	dword 2
  1251 00000845 E982000000                      jmp     cpu_except
  1252                                  exc3:
  1253 0000084A 6A03                            push 	dword 3
  1254 0000084C EB7E                            jmp     cpu_except
  1255                                  exc4:
  1256 0000084E 6A04                            push 	dword 4
  1257 00000850 EB7A                            jmp     cpu_except
  1258                                  exc5:
  1259 00000852 6A05                            push 	dword 5
  1260 00000854 EB76                            jmp     cpu_except
  1261                                  exc6:
  1262 00000856 6A06                            push 	dword 6
  1263 00000858 EB72                            jmp     cpu_except
  1264                                  exc7:
  1265 0000085A 6A07                            push 	dword 7
  1266 0000085C EB6E                            jmp     cpu_except
  1267                                  exc8:
  1268                                  	; [esp] = Error code
  1269 0000085E 6A08                            push 	dword 8
  1270 00000860 EB5C                            jmp     cpu_except_en
  1271                                  exc9:
  1272 00000862 6A09                            push 	dword 9
  1273 00000864 EB66                            jmp     cpu_except
  1274                                  exc10:
  1275                                  	; [esp] = Error code
  1276 00000866 6A0A                            push 	dword 10
  1277 00000868 EB54                            jmp     cpu_except_en
  1278                                  exc11:
  1279                                  	; [esp] = Error code
  1280 0000086A 6A0B                            push 	dword 11
  1281 0000086C EB50                            jmp     cpu_except_en
  1282                                  exc12:
  1283                                  	; [esp] = Error code
  1284 0000086E 6A0C                            push 	dword 12
  1285 00000870 EB4C                            jmp     cpu_except_en
  1286                                  exc13:
  1287                                  	; [esp] = Error code
  1288 00000872 6A0D                            push 	dword 13
  1289 00000874 EB48                            jmp     cpu_except_en
  1290                                  exc14:
  1291                                  	; [esp] = Error code
  1292 00000876 6A0E                            push 	dword 14
  1293 00000878 EB44                    	jmp	short cpu_except_en
  1294                                  exc15:
  1295 0000087A 6A0F                            push 	dword 15
  1296 0000087C EB4E                            jmp     cpu_except
  1297                                  exc16:
  1298 0000087E 6A10                            push 	dword 16
  1299 00000880 EB4A                            jmp     cpu_except
  1300                                  exc17:
  1301                                  	; [esp] = Error code
  1302 00000882 6A11                            push 	dword 17
  1303 00000884 EB38                    	jmp	short cpu_except_en
  1304                                  exc18:
  1305 00000886 6A12                            push 	dword 18
  1306 00000888 EB42                    	jmp	short cpu_except
  1307                                  exc19:
  1308 0000088A 6A13                            push 	dword 19
  1309 0000088C EB3E                    	jmp	short cpu_except
  1310                                  exc20:
  1311 0000088E 6A14                            push 	dword 20
  1312 00000890 EB3A                    	jmp	short cpu_except
  1313                                  exc21:
  1314 00000892 6A15                            push 	dword 21
  1315 00000894 EB36                    	jmp	short cpu_except
  1316                                  exc22:
  1317 00000896 6A16                            push 	dword 22
  1318 00000898 EB32                    	jmp	short cpu_except
  1319                                  exc23:
  1320 0000089A 6A17                            push 	dword 23
  1321 0000089C EB2E                    	jmp	short cpu_except
  1322                                  exc24:
  1323 0000089E 6A18                            push 	dword 24
  1324 000008A0 EB2A                    	jmp	short cpu_except
  1325                                  exc25:
  1326 000008A2 6A19                            push 	dword 25
  1327 000008A4 EB26                    	jmp	short cpu_except
  1328                                  exc26:
  1329 000008A6 6A1A                            push 	dword 26
  1330 000008A8 EB22                    	jmp	short cpu_except
  1331                                  exc27:
  1332 000008AA 6A1B                            push 	dword 27
  1333 000008AC EB1E                    	jmp	short cpu_except
  1334                                  exc28:
  1335 000008AE 6A1C                            push 	dword 28
  1336 000008B0 EB1A                    	jmp	short cpu_except
  1337                                  exc29:
  1338 000008B2 6A1D                            push 	dword 29
  1339 000008B4 EB16                    	jmp	short cpu_except
  1340                                  exc30:
  1341 000008B6 6A1E                            push 	dword 30
  1342 000008B8 EB04                    	jmp	short cpu_except_en
  1343                                  exc31:
  1344 000008BA 6A1F                            push 	dword 31
  1345 000008BC EB0E                            jmp     short cpu_except
  1346                                  
  1347                                  	; 19/10/2015
  1348                                  	; 19/09/2015
  1349                                  	; 01/09/2015
  1350                                  	; 28/08/2015
  1351                                  	; 28/08/2014
  1352                                  cpu_except_en:
  1353 000008BE 87442404                	xchg	eax, [esp+4] ; Error code
  1354 000008C2 36A3[5CF10000]          	mov	[ss:error_code], eax
  1355 000008C8 58                      	pop	eax  ; Exception number
  1356 000008C9 870424                  	xchg	eax, [esp]
  1357                                  		; eax = eax before exception
  1358                                  		; [esp] -> exception number
  1359                                  		; [esp+4] -> EIP to return
  1360                                  	; 19/10/2015
  1361                                  	; 19/09/2015
  1362                                  	; 01/09/2015
  1363                                  	; 28/08/2015
  1364                                  	; 29/08/2014
  1365                                  	; 28/08/2014
  1366                                  	; 25/08/2014
  1367                                  	; 21/08/2014
  1368                                  cpu_except:	; CPU Exceptions
  1369 000008CC FC                      	cld
  1370 000008CD 870424                  	xchg	eax, [esp] 
  1371                                  		; eax = Exception number
  1372                                  		; [esp] = eax (before exception)	
  1373 000008D0 53                      	push	ebx
  1374 000008D1 56                      	push	esi
  1375 000008D2 57                      	push	edi
  1376 000008D3 1E                      	push 	ds
  1377 000008D4 06                      	push 	es
  1378                                  	; 28/08/2015
  1379 000008D5 66BB1000                	mov	bx, KDATA
  1380 000008D9 8EDB                    	mov	ds, bx
  1381 000008DB 8EC3                    	mov	es, bx
  1382 000008DD 0F20DB                  	mov	ebx, cr3
  1383 000008E0 53                      	push	ebx ; (*) page directory
  1384                                  	; 19/10/2015
  1385 000008E1 FC                      	cld
  1386                                  	; 25/03/2015
  1387 000008E2 8B1D[B8D20000]          	mov	ebx, [k_page_dir]
  1388 000008E8 0F22DB                  	mov	cr3, ebx
  1389                                  	; 28/08/2015
  1390 000008EB 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1391 000008EE 7512                    	jne	short cpu_except_nfp
  1392 000008F0 E8732B0000              	call	page_fault_handler
  1393 000008F5 21C0                    	and 	eax, eax
  1394 000008F7 0F84C0000000                    jz	iiretp ; 01/09/2015
  1395 000008FD B80E000000              	mov	eax, 0Eh ; 14
  1396                                  cpu_except_nfp:
  1397                                  	; 02/04/2015
  1398 00000902 BB[E1050000]            	mov	ebx, hang
  1399 00000907 875C241C                	xchg	ebx, [esp+28]
  1400                                  		; EIP (points to instruction which faults)
  1401                                  	  	; New EIP (hang)
  1402 0000090B 891D[60F10000]          	mov	[FaultOffset], ebx
  1403 00000911 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1404 00000919 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1405                                  	;
  1406 00000921 88C4                    	mov	ah, al
  1407 00000923 240F                    	and	al, 0Fh
  1408 00000925 3C09                    	cmp	al, 9
  1409 00000927 7602                    	jna	short h1ok
  1410 00000929 0407                    	add	al, 'A'-':'
  1411                                  h1ok:
  1412 0000092B D0EC                    	shr	ah, 1
  1413 0000092D D0EC                    	shr	ah, 1
  1414 0000092F D0EC                    	shr	ah, 1
  1415 00000931 D0EC                    	shr	ah, 1
  1416 00000933 80FC09                  	cmp	ah, 9
  1417 00000936 7603                    	jna	short h2ok
  1418 00000938 80C407                  	add	ah, 'A'-':'
  1419                                  h2ok:	
  1420 0000093B 86E0                    	xchg 	ah, al	
  1421 0000093D 66053030                	add	ax, '00'
  1422 00000941 66A3[48CE0000]          	mov	[excnstr], ax
  1423                                  	;
  1424                                  	; 29/08/2014
  1425 00000947 A1[60F10000]            	mov	eax, [FaultOffset]
  1426 0000094C 51                      	push	ecx
  1427 0000094D 52                      	push	edx
  1428 0000094E 89E3                    	mov	ebx, esp
  1429                                  	; 28/08/2015
  1430 00000950 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1431                                  			  ; to hexadecimal string
  1432                                  	;mov	ecx, 10	    ; divisor to convert	
  1433                                  			    ; binary number to decimal string
  1434                                  b2d1:
  1435 00000955 31D2                    	xor	edx, edx
  1436 00000957 F7F1                    	div	ecx
  1437 00000959 6652                    	push	dx
  1438 0000095B 39C8                    	cmp	eax, ecx
  1439 0000095D 73F6                    	jnb	short b2d1
  1440 0000095F BF[53CE0000]            	mov	edi, EIPstr ; EIP value
  1441                                  			    ; points to instruction which faults	
  1442                                  	; 28/08/2015
  1443 00000964 89C2                    	mov	edx, eax
  1444                                  b2d2:
  1445                                  	;add	al, '0'
  1446 00000966 8A82[3A190000]          	mov	al, [edx+hexchrs]
  1447 0000096C AA                      	stosb		    ; write hexadecimal digit to its place	
  1448 0000096D 39E3                    	cmp	ebx, esp
  1449 0000096F 7606                    	jna	short b2d3
  1450 00000971 6658                    	pop	ax
  1451 00000973 88C2                    	mov	dl, al
  1452 00000975 EBEF                    	jmp	short b2d2
  1453                                  b2d3:
  1454 00000977 B068                    	mov 	al, 'h' ; 28/08/2015
  1455 00000979 AA                      	stosb
  1456 0000097A B020                    	mov	al, 20h	    ; space
  1457 0000097C AA                      	stosb
  1458 0000097D 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1459 0000097F AA                      	stosb
  1460                                  	;
  1461 00000980 5A                      	pop	edx
  1462 00000981 59                      	pop	ecx
  1463                                  	;
  1464 00000982 B44F                    	mov	ah, 4Fh	; red (4) background, 
  1465                                  			; white (F) forecolor
  1466 00000984 BE[38CE0000]            	mov	esi, exc_msg ; message offset
  1467                                  	;
  1468 00000989 EB19                    	jmp	short piemsg
  1469                                  	;
  1470                                          ;add    dword [scr_row], 0A0h
  1471                                          ;mov    edi, [scr_row]
  1472                                          ;
  1473                                  	;call 	printk
  1474                                  	;
  1475                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1476                                  	;out	20h, al	; 8259 PORT
  1477                                  	;
  1478                                  	;pop	es
  1479                                  	;pop	ds
  1480                                  	;pop	edi
  1481                                  	;pop	esi
  1482                                  	;pop 	eax
  1483                                  	;iret
  1484                                  	
  1485                                  	; 18/04/2016
  1486                                  	; 28/08/2015
  1487                                  	; 23/02/2015
  1488                                  	; 20/08/2014
  1489                                  ignore_int:
  1490 0000098B 50                      	push	eax
  1491 0000098C 53                      	push	ebx ; 23/02/2015
  1492 0000098D 56                      	push	esi
  1493 0000098E 57                      	push	edi
  1494 0000098F 1E                      	push 	ds
  1495 00000990 06                      	push 	es
  1496                                  	; 18/04/2016
  1497 00000991 66B81000                	mov	ax, KDATA
  1498 00000995 8ED8                    	mov	ds, ax
  1499 00000997 8EC0                    	mov	es, ax
  1500                                  	; 28/08/2015
  1501 00000999 0F20D8                  	mov	eax, cr3
  1502 0000099C 50                      	push	eax ; (*) page directory
  1503                                  	;
  1504 0000099D B467                    	mov	ah, 67h	; brown (6) background, 
  1505                                  			; light gray (7) forecolor
  1506 0000099F BE[22CE0000]            	mov	esi, int_msg ; message offset
  1507                                  piemsg:
  1508                                          ; 27/08/2014
  1509 000009A4 8105[1ACE0000]A000-             add     dword [scr_row], 0A0h
  1509 000009AC 0000               
  1510 000009AE 8B3D[1ACE0000]                  mov     edi, [scr_row]
  1511                                          ;
  1512 000009B4 E867FCFFFF              	call 	printk
  1513                                  	;
  1514                                  	; 23/02/2015
  1515 000009B9 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1516 000009BB E6A0                    	out	0A0h, al ; the 2nd 8259
  1517                                  iiretp: ; 01/09/2015
  1518                                  	; 28/08/2015
  1519 000009BD 58                      	pop	eax ; (*) page directory
  1520 000009BE 0F22D8                  	mov	cr3, eax
  1521                                  	;
  1522                                  iiret:
  1523                                  	; 22/08/2014
  1524 000009C1 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1525 000009C3 E620                    	out	20h, al	; 8259 PORT
  1526                                  	;
  1527 000009C5 07                      	pop	es
  1528 000009C6 1F                      	pop	ds
  1529 000009C7 5F                      	pop	edi
  1530 000009C8 5E                      	pop	esi
  1531 000009C9 5B                      	pop	ebx ; 29/08/2014
  1532 000009CA 58                      	pop 	eax
  1533 000009CB CF                      	iretd
  1534                                  
  1535                                  	; 23/05/2016
  1536                                  	; 22/08/2014
  1537                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  1538                                  	; (INT 1Ah)
  1539                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  1540                                  time_of_day:
  1541 000009CC E808350000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  1542 000009D1 726F                            jc      short time_of_day_retn ; 23/05/2016
  1543 000009D3 B000                    	mov	al, CMOS_SECONDS
  1544 000009D5 E81A350000              	call	CMOS_READ
  1545 000009DA A2[28D30000]            	mov	[time_seconds], al 
  1546 000009DF B002                    	mov	al, CMOS_MINUTES
  1547 000009E1 E80E350000              	call	CMOS_READ
  1548 000009E6 A2[29D30000]            	mov	[time_minutes], al 
  1549 000009EB B004                    	mov	al, CMOS_HOURS
  1550 000009ED E802350000              	call	CMOS_READ
  1551 000009F2 A2[2AD30000]                    mov     [time_hours], al
  1552 000009F7 B006                    	mov	al, CMOS_DAY_WEEK 
  1553 000009F9 E8F6340000              	call	CMOS_READ
  1554 000009FE A2[2BD30000]            	mov	[date_wday], al
  1555 00000A03 B007                     	mov	al, CMOS_DAY_MONTH
  1556 00000A05 E8EA340000              	call	CMOS_READ
  1557 00000A0A A2[2CD30000]            	mov	[date_day], al
  1558 00000A0F B008                    	mov	al, CMOS_MONTH
  1559 00000A11 E8DE340000              	call	CMOS_READ
  1560 00000A16 A2[2DD30000]            	mov	[date_month], al
  1561 00000A1B B009                    	mov	al, CMOS_YEAR
  1562 00000A1D E8D2340000              	call	CMOS_READ
  1563 00000A22 A2[2ED30000]            	mov	[date_year], al
  1564 00000A27 B032                    	mov	al, CMOS_CENTURY
  1565 00000A29 E8C6340000              	call	CMOS_READ
  1566 00000A2E A2[2FD30000]            	mov	[date_century], al
  1567                                  	;
  1568 00000A33 B000                    	mov	al, CMOS_SECONDS
  1569 00000A35 E8BA340000              	call 	CMOS_READ
  1570 00000A3A 3A05[28D30000]          	cmp	al, [time_seconds]
  1571 00000A40 758A                    	jne	short time_of_day
  1572                                  
  1573                                  time_of_day_retn:
  1574 00000A42 C3                      	retn
  1575                                  
  1576                                  	; 10/06/2016
  1577                                  	; 07/06/2016
  1578                                  	; 06/06/2016
  1579                                  	; 23/05/2016
  1580                                  u_timer: 
  1581                                  	; Timer Events with 18.2 Hz Timer Ticks
  1582                                  	; (and also timer events with RTC seconds)
  1583                                  rtc_p:
  1584                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1585                                  	; Major Modification:
  1586                                  	; Check and Perform Timer Events (for RTC)
  1587                                  	; 25/08/2014 - 07/09/2014
  1588                                  	; Retro UNIX 386 v1:
  1589                                   	; Print Real Time Clock content
  1590                                  	
  1591 00000A43 803D[40E00000]00        	cmp	byte [timer_events], 0 ; 07/06/2016
  1592 00000A4A 7649                    	jna	short rtc_p5
  1593                                  
  1594 00000A4C 8A0D[40E00000]          	mov	cl, [timer_events]
  1595                                  
  1596 00000A52 BE[44F00000]            	mov	esi, timer_set  ; beginning address of
  1597                                  				; timer events space
  1598                                  rtc_p0:
  1599 00000A57 8B06                    	mov	eax, [esi]	
  1600 00000A59 20C0                    	and	al, al ; 0 = free, >0 = process ID
  1601 00000A5B 7413                    	jz	short rtc_p2
  1602                                  	;
  1603 00000A5D C1C810                  	ror	eax, 16
  1604                                  	; ah = response value, al = interrupt type
  1605 00000A60 3C01                    	cmp	al, 1 ; RTC interrupt ?
  1606 00000A62 7411                    	je	short rtc_p3 ; yes, check for response
  1607                                  	; 06/06/2016 - 18.2 Hz Timer Ticks
  1608 00000A64 7706                    	ja	short rtc_p1 ; undefined ! ; 10/06/2016
  1609 00000A66 836E080A                	sub	dword [esi+8], 10 ; 1 tick = 10
  1610 00000A6A 7612                    	jna	short rtc_p4  ; continue for responding
  1611                                  rtc_p1:
  1612                                  	; 07/06/2016
  1613 00000A6C FEC9                    	dec	cl    ; remain count of timer events	
  1614 00000A6E 7425                    	jz	short rtc_p5 
  1615                                  rtc_p2:	
  1616                                  	;cmp	esi, timer_set + 240 ; 15*16 (last event)
  1617                                  	;jnb	short rtc_p5 ; end of timer event space
  1618 00000A70 83C610                  	add	esi, 16 ; next timer event
  1619 00000A73 EBE2                    	jmp	short rtc_p0
  1620                                  rtc_p3:	 
  1621                                  	; current timer count ; 06/06/2016 (182)
  1622 00000A75 816E08B6000000          	sub	dword [esi+8], 182 ; 1 second (10*18.2)
  1623 00000A7C 77EE                    	ja	short rtc_p1  ; check for the next 
  1624                                  rtc_p4:	
  1625                                  	; it is the time of response! 
  1626 00000A7E 8B5E04                  	mov	ebx, [esi+4] ; set (count limit) value
  1627 00000A81 895E08                  	mov	[esi+8], ebx ; reset count down value
  1628                                  			     ; to count limit
  1629                                  	; response address is physical address of
  1630                                  	; the program's response (signal return) byte
  1631                                  	; 06/06/2016
  1632 00000A84 8B7E0C                  	mov	edi, [esi+12] ; response address
  1633 00000A87 8827                    	mov	[edi], ah     ; response value 
  1634                                  	;
  1635 00000A89 C1C010                  	rol	eax, 16
  1636                                  	; al = process number  ; 10/06/2016
  1637 00000A8C B202                    	mov	dl, 2 ; priority, 2 = event (high)	
  1638 00000A8E E8ADB40000              	call	set_run_sequence ; 19/05/2016
  1639 00000A93 EBD7                    	jmp	short rtc_p1 ; 10/06/2016
  1640                                  rtc_p5:	 
  1641 00000A95 C3                      	retn
  1642                                  
  1643                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  1644                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  1645                                  default_irq7:
  1646 00000A96 6650                    	push	ax
  1647 00000A98 B00B                    	mov	al, 0Bh  ; In-Service register
  1648 00000A9A E620                    	out	20h, al
  1649 00000A9C EB00                            jmp short $+2
  1650 00000A9E EB00                    	jmp short $+2
  1651 00000AA0 E420                    	in	al, 20h
  1652 00000AA2 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  1653 00000AA4 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  1654 00000AA6 B020                            mov     al, 20h ; EOI
  1655 00000AA8 E620                    	out	20h, al 
  1656                                  irq7_iret:
  1657 00000AAA 6658                    	pop	ax
  1658 00000AAC CF                      	iretd
  1659                                  	
  1660                                  bcd_to_ascii:
  1661                                  	; 25/08/2014
  1662                                  	; INPUT ->
  1663                                  	;	al = Packed BCD number
  1664                                  	; OUTPUT ->
  1665                                  	;	ax  = ASCII word/number
  1666                                  	;
  1667                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  1668                                  	;
  1669 00000AAD D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  1670                                  					; AH = AL / 10h
  1671                                  					; AL = AL MOD 10h
  1672 00000AAF 660D3030                	or ax,'00'                      ; Make it ASCII based
  1673                                  
  1674 00000AB3 86E0                            xchg ah, al 
  1675                                  	
  1676 00000AB5 C3                      	retn	
  1677                                  	
  1678                                  
  1679                                  %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 00000AB6 9C                  <1> 	pushfd	; 28/08/2014
    40 00000AB7 0E                  <1> 	push 	cs
    41 00000AB8 E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
    42 00000ABD 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 00000ABE FB                  <1> 	sti				; INTERRUPTS BACK ON
   141                              <1> 	; 29/05/2016
   142 00000ABF 80642408BE          <1>         and     byte [esp+8], 10111110b ; clear zero flag and cary flag
   143                              <1> 	;
   144 00000AC4 1E                  <1> 	push	ds			; SAVE CURRENT DS
   145 00000AC5 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
   146                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
   147 00000AC6 66BB1000            <1>         mov     bx, KDATA 
   148 00000ACA 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
   149 00000ACC 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
   150 00000ACE 7439                <1> 	jz	short _K1		; ASCII_READ
   151 00000AD0 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
   152 00000AD2 7452                <1>         jz      short _K2               ; ASCII_STATUS
   153 00000AD4 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
   154 00000AD6 0F8492000000        <1>         jz      _K3                     ; SHIFT STATUS
   155 00000ADC FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
   156 00000ADE 0F8491000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
   157 00000AE4 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
   158 00000AE7 0F84B6000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
   159                              <1> _KIO1:	
   160 00000AED 80EC0B              <1> 	sub	ah, 11			; AH =  10H
   161 00000AF0 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
   162 00000AF2 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
   163 00000AF4 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
   164 00000AF6 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
   165 00000AF8 7456                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
   166                              <1> _KIO_EXIT:
   167                              <1> 	;pop	ecx			; RECOVER REGISTER
   168 00000AFA 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   169 00000AFB 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   170 00000AFC CF                  <1> 	iretd				; INVALID COMMAND, EXIT
   171                              <1> 
   172                              <1> 	;-----	ASCII CHARACTER
   173                              <1> _K1E:	
   174 00000AFD E8CE000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
   175 00000B02 E843010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   176 00000B07 EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
   177                              <1> _K1:	
   178 00000B09 E8C2000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
   179 00000B0E E842010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   180 00000B13 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
   181                              <1> _K1A:
   182 00000B15 EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
   183                              <1> 
   184                              <1> 	;-----	ASCII STATUS
   185                              <1> _K2E:	
   186 00000B17 E8FF000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
   187 00000B1C 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   188 00000B1E 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   189 00000B1F E826010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   190 00000B24 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
   191                              <1> _K2:	
   192 00000B26 E8F0000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
   193 00000B2B 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   194 00000B2D 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   195 00000B2E E822010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   196 00000B33 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
   197 00000B35 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
   198 00000B36 E895000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
   199 00000B3B EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
   200                              <1> _K2A:
   201 00000B3D 9D                  <1> 	popf				; RESTORE ZF FROM TEST
   202                              <1> _K2B:
   203                              <1> 	;pop	ecx			; RECOVER REGISTER
   204 00000B3E 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   205 00000B3F 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   206                              <1> 	; (*) 29/05/2016
   207                              <1> 	; (*) retf 4			; THROW AWAY (e)FLAGS
   208 00000B40 7208                <1> 	jc	short _k2d
   209 00000B42 7505                <1> 	jnz	short _k2c
   210 00000B44 804C240840          <1> 	or	byte [esp+8], 01000000b	; set zero flag bit of eflags register
   211                              <1> _k2c:
   212 00000B49 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 00000B4A 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 00000B4F 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 00000B50 8A25[E2CC0000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
   246 00000B56 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 00000B59 C0E405              <1>         shl	ah, 5
   250 00000B5C A0[E2CC0000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
   251 00000B61 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
   252 00000B63 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
   253 00000B65 A0[E4CC0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
   254 00000B6A 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
   255 00000B6C 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
   256                              <1> _K3:
   257 00000B6E A0[E1CC0000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
   258 00000B73 EB85                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
   259                              <1> 
   260                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
   261                              <1> _K300:
   262 00000B75 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
   263 00000B77 7581                <1> 	jne	short _KIO_EXIT		; NO, RETURN
   264 00000B79 F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
   265 00000B7C 0F8578FFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   266 00000B82 F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
   267 00000B85 0F856FFFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   268 00000B8B B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
   269 00000B8D E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   270                              <1> 	;mov	cx, 5			; SHIFT COUNT
   271                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
   272 00000B92 C0E705              <1> 	shl	bh, 5
   273 00000B95 88D8                <1> 	mov	al, bl			; PUT IN RATE
   274 00000B97 08F8                <1> 	or	al, bh			; AND DELAY
   275 00000B99 E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   276 00000B9E E957FFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
   277                              <1> 
   278                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
   279                              <1> _K500:
   280 00000BA3 56                  <1> 	push	esi			; SAVE SI (esi)
   281 00000BA4 FA                  <1> 	cli				; 
   282 00000BA5 8B1D[F2CC0000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
   283 00000BAB 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
   284 00000BAD E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
   285 00000BB2 3B1D[EECC0000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
   286 00000BB8 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
   287 00000BBA 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
   288 00000BBD 891D[F2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
   289 00000BC3 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
   290 00000BC5 EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
   291                              <1> _K502:
   292 00000BC7 B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
   293                              <1> _K504:
   294 00000BC9 FB                  <1> 	sti				
   295 00000BCA 5E                  <1> 	pop	esi			; RECOVER SI (esi)
   296 00000BCB 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 00000BD0 FA                  <1> 	cli	; 03/12/2014
   301 00000BD1 8B1D[EECC0000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   302 00000BD7 3B1D[F2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   303                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
   304 00000BDD 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 00000BDF FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
   313 00000BE0 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
   314                              <1> _K1U:	
   315 00000BE1 FA                  <1> 	cli				; INTERRUPTS BACK OFF
   316 00000BE2 8B1D[EECC0000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   317 00000BE8 3B1D[F2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   318                              <1> _k1x:
   319 00000BEE 53                  <1> 	push	ebx			; SAVE ADDRESS		
   320 00000BEF 9C                  <1> 	pushf				; SAVE FLAGS
   321 00000BF0 E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   322 00000BF5 8A1D[E3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   323 00000BFB 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   324 00000BFD 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
   325 00000C00 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
   326 00000C02 E8C9060000          <1> 	call	SND_LED1
   327 00000C07 FA                  <1> 	cli				; DISABLE INTERRUPTS
   328                              <1> _K1V:
   329 00000C08 9D                  <1> 	popf				; RESTORE FLAGS
   330 00000C09 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
   331 00000C0A 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
   332                              <1> 	;
   333 00000C0C 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
   334 00000C0F E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
   335 00000C14 891D[EECC0000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
   336 00000C1A C3                  <1> 	retn				; RETURN
   337                              <1> 
   338                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
   339                              <1> _K2S:
   340 00000C1B FA                  <1> 	cli				; INTERRUPTS OFF
   341 00000C1C 8B1D[EECC0000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   342 00000C22 3B1D[F2CC0000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
   343 00000C28 668B03              <1> 	mov	ax, [ebx]
   344 00000C2B 9C                  <1> 	pushf				; SAVE FLAGS
   345 00000C2C 6650                <1> 	push	ax			; SAVE CODE
   346 00000C2E E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   347 00000C33 8A1D[E3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   348 00000C39 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   349 00000C3B 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
   350 00000C3E 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
   351 00000C40 E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   352                              <1> _K2T:
   353 00000C45 6658                <1> 	pop	ax			; RESTORE CODE
   354 00000C47 9D                  <1> 	popf				; RESTORE FLAGS
   355 00000C48 FB                  <1> 	sti				; INTERRUPTS BACK ON
   356 00000C49 C3                  <1> 	retn				; RETURN
   357                              <1> 
   358                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
   359                              <1> _KIO_E_XLAT:
   360 00000C4A 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   361 00000C4C 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
   362 00000C4E 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
   363 00000C50 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
   364 00000C52 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
   365                              <1> _KIO_E_RET:				
   366 00000C54 C3                  <1> 	retn				; GO BACK
   367                              <1> 
   368                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
   369                              <1> _KIO_S_XLAT:
   370 00000C55 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
   371 00000C58 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
   372 00000C5A 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
   373 00000C5C 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
   374 00000C5E 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
   375 00000C60 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
   376 00000C62 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
   377                              <1> _kio_ret: ; 03/12/2014
   378 00000C64 F8                  <1> 	clc
   379 00000C65 C3                  <1> 	retn
   380                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   381                              <1> _KIO_S1:				
   382 00000C66 B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
   383                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   384 00000C68 C3                  <1> 	retn
   385                              <1> _KIO_S2:		
   386 00000C69 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
   387 00000C6C 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
   388 00000C6E 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   389 00000C70 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
   390 00000C72 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   391 00000C74 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
   392 00000C76 EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
   393                              <1> _KIO_S3:
   394 00000C78 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 00000C7A 75E8                <1> 	jne	short _kio_ret
   397 00000C7C 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   398 00000C7E 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
   399 00000C80 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 00000C82 C3                  <1> 	retn				; RETURN	
   404                              <1> _KIO_DIS:
   405 00000C83 F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
   406 00000C84 C3                  <1> 	retn				; RETURN
   407                              <1> 
   408                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
   409                              <1> _K4:    
   410 00000C85 43                  <1> 	inc     ebx
   411 00000C86 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
   412 00000C87 3B1D[EACC0000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
   413                              <1>         ;jne    short _K5               ; NO, CONTINUE
   414 00000C8D 7206                <1> 	jb	short _K5
   415 00000C8F 8B1D[E6CC0000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
   416                              <1> _K5:
   417 00000C95 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 00000C96 FB                  <1> 	sti				; ENABLE INTERRUPTS
   527                              <1> 	;push	ebp
   528 00000C97 50                  <1> 	push	eax
   529 00000C98 53                  <1> 	push	ebx
   530 00000C99 51                  <1> 	push	ecx
   531 00000C9A 52                  <1> 	push	edx
   532 00000C9B 56                  <1> 	push	esi
   533 00000C9C 57                  <1> 	push	edi
   534 00000C9D 1E                  <1> 	push	ds
   535 00000C9E 06                  <1> 	push	es
   536 00000C9F FC                  <1> 	cld				; FORWARD DIRECTION
   537 00000CA0 66B81000            <1> 	mov	ax, KDATA
   538 00000CA4 8ED8                <1> 	mov	ds, ax
   539 00000CA6 8EC0                <1> 	mov	es, ax
   540                              <1> 	;
   541                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
   542 00000CA8 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
   543 00000CAA E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
   544 00000CAF FA                  <1> 	cli				; DISABLE INTERRUPTS
   545 00000CB0 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
   546                              <1> KB_INT_01:
   547 00000CB5 E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
   548 00000CB7 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
   549 00000CB9 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
   550                              <1> 	;
   551                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
   552 00000CBB 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> 	;				; EXT 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 00000CBD FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
   566 00000CBE 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
   567 00000CC0 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
   568                              <1> 	;
   569                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
   570 00000CC2 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
   571 00000CC4 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
   572                              <1> 	;
   573                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
   574 00000CC6 FA                  <1> 	cli				; DISABLE INTERRUPTS
   575 00000CC7 800D[E3CC0000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
   576 00000CCE 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 00000CD3 FA                  <1> 	cli				; DISABLE INTERRUPTS
   581 00000CD4 800D[E3CC0000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
   582 00000CDB 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 00000CE0 6650                <1> 	push 	ax			; SAVE DATA IN
   587 00000CE2 E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   588 00000CE7 8A1D[E3CC0000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   589 00000CED 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   590 00000CEF 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
   591 00000CF2 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
   592 00000CF4 E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   593                              <1> UP0:
   594 00000CF9 6658                <1> 	pop	ax			; RESTORE DATA IN
   595                              <1> ;------------------------------------------------------------------------
   596                              <1> ;	START OF KEY PROCESSING						;
   597                              <1> ;------------------------------------------------------------------------
   598 00000CFB 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
   599                              <1> 	;
   600                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
   601 00000CFD 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
   602 00000CFF 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
   603                              <1> 	;
   604                              <1> K16:	
   605 00000D05 8A3D[E4CC0000]      <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 00000D0B F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
   609 00000D0E 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
   610 00000D10 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
   611 00000D12 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
   612 00000D14 7507                <1> 	jne	short RST_RD_ID
   613 00000D16 800D[E4CC0000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   614                              <1> RST_RD_ID:
   615 00000D1D 8025[E4CC0000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
   616                              <1>         ;jmp    short ID_EX		; AND EXIT
   617 00000D24 E924020000          <1> 	jmp	K26
   618                              <1> 	;
   619                              <1> TST_ID_2:
   620 00000D29 8025[E4CC0000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
   621 00000D30 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
   622 00000D32 7419                <1>         je	short KX_BIT		; JUMP IF SO
   623 00000D34 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
   624                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
   625 00000D36 0F8511020000        <1> 	jne	K26
   626                              <1> 	;
   627                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
   628 00000D3C F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
   629 00000D3F 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
   630 00000D41 800D[E1CC0000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
   631 00000D48 E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
   632                              <1> KX_BIT:
   633 00000D4D 800D[E4CC0000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
   634 00000D54 E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
   635                              <1> 	;
   636                              <1> NOT_ID:
   637 00000D59 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
   638 00000D5B 750C                <1> 	jne	short TEST_E1
   639 00000D5D 800D[E4CC0000]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 00000D64 E9EB010000          <1> 	jmp	K26A	
   642                              <1> TEST_E1:	
   643 00000D69 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
   644 00000D6B 750C                <1> 	jne	short NOT_HC
   645 00000D6D 800D[E4CC0000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
   646 00000D74 E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
   647                              <1> 	;
   648                              <1> NOT_HC:
   649 00000D79 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
   650 00000D7B F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
   651 00000D7E 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
   652                              <1> 	;
   653 00000D80 BF[CECB0000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
   654 00000D85 AE                  <1> 	scasb
   655 00000D86 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
   656 00000D8C AE                  <1> 	scasb
   657 00000D8D 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
   658                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
   659 00000D8F E9B9010000          <1> 	jmp	K26
   660                              <1> 	;
   661                              <1> NOT_LC_E0:
   662 00000D94 F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
   663 00000D97 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
   664 00000D99 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
   665 00000D9E BF[CCCB0000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
   666 00000DA3 F2AE                <1> 	repne	scasb			; CHECK IT
   667                              <1> 	;je	short EXIT		; THROW AWAY IF SO
   668 00000DA5 0F84A9010000        <1> 	je	K26A			
   669                              <1> 	;
   670 00000DAB 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
   671                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
   672 00000DAD 0F859A010000        <1> 	jne	K26
   673 00000DB3 F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
   674                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
   675 00000DB6 0F8591010000        <1> 	jnz	K26
   676                              <1>         ; 20/02/2015 
   677 00000DBC F605[E2CC0000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
   678                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
   679 00000DC3 0F8584010000        <1> 	jnz	K26
   680 00000DC9 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 00000DCE 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
   685 00000DD0 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
   686                              <1> 	;
   687 00000DD2 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
   688 00000DD5 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
   689                              <1> 	;
   690 00000DD7 F605[E2CC0000]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 00000DDE 0F8569010000        <1> 	jnz     K26			
   693                              <1> 	;
   694 00000DE4 800D[E2CC0000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
   695 00000DEB B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   696 00000DED E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   697                              <1> 					; INTERRUPT-RETURN-NO-EOI
   698 00000DEF B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   699 00000DF1 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 00000DF6 E965010000          <1>         jmp     K27A                    ; END PROCESSING
   705                              <1> 	;
   706                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
   707                              <1> 	;
   708                              <1> K16C:
   709 00000DFB 8025[E2CC0000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
   710 00000E02 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   711 00000E04 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 00000E06 E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
   722                              <1> 	;
   723                              <1> 	;-----	TEST FOR SHIFT KEYS
   724                              <1> K16A:
   725 00000E0B 8A1D[E1CC0000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   726 00000E11 BF[C8CB0000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
   727 00000E16 B908000000          <1> 	mov	ecx, _K6L		; LENGTH
   728 00000E1B F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
   729 00000E1D 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
   730 00000E1F 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
   731                              <1> 	;
   732                              <1> 	;------	SHIFT KEY FOUND
   733                              <1> K17:
   734 00000E25 81EF[C9CB0000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   735 00000E2B 8AA7[D0CB0000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
   736 00000E31 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
   737 00000E33 A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
   738 00000E35 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
   739                              <1> 	;
   740                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
   741                              <1> K17C:
   742 00000E3B 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
   743 00000E3E 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
   744                              <1> 	;
   745                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
   746 00000E40 0825[E1CC0000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
   747 00000E46 A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
   748                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
   749 00000E48 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
   750                              <1> K17D:
   751 00000E4E F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
   752 00000E51 740B                <1> 	jz 	short K17E		; NO, JUMP
   753 00000E53 0825[E4CC0000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
   754 00000E59 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
   755                              <1> K17E:
   756 00000E5E D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
   757 00000E60 0825[E2CC0000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
   758 00000E66 E9E2000000          <1> 	jmp	K26
   759                              <1> 	;
   760                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
   761                              <1> K18:					; SHIFT-TOGGLE
   762 00000E6B F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
   763                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
   764 00000E6E 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
   765                              <1> K18A:
   766 00000E74 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
   767 00000E76 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
   768 00000E78 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
   769                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
   770 00000E7B 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
   771                              <1> K18B:
   772 00000E81 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
   773 00000E84 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
   774                              <1> K19:	
   775 00000E86 F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
   776 00000E89 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
   777 00000E8B F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
   778 00000E8E 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
   779                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
   780 00000E90 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
   781 00000E92 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
   782                              <1> K21:					; MIGHT BE NUMERIC
   783 00000E97 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
   784 00000E9A 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
   785                              <1> 	;
   786                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
   787 00000E9C 8425[E2CC0000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
   788 00000EA2 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
   789                              <1> K22A:
   790 00000EA8 0825[E2CC0000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   791 00000EAE 3025[E1CC0000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
   792                              <1> 	;
   793                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
   794 00000EB4 F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
   795 00000EB7 7409                <1> 	jz	short K22B		; GO IF NOT
   796                              <1> 	;
   797 00000EB9 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
   798 00000EBB E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
   799 00000EC0 6658                <1> 	pop	ax			; RESTORE SCAN CODE
   800                              <1> K22B:
   801 00000EC2 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
   802 00000EC4 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
   803 00000ECA 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
   804 00000ECC E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
   805                              <1> 	;
   806                              <1> 	;-----	BREAK SHIFT FOUND
   807                              <1> K23:					; BREAK-SHIFT-FOUND
   808 00000ED1 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
   809 00000ED4 F6D4                <1> 	not	ah			; INVERT MASK
   810 00000ED6 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
   811 00000ED8 2025[E1CC0000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
   812 00000EDE 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
   813 00000EE1 7730                <1> 	ja	short K23D		; NO, ALL DONE
   814                              <1> 	;
   815 00000EE3 F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
   816 00000EE6 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
   817 00000EE8 2025[E4CC0000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
   818 00000EEE EB08                <1> 	jmp	short K23B		; CONTINUE
   819                              <1> K23A:
   820 00000EF0 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
   821 00000EF2 2025[E2CC0000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
   822                              <1> K23B:
   823 00000EF8 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
   824 00000EFA A0[E4CC0000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
   825 00000EFF D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
   826 00000F01 0A05[E2CC0000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
   827 00000F07 D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
   828 00000F09 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
   829 00000F0B 0805[E1CC0000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
   830 00000F11 88E0                <1> 	mov	al, ah
   831                              <1> K23D:
   832 00000F13 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
   833 00000F15 7536                <1> 	jne	short K26		; INTERRUPT RETURN
   834                              <1> 	;	
   835                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
   836 00000F17 A0[E5CC0000]        <1> 	mov	al, [ALT_INPUT]
   837 00000F1C B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   838 00000F1E 8825[E5CC0000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
   839 00000F24 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
   840 00000F26 7425                <1> 	je	short K26		; INTERRUPT_RETURN
   841                              <1>         ; 29/01/2016
   842                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
   843 00000F28 E9D0020000          <1> 	jmp	_K60
   844                              <1> 	;
   845                              <1> K24:					; BREAK-TOGGLE
   846 00000F2D 2025[E2CC0000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
   847 00000F33 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 00000F35 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
   853 00000F37 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
   854 00000F39 F605[E2CC0000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
   855 00000F40 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
   856 00000F42 3C45                <1> 	cmp	al, NUM_KEY
   857 00000F44 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
   858 00000F46 8025[E2CC0000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   859                              <1> 	;
   860                              <1> K26:
   861 00000F4D 8025[E4CC0000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
   862                              <1> K26A:					; INTERRUPT-RETURN
   863 00000F54 FA                  <1> 	cli				; TURN OFF INTERRUPTS
   864 00000F55 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   865 00000F57 E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   866                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
   867 00000F59 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   868 00000F5B E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   869                              <1> K27A:
   870 00000F60 FA                  <1> 	cli				; DISABLE INTERRUPTS
   871 00000F61 07                  <1> 	pop	es			; RESTORE REGISTERS
   872 00000F62 1F                  <1> 	pop	ds
   873 00000F63 5F                  <1> 	pop	edi
   874 00000F64 5E                  <1> 	pop	esi
   875 00000F65 5A                  <1> 	pop	edx
   876 00000F66 59                  <1> 	pop	ecx
   877 00000F67 5B                  <1> 	pop	ebx
   878 00000F68 58                  <1> 	pop	eax
   879                              <1> 	;pop	ebp
   880 00000F69 CF                  <1> 	iret				; RETURN
   881                              <1> 
   882                              <1> 	;-----	NOT IN	HOLD STATE
   883                              <1> K28:					; NO-HOLD-STATE
   884 00000F6A 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
   885 00000F6C 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
   886                              <1> 	;
   887 00000F6E F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
   888                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
   889 00000F71 0F84F1000000        <1>         jz      K38
   890                              <1> 	;
   891 00000F77 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
   892 00000F7A 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
   893                              <1> 	 ;28/02/2015
   894 00000F7C F605[E2CC0000]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 00000F83 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 00000F89 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
   903 00000F8C 740B                <1> 	jz	short K31		; NO_RESET
   904 00000F8E 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
   905 00000F90 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 00000F92 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
   913 00000F94 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
   914                              <1> khere:
   915 00000F96 F4                  <1> 	hlt				; WAIT FOR 80286 RESET
   916 00000F97 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 00000F99 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
   922 00000F9B 7507                <1> 	jne	short K311		; NOT THERE
   923 00000F9D B020                <1> 	mov	al, ' '			; SET SPACE CHAR
   924 00000F9F E948020000          <1>         jmp     K57                     ; BUFFER_FILL
   925                              <1> K311:
   926 00000FA4 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
   927 00000FA6 7509                <1> 	jne	short K312		; NOT THERE
   928 00000FA8 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
   929 00000FAC E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
   930                              <1> K312:
   931 00000FB1 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
   932 00000FB3 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
   933 00000FB9 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
   934 00000FBB 0F849A000000        <1>         je      K37B                    ; GO PROCESS
   935                              <1> 	;
   936                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
   937                              <1> K32:					; ALT-KEY-PAD
   938 00000FC1 BF[A4CB0000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
   939 00000FC6 B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
   940 00000FCB F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
   941 00000FCD 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
   942 00000FCF F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
   943 00000FD2 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
   944 00000FD8 81EF[A5CB0000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   945 00000FDE A0[E5CC0000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
   946 00000FE3 B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
   947 00000FE5 F6E4                <1> 	mul	ah
   948 00000FE7 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
   949 00000FEA A2[E5CC0000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
   950                              <1> ;K32A:
   951 00000FEF E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
   952                              <1> 	;
   953                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
   954                              <1> K33:					; NO-ALT-KEYPAD
   955 00000FF4 C605[E5CC0000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
   956 00000FFB B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
   957 00001000 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
   958 00001002 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 00001004 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
   963 00001006 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
   964 00001008 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
   965 0000100A 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
   966 0000100C 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
   967 0000100F 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 00001011 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
   972 00001013 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
   973 00001015 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
   974 00001017 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
   975 00001019 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
   976 0000101C EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   977                              <1> K35A:
   978 0000101E F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
   979 00001021 7422                <1> 	jz	short K37		; NO, JUMP
   980 00001023 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
   981 00001025 7509                <1>         jne     short K35B              ; NOT THERE
   982 00001027 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
   983 0000102B E9BC010000          <1> 	jmp	K57			; BUFFER FILL
   984                              <1> K35B:
   985 00001030 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
   986 00001032 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
   987 00001034 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
   988                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
   989 00001036 0F8511FFFFFF        <1>         jne     K26
   990 0000103C 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
   991 00001040 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
   992                              <1> K37:
   993 00001045 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
   994 00001047 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
   995 00001049 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
   996                              <1>         ;ja	short K32A		; IF SO, IGNORE
   997 0000104B 0F87FCFEFFFF        <1>         ja      K26
   998 00001051 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
   999                              <1> K37A:
  1000 00001054 B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  1001 00001056 E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  1002                              <1> K37B:
  1003 0000105B B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  1004 0000105D E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  1005                              <1> K37C:
  1006 00001062 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  1007 00001064 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  1008 00001066 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 00001068 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  1014                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  1015 0000106B 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 00001071 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  1021 00001073 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  1022 00001075 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1023 00001078 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  1024 0000107A F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1025 0000107D 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  1026                              <1> K38B:
  1027 0000107F 8B1D[EECC0000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  1028 00001085 891D[F2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx
  1029 0000108B C605[E0CC0000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  1030                              <1> 	;
  1031                              <1> 	;-----	ENABLE KEYBOARD
  1032 00001092 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1033 00001094 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 00001099 E80B300000          <1> 	call	ctrlbrk ; control+break subroutine
  1039                              <1> 	;
  1040 0000109E 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  1041 000010A1 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  1042                              <1> 	;
  1043                              <1> 	;-----	TEST FOR PAUSE
  1044                              <1> K39:					; NO_BREAK
  1045 000010A6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1046 000010A9 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  1047 000010AB 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  1048 000010AD 7533                <1> 	jne	short K41		; NO-PAUSE
  1049                              <1> K39P:
  1050 000010AF 800D[E2CC0000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  1051                              <1> 	;
  1052                              <1> 	;-----	ENABLE KEYBOARD
  1053 000010B6 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1054 000010B8 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1055                              <1> K39A:
  1056 000010BD B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  1057 000010BF 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 000010C1 803D[16CD0000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  1061 000010C8 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  1062 000010CA 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  1063 000010CE A0[17CD0000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  1064 000010D3 EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  1065                              <1> 	;
  1066                              <1> K40:					; PAUSE-LOOP
  1067 000010D4 F605[E2CC0000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  1068 000010DB 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  1069                              <1> 	;
  1070 000010DD E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  1071                              <1>         ;
  1072                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  1073                              <1> K41:					; NO-PAUSE
  1074 000010E2 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  1075 000010E4 7513                <1> 	jne	short K42		; NOT-KEY-55
  1076 000010E6 F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1077 000010E9 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  1078 000010EB F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1079 000010EE 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  1080                              <1> K41A:	
  1081 000010F0 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  1082 000010F4 E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  1083                              <1> 	;
  1084                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  1085                              <1> K42:					; NOT-KEY-55
  1086 000010F9 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  1087 000010FB 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  1088 000010FD 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  1089 000010FF 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  1090 00001101 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  1091 00001104 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  1092 00001106 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  1093 0000110A E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  1094                              <1> K42A: 
  1095                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1096 0000110F 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 00001111 BB[D8CB0000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1102 00001116 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  1103 0000111C E9B9000000          <1> 	jmp	K64	
  1104                              <1>         ;
  1105                              <1> 	;-----	NOT IN CONTROL SHIFT
  1106                              <1> K44:					; NOT-CTL-SHIFT
  1107 00001121 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  1108 00001123 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  1109 00001125 F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  1110 00001128 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  1111 0000112A F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  1112 0000112D 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  1113 0000112F EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1114                              <1> K44A:
  1115 00001131 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  1116 00001134 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1117                              <1> 	;
  1118                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  1119                              <1> K44B:
  1120 00001136 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1121 00001138 E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1122 0000113D B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  1123 0000113F 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 00001141 8025[E4CC0000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  1129 00001148 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  1130                              <1> 	;
  1131                              <1> 	;-----	HANDLE IN-CORE KEYS
  1132                              <1> K45:					; NOT-PRINT-SCREEN
  1133 0000114D 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  1134 0000114F 7734                <1> 	ja	short K46		; JUMP IF NOT
  1135 00001151 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  1136 00001153 7505                <1> 	jne	short K45A		; NO, JUMP
  1137 00001155 F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  1138 00001158 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  1139                              <1> K45A:
  1140 0000115A B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  1141 0000115F BF[AECB0000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  1142 00001164 F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  1143                              <1> 		; 20/02/2015
  1144 00001166 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  1145                              <1> 	;
  1146 00001168 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  1147 0000116B 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  1148                              <1> K45B:
  1149 0000116D F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1150 00001170 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  1151                              <1> 					; NO, LOWERCASE
  1152                              <1> K45C:
  1153 00001172 BB[30CC0000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  1154 00001177 EB51                <1> 	jmp	short K56	
  1155                              <1> K45D:					; ALMOST-CAPS-STATE
  1156 00001179 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  1157 0000117C 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  1158                              <1> K45E:
  1159 0000117E BB[88CC0000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  1160 00001183 EB45                <1> K45F:	jmp	short K56
  1161                              <1> 	;
  1162                              <1> 	;-----	TEST FOR KEYS F1 - F10
  1163                              <1> K46:					; NOT IN-CORE AREA
  1164 00001185 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 00001187 7635                <1> 	jna	short K53		
  1168                              <1> 	;
  1169                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  1170                              <1> K47:					; NOT F1 - F10
  1171 00001189 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  1172 0000118B 772D                <1> 	ja	short K52		; JUMP IF NOT
  1173                              <1> 	;
  1174                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  1175                              <1> K48:
  1176 0000118D 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  1177 0000118F 74ED                <1> 	je	short K45E		; GO TRANSLATE
  1178 00001191 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  1179 00001193 74E9                <1> 	je	short K45E		; GO TRANSLATE
  1180 00001195 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  1181 00001198 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  1182                              <1> 	;		
  1183 0000119A F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  1184 0000119D 7514                <1> 	jnz	short K50		; TEST FOR SURE
  1185 0000119F F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1186                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  1187 000011A2 75DA                <1> 	jnz	short K45E
  1188                              <1> 	;
  1189                              <1> 	;-----	BASE CASE FOR KEYPAD
  1190                              <1> K49:					
  1191 000011A4 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  1192 000011A6 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  1193 000011A8 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  1194 000011AA EB40                <1> 	jmp	short K57		; BUFFER FILL
  1195                              <1> K49A:
  1196 000011AC BB[30CC0000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  1197 000011B1 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 000011B3 F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  1202 000011B6 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  1203 000011B8 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 000011BA 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 000011BC 74AF                <1> 	je	short K45B		
  1211                              <1> 	;
  1212                              <1> 	;-----	MUST BE F11 OR F12 
  1213                              <1> K53:					; F1 - F10 COME HERE, TOO
  1214 000011BE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  1215 000011C1 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  1216                              <1> 		; 20/02/2015 
  1217 000011C3 BB[88CC0000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  1218 000011C8 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  1219                              <1> 	;
  1220                              <1> 	;-----	TRANSLATE THE CHARACTER
  1221                              <1> K56:					; TRANSLATE-CHAR
  1222 000011CA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1223 000011CC D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  1224 000011CD F605[E4CC0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1225 000011D4 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1226 000011D6 B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  1227 000011D8 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 000011DA FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1232 000011DC D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  1233 000011DD 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  1234 000011DF B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  1235 000011E1 F605[E4CC0000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1236 000011E8 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1237 000011EA 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 000011EC 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  1242                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  1243 000011EE 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  1244 000011F4 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  1245                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  1246 000011F7 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 000011FD 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  1252 00001200 721F                <1> 	jb	short K61
  1253 00001202 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  1254 00001205 771A                <1> 	ja	short K61
  1255                              <1> 	;
  1256 00001207 8A1D[E6D20000]      <1> 	mov	bl, [ACTIVE_PAGE]
  1257 0000120D 80C368              <1> 	add	bl, 68h
  1258 00001210 38E3                <1> 	cmp	bl, ah
  1259 00001212 740D                <1> 	je	short K61
  1260 00001214 6650                <1> 	push	ax
  1261 00001216 88E0                <1> 	mov	al, ah
  1262 00001218 2C68                <1> 	sub	al, 68h
  1263 0000121A E8A6020000          <1> 	call	set_active_page
  1264 0000121F 6658                <1> 	pop	ax
  1265                              <1> K61:					; NOT-CAPS-STATE
  1266 00001221 8B1D[F2CC0000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  1267 00001227 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  1268 00001229 E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  1269 0000122E 3B1D[EECC0000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  1270 00001234 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  1271 00001236 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  1272 00001239 891D[F2CC0000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  1273 0000123F 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 00001244 B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  1288 00001246 E620                <1> 	out	INTA00, al
  1289 00001248 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  1290 0000124C B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  1291 0000124E E893050000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  1292 00001253 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 00001258 6650                <1> 	push	ax			; SAVE DATA TO SEND
  1302                              <1> 
  1303                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  1304 0000125A FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  1305                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  1306 0000125B B900000100          <1> 	mov	ecx, 10000h			
  1307                              <1> S10:
  1308 00001260 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  1309 00001262 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  1310 00001264 E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  1311                              <1> 
  1312 00001266 6658                <1> 	pop	ax			; GET DATA TO SEND
  1313 00001268 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  1314 0000126A FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  1315 0000126B 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 0000126C 6650                <1> 	push	ax			; SAVE REGISTERS
  1326 0000126E 6653                <1> 	push	bx
  1327 00001270 51                  <1> 	push	ecx
  1328 00001271 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  1329 00001273 B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  1330                              <1> SD0:
  1331 00001275 FA                  <1> 	cli				; DISABLE INTERRUPTS
  1332 00001276 8025[E3CC0000]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 0000127D B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  1336                              <1> SD5:
  1337 00001282 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  1338 00001284 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  1339 00001286 E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  1340                              <1> 	;
  1341 00001288 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  1342 0000128A E660                <1> 	out	PORT_A, al		; SEND BYTE
  1343 0000128C FB                  <1> 	sti				; ENABLE INTERRUPTS
  1344                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  1345 0000128D B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  1346                              <1> SD1:
  1347 00001292 F605[E3CC0000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  1348 00001299 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  1349 0000129B E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  1350                              <1> SD2:
  1351 0000129D FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  1352 0000129F 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  1353 000012A1 800D[E3CC0000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  1354 000012A8 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  1355                              <1> SD3:
  1356 000012AA F605[E3CC0000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  1357 000012B1 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  1358                              <1> SD4:	
  1359 000012B3 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  1360 000012B4 665B                <1> 	pop	bx
  1361 000012B6 6658                <1> 	pop	ax
  1362 000012B8 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 000012B9 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1372 000012BA F605[E3CC0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1373 000012C1 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1374                              <1> 	;
  1375 000012C3 800D[E3CC0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1376 000012CA B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  1377 000012CC E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  1378 000012CE EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  1379                              <1> SND_LED1:
  1380 000012D0 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1381 000012D1 F605[E3CC0000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1382 000012D8 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1383                              <1> 	;
  1384 000012DA 800D[E3CC0000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1385                              <1> SL0:
  1386 000012E1 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  1387 000012E3 E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1388 000012E8 FA                  <1> 	cli
  1389 000012E9 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  1390 000012EE 8025[E3CC0000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1391 000012F5 0805[E3CC0000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1392 000012FB F605[E3CC0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1393 00001302 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  1394                              <1> 	;
  1395 00001304 E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1396 00001309 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1397 0000130A F605[E3CC0000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1398 00001311 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  1399                              <1> SL2:
  1400 00001313 B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  1401 00001315 E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1402 0000131A FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1403                              <1> SL3:
  1404 0000131B 8025[E3CC0000]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 00001322 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1407 00001323 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 00001324 A0[E1CC0000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  1418 00001329 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 0000132B C0C004              <1> 	rol	al, 4 ; 20/02/2015
  1422 0000132E 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  1423                              <1> 	;pop	cx
  1424 00001330 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 ///
  1680                                  
  1681                                  %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: 17/06/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 00001331 9C                  <1> 	pushfd
    35 00001332 0E                  <1> 	push 	cs
    36 00001333 E851000000          <1> 	call 	VIDEO_IO_1
    37 00001338 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 00001339 [DA130000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   191 0000133D [72140000]          <1> 	dd	SET_CTYPE
   192 00001341 [8A140000]          <1> 	dd	SET_CPOS
   193 00001345 [94140000]          <1> 	dd	READ_CURSOR
   194 00001349 [EB130000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
   195 0000134D [BB140000]          <1> 	dd	ACT_DISP_PAGE
   196 00001351 [34150000]          <1> 	dd	SCROLL_UP
   197 00001355 [1E160000]          <1> 	dd	SCROLL_DOWN
   198 00001359 [71160000]          <1> 	dd	READ_AC_CURRENT
   199 0000135D [9F160000]          <1> 	dd	WRITE_AC_CURRENT
   200 00001361 [B2160000]          <1> 	dd	WRITE_C_CURRENT
   201 00001365 [EB130000]          <1> 	dd	VIDEO_RETURN	; SET_COLOR
   202 00001369 [EB130000]          <1> 	dd	VIDEO_RETURN	; WRITE_DOT
   203 0000136D [EB130000]          <1> 	dd	VIDEO_RETURN	; READ_DOT
   204 00001371 [F8160000]          <1> 	dd	WRITE_TTY
   205 00001375 [C7130000]          <1> 	dd	VIDEO_STATE
   206 00001379 [EB130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   207 0000137D [EB130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   208 00001381 [EB130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   209 00001385 [EB130000]          <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 00001389 FB                  <1> 	sti				; INTERRUPTS BACK ON
   223 0000138A FC                  <1> 	cld				; SET DIRECTION FORWARD
   224 0000138B 80FC14              <1> 	cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
   225 0000138E 7326                <1> 	jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
   226                              <1> 
   227 00001390 06                  <1> 	push	es
   228 00001391 1E                  <1> 	push	ds			; SAVE WORK AND PARAMETER REGISTERS
   229 00001392 52                  <1> 	push	edx
   230 00001393 51                  <1> 	push	ecx
   231 00001394 53                  <1> 	push	ebx
   232 00001395 56                  <1> 	push	esi
   233 00001396 57                  <1> 	push	edi
   234 00001397 55                  <1> 	push	ebp
   235 00001398 66BE1000            <1> 	mov	si, KDATA 		; POINT DS: TO DATA SEGMENT
   236 0000139C 8EDE                <1> 	mov	ds, si
   237 0000139E 8EC6                <1> 	mov	es, si
   238 000013A0 BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
   239 000013A5 A3[34E00000]        <1> 	mov	[video_eax], eax ; 12/05/2016 
   240                              <1> 	; 23/03/2016
   241 000013AA C0E402              <1> 	shl	ah, 2  ; dword		; TIMES 2 FOR WORD TABLE LOOKUP
   242 000013AD 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 000013B0 FFA6[39130000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
   246                              <1> 
   247                              <1> M4:					;	COMMAND NOT VALID
   248 000013B6 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 000013B7 53                  <1> 	push	ebx
   257 000013B8 52                  <1> 	push	edx
   258 000013B9 50                  <1> 	push	eax
   259 000013BA 57                  <1> 	push	edi
   260 000013BB 51                  <1> 	push	ecx
   261 000013BC E838000000          <1> 	call	set_txt_mode
   262 000013C1 59                  <1> 	pop	ecx
   263 000013C2 5F                  <1> 	pop	edi
   264 000013C3 58                  <1> 	pop	eax
   265 000013C4 5A                  <1> 	pop	edx
   266 000013C5 5B                  <1> 	pop	ebx
   267 000013C6 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 000013C7 B480                <1> 	mov	ah, 80h
   283 000013C9 A0[16CD0000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
   284                              <1> 	;movzx	esi, al
   285                              <1> 	;mov	ah, [esi+M6] 
   286                              <1> 	; BH = active page
   287 000013CE 8A3D[E6D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
   288 000013D4 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
   289 000013D5 5F                  <1> 	pop	edi
   290 000013D6 5E                  <1> 	pop	esi
   291 000013D7 59                  <1> 	pop	ecx		; DISCARD SAVED BX
   292 000013D8 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 000013DA FE05[3BE00000]      <1> 	inc 	byte [set_mode_clear] ; 29/05/2016
   313                              <1> 
   314 000013E0 E814000000          <1> 	call	set_txt_mode
   315                              <1> 
   316 000013E5 FE0D[3BE00000]      <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 000013EB A1[34E00000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   325                              <1> _video_return:
   326 000013F0 5D                  <1> 	pop	ebp
   327 000013F1 5F                  <1> 	pop	edi
   328 000013F2 5E                  <1> 	pop	esi
   329 000013F3 5B                  <1> 	pop	ebx
   330                              <1> M15:	; VIDEO_RETURN_C
   331 000013F4 59                  <1> 	pop	ecx
   332 000013F5 5A                  <1> 	pop	edx
   333 000013F6 1F                  <1> 	pop	ds
   334 000013F7 07                  <1> 	pop	es	; RECOVER SEGMENTS
   335 000013F8 CF                  <1> 	iret		; ALL DONE
   336                              <1> 
   337                              <1> ; 17/06/2016
   338                              <1> ; 29/05/2016
   339                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   340                              <1> set_txt_mode:
   341                              <1> 	;mov	dx, 03D4h 	; address of color card
   342 000013F9 B003                <1> 	mov	al, 3
   343                              <1> ;M8:
   344 000013FB A2[16CD0000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
   345 00001400 B029                <1> 	mov	al, 29h
   346                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
   347 00001402 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
   348                              <1> 	;push	dx  		; save port value
   349                              <1> 	;add	dx, 4		; point to control register
   350 00001404 66BAD803            <1> 	mov	dx, 3D8h
   351 00001408 EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
   352                              <1> 	;pop	dx
   353                              <1> ;M9:
   354 00001409 BB[18CD0000]        <1> 	mov	ebx, video_params ; initialization table
   355 0000140E 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
   356 00001412 86E0                <1> 	xchg 	ah, al
   357 00001414 66A3[38CD0000]      <1> 	mov	[CURSOR_MODE], ax ; save (reset) cursor mode
   358 0000141A 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
   359                              <1> 	
   360                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
   361 0000141C B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
   362                              <1> M10:			;  initialization loop
   363 00001421 88E0                <1> 	mov	al, ah 	; get 6845 register number
   364 00001423 EE                  <1> 	out	dx, al
   365 00001424 6642                <1> 	inc	dx      ; point to data port
   366 00001426 FEC4                <1> 	inc	ah	; next register value
   367 00001428 8A03                <1> 	mov	al, [ebx] ; get table value
   368 0000142A EE                  <1> 	out	dx, al	; out to chip
   369 0000142B 43                  <1> 	inc	ebx	; next in table
   370 0000142C 664A                <1> 	dec	dx	; back to pointer register
   371 0000142E E2F1                <1> 	loop	M10	; do the whole table
   372                              <1> 
   373                              <1> 	; 29/05/2016
   374                              <1> 	; TRDOS 386 (INT 31h) VIDEO interrupt will reset
   375                              <1> 	; ACTIVE PAGE to 0 and then video page 0 will be cleared.
   376                              <1> 	; But, if 'set_txt_mode' will be called by 'write_tty'
   377                              <1> 	; ('set_mode_3'), active video page will not be reset and
   378                              <1> 	; also it will not be cleared.
   379                              <1> 	;  
   380 00001430 380D[3BE00000]      <1> 	cmp	byte [set_mode_clear], cl ; 0
   381 00001436 761F                <1> 	jna	short _M11
   382                              <1> 	;
   383                              <1> ;-----	FILL REGEN AREA WITH BLANK
   384 00001438 6631C0              <1> 	xor	ax, ax  
   385 0000143B 66A3[D4D20000]      <1> 	mov	[CRT_START], ax  ; start address saved in global
   386 00001441 A2[E6D20000]        <1> 	mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
   387 00001446 B900200000          <1> 	mov	ecx, 8192 ; number of words in color card
   388                              <1> 	; black background, light gray characeter color, space character
   389 0000144B 66B82007            <1> 	mov	ax, 0720h ; fill char for alpha - attribute
   390                              <1> ;M13:			  ; clear buffer
   391 0000144F BF00800B00          <1> 	mov	edi, 0B8000h ; [crt_base]
   392 00001454 F366AB              <1> 	rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   393                              <1> _M11:
   394                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
   395                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
   396                              <1> 			 ; prepare to output to video enable port
   397                              <1> 	;add	dx,4	 ; point to the mode control gerister
   398 00001457 66BAD803            <1> 	mov	dx, 3D8h
   399                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
   400 0000145B B029                <1> 	mov	al, 29h
   401 0000145D EE                  <1> 	out	dx, al	 ; set video enable port
   402                              <1> 
   403                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
   404                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
   405                              <1> 	;
   406                              <1> 	;mov	byte [CRT_COLS], 80h ; initialize number of columns count
   407                              <1> 	;
   408                              <1> ;-----	SET CURSOR POSITIONS
   409                              <1> 	;mov	word [CRT_LEN], 80*25*2
   410 0000145E BF[D6D20000]        <1> 	mov	edi, CURSOR_POSN
   411 00001463 B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
   412 00001468 31C0                <1> 	xor	eax, eax
   413 0000146A F3AB                <1> 	rep 	stosd	; fill with zeroes
   414                              <1> 
   415                              <1> ;-----	SET UP OVERSCAN REGISTER
   416 0000146C 6642                <1> 	inc	dx	; set overscan port to a default
   417 0000146E B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
   418                              <1> ;M14:
   419 00001470 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
   420                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
   421                              <1> 
   422                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   423 00001471 C3                  <1> 	retn
   424                              <1> 
   425                              <1> SET_CTYPE:
   426                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   427 00001472 E805000000          <1> 	call	_set_ctype
   428 00001477 E96FFFFFFF          <1>         jmp     VIDEO_RETURN
   429                              <1> 
   430                              <1> _set_ctype:
   431                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
   432                              <1> 	;
   433                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   434                              <1> 
   435                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
   436                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
   437                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
   438                              <1> 	;     OR NO CURSOR AT ALL
   439                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
   440                              <1> 
   441                              <1> ;------------------------------------------------
   442                              <1> ; SET_CTYPE
   443                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
   444                              <1> ; INPUT
   445                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
   446                              <1> ; OUTPUT	
   447                              <1> ;	NONE
   448                              <1> ;------------------------------------------------
   449                              <1> 
   450 0000147C B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
   451 0000147E 66890D[38CD0000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
   452                              <1> 	;call	m16	; output cx register
   453                              <1> 	;retn
   454 00001485 E92E030000          <1>         jmp     m16
   455                              <1> 
   456                              <1> SET_CPOS:
   457                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   458 0000148A E8FE020000          <1> 	call	_set_cpos
   459 0000148F E957FFFFFF          <1>         jmp     VIDEO_RETURN
   460                              <1> 
   461                              <1> READ_CURSOR:
   462                              <1> 	; 12/05/2016
   463                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   464                              <1> 	;
   465                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   466                              <1> 
   467                              <1> ;------------------------------------------------------
   468                              <1> ; READ_CURSOR
   469                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
   470                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
   471                              <1> ; INPUT
   472                              <1> ;	BH - PAGE OF CURSOR
   473                              <1> ; OUTPUT
   474                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
   475                              <1> ;	CX - CURRENT CURSOR MODE
   476                              <1> ;------------------------------------------------------
   477                              <1> 
   478                              <1> 	; BH = Video page number (0 to 7)
   479                              <1> 	
   480 00001494 E815000000          <1> 	call	get_cpos
   481 00001499 0FB70D[38CD0000]    <1> 	movzx	ecx, word [CURSOR_MODE]
   482                              <1> 
   483 000014A0 5D                  <1> 	pop	ebp
   484 000014A1 5F                  <1> 	pop	edi
   485 000014A2 5E                  <1> 	pop	esi
   486 000014A3 5B                  <1> 	pop	ebx
   487 000014A4 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
   488 000014A5 58                  <1> 	pop	eax
   489 000014A6 A1[34E00000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   490 000014AB 1F                  <1> 	pop	ds
   491 000014AC 07                  <1> 	pop	es
   492 000014AD CF                  <1> 	iret
   493                              <1> 
   494                              <1> get_cpos:
   495                              <1> 	; 12/05/2016
   496                              <1> 	; 16/01/2016
   497                              <1> 	; BH = Video page number (0 to 7)
   498                              <1> 	;
   499 000014AE D0E7                <1> 	shl	bh, 1 ; WORD OFFSET
   500 000014B0 0FB6F7              <1> 	movzx	esi, bh 
   501 000014B3 0FB796[D6D20000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
   502 000014BA C3                  <1> 	retn
   503                              <1> 
   504                              <1> ACT_DISP_PAGE:
   505                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   506                              <1> 	;
   507                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   508                              <1> 	;
   509                              <1> ;-----------------------------------------------------
   510                              <1> ; ACT_DISP_PAGE
   511                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
   512                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
   513                              <1> ; INPUT
   514                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
   515                              <1> ; OUTPUT
   516                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
   517                              <1> ;-----------------------------------------------------
   518                              <1> 
   519 000014BB E805000000          <1> 	call	set_active_page
   520 000014C0 E926FFFFFF          <1>         jmp     VIDEO_RETURN
   521                              <1> 
   522                              <1> set_active_page:   ; tty_sw
   523                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   524                              <1> 	; 30/06/2015
   525                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
   526                              <1> 	; 10/12/2013
   527                              <1> 	; 04/12/2013
   528                              <1> 	;
   529 000014C5 A2[E6D20000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
   530                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
   531 000014CA 66B9A00F            <1> 	mov	cx, 25*80*2
   532                              <1> 	; 27/06/2015
   533 000014CE 0FB6D8              <1> 	movzx	ebx, al
   534                              <1> 	;
   535 000014D1 6698                <1> 	cbw	; 07/09/2014 (ah=0)
   536 000014D3 66F7E1              <1> 	mul 	cx	; display page times regen length
   537                              <1> 	; 10/12/2013
   538 000014D6 66A3[D4D20000]      <1> 	mov	[CRT_START], ax ; save start address for later
   539 000014DC 6689C1              <1> 	mov	cx, ax ; start address to cx
   540                              <1> 	;sar	cx, 1
   541 000014DF 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
   542 000014E2 B40C                <1> 	mov	ah, 12	; 6845 register for start address
   543 000014E4 E8CF020000          <1> 	call	m16
   544                              <1> 	;sal	bx, 1
   545                              <1> 	; 01/09/2014
   546 000014E9 D0E3                <1> 	shl	bl, 1	; *2 for word offset
   547 000014EB 81C3[D6D20000]      <1> 	add	ebx, CURSOR_POSN
   548 000014F1 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
   549                              <1> 	; 16/01/2016
   550                              <1> 	;call	m18
   551                              <1> 	;retn
   552 000014F4 E9AB020000          <1> 	jmp	m18
   553                              <1> 
   554                              <1> position:
   555                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   556                              <1> 	; 27/06/2015
   557                              <1> 	; 02/09/2014
   558                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   559                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
   560                              <1> 	;
   561                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   562                              <1> 	;
   563                              <1> ;-----------------------------------------
   564                              <1> ; POSITION
   565                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
   566                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
   567                              <1> ; INPUT
   568                              <1> ;	AX = ROW, COLUMN POSITION
   569                              <1> ; OUTPUT
   570                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
   571                              <1> ;-----------------------------------------
   572                              <1> 
   573                              <1> 	; DX = ROW, COLUMN POSITION
   574                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
   575 000014F9 31C0                <1> 	xor	eax, eax ; 02/09/2014
   576 000014FB B050                <1> 	mov	al, 80   ; determine bytes to row	
   577 000014FD F6E6                <1> 	mul	dh	 ; row value
   578 000014FF 30F6                <1> 	xor	dh, dh   ; 0	
   579 00001501 6601D0              <1> 	add	ax, dx	 ; add column value to the result
   580 00001504 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
   581                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
   582 00001507 C3                  <1> 	retn
   583                              <1> 
   584                              <1> find_position:
   585                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   586                              <1> 	; 27/06/2015
   587                              <1> 	; 07/09/2014
   588                              <1> 	; 02/09/2014
   589                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   590                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   591 00001508 0FB6CF              <1> 	movzx	ecx, bh ; video page number
   592 0000150B 89CE                <1> 	mov	esi, ecx
   593 0000150D 66D1E6              <1> 	shl	si, 1
   594 00001510 668B96[D6D20000]    <1> 	mov	dx, [esi + CURSOR_POSN]
   595 00001517 740A                <1> 	jz	short p21
   596 00001519 6631F6              <1> 	xor	si, si
   597                              <1> p20:
   598                              <1> 	;add	si, [CRT_LEN]
   599 0000151C 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
   600 00001521 E2F9                <1> 	loop	p20
   601                              <1> p21:
   602 00001523 6621D2              <1> 	and	dx, dx
   603 00001526 7407                <1> 	jz	short p22
   604 00001528 E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
   605 0000152D 01C6                <1> 	add	esi, eax ; add location to start of regen page
   606                              <1> p22:	
   607                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
   608                              <1> 	;mov	dx, 03D4h ; I/O address of color card
   609                              <1> 	;add	dx, 6	; point at status port
   610 0000152F 66BADA03            <1> 	mov	dx, 03DAh ; status port
   611                              <1> 	; cx = 0
   612 00001533 C3                  <1> 	retn
   613                              <1> 
   614                              <1> SCROLL_UP:
   615                              <1> 	; 12/05/2016
   616                              <1> 	; 30/01/2016
   617                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   618                              <1> 	; 07/09/2014
   619                              <1> 	; 02/09/2014
   620                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
   621                              <1> 	; 04/04/2014
   622                              <1> 	; 04/12/2013
   623                              <1> 	;
   624                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   625                              <1> 	;
   626                              <1> ;----------------------------------------------
   627                              <1> ; SCROLL UP
   628                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
   629                              <1> ;	ON THE SCREEN
   630                              <1> ; INPUT
   631                              <1> ;	(AH) = CURRENT CRT MODE
   632                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
   633                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
   634                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
   635                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
   636                              <1> ;	(DS) = DATA SEGMENT
   637                              <1> ;	(ES) = REGEN BUFFER SEGMENT
   638                              <1> ; OUTPUT
   639                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
   640                              <1> ;--------------------------------------------
   641                              <1> 
   642 00001534 E805000000          <1> 	call	_scroll_up
   643 00001539 E9ADFEFFFF          <1>         jmp     VIDEO_RETURN
   644                              <1> 
   645                              <1> _scroll_up:  ; from 'write_tty'
   646                              <1> 	;
   647                              <1> 	; cl = left upper column
   648                              <1> 	; ch = left upper row
   649                              <1> 	; dl = right lower column
   650                              <1> 	; dh = right lower row
   651                              <1> 	;
   652                              <1> 	; al = line count 
   653                              <1> 	; bl = attribute to be used on blanked line	
   654                              <1> 	; bh = video page number (0 to 7)
   655                              <1> 
   656 0000153E E870000000          <1> 	call	test_line_count ; 16/01/2016
   657                              <1> 
   658                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
   659                              <1> 	;cmp	ah, 4
   660                              <1>  	;jb	short n1
   661                              <1> 
   662                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
   663                              <1> 	;jne	GRAPHICS_UP
   664                              <1> n1:
   665 00001543 88DC                <1> 	mov	ah, bl ; attribute
   666 00001545 6650                <1> 	push	ax ; *
   667                              <1> 	;mov 	esi, [CRT_BASE]
   668 00001547 BE00800B00          <1>         mov     esi, 0B8000h  
   669 0000154C 3A3D[E6D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
   670 00001552 750B                <1> 	jne	short n2
   671                              <1> 	;
   672 00001554 66A1[D4D20000]      <1>         mov     ax, [CRT_START]
   673 0000155A 6601C6              <1>         add     si, ax
   674 0000155D EB0F                <1>         jmp     short n4
   675                              <1> n2:
   676 0000155F 20FF                <1>         and     bh, bh
   677 00001561 740B                <1> 	jz	short n4
   678 00001563 88F8                <1> 	mov	al, bh
   679                              <1> n3:
   680                              <1>         ;add    si, [CRT_LEN]
   681                              <1>         ;add    esi, 80*25*2 
   682 00001565 6681C6A00F          <1>         add     si, 80*25*2
   683 0000156A FEC8                <1>         dec	al
   684 0000156C 75F7                <1> 	jnz	short n3
   685                              <1> n4:	
   686 0000156E E853000000          <1> 	call	scroll_position ; 16/01/2016
   687 00001573 741D                <1>         jz      short n6 
   688                              <1> 
   689 00001575 01CE                <1>         add     esi, ecx ; from address for scroll
   690 00001577 88F5                <1> 	mov	ch, dh  ; #rows in block
   691 00001579 28C5                <1> 	sub	ch, al	; #rows to be moved
   692                              <1> n5:
   693 0000157B E886000000          <1> 	call	n10 ; 16/01/2016
   694                              <1> 	
   695                              <1>         ;push	ecx
   696                              <1> 	;mov	cl, [CRT_COLS] 
   697                              <1> 	;add	cl, cl
   698                              <1>         ;mov	ecx, 80*2
   699                              <1> 	;add	esi, ecx  ; next line
   700                              <1>         ;add	edi, ecx
   701                              <1> 	;pop	ecx
   702                              <1> 
   703 00001580 81C6A0000000        <1> 	add     esi, 80*2 ; next line
   704 00001586 81C7A0000000        <1> 	add     edi, 80*2
   705 0000158C FECD                <1> 	dec	ch	 ; count of lines to move
   706 0000158E 75EB                <1> 	jnz	short n5 ; row loop
   707                              <1> 	; ch = 0
   708 00001590 88C6                <1> 	mov	dh, al	 ; #rows	
   709                              <1> n6:
   710                              <1> 	; attribute in ah
   711 00001592 B020                <1> 	mov	al, ' '	 ; fill with blanks
   712                              <1> n7:
   713 00001594 E87A000000          <1> 	call	n11 ; 16/01/2016
   714                              <1> 
   715                              <1> 	;push	ecx
   716                              <1> 	;mov	cl, [CRT_COLS]
   717                              <1> 	;add	cl, cl
   718                              <1>         ;mov	ecx, 80*2
   719                              <1>  	;add	edi, ecx
   720                              <1> 	;pop	ecx
   721                              <1> 
   722 00001599 81C7A0000000        <1> 	add     edi, 80*2
   723 0000159F FECE                <1> 	dec	dh
   724 000015A1 75F1                <1> 	jnz	short n7
   725                              <1> 	;
   726 000015A3 3A3D[E6D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
   727 000015A9 7507                <1> 	jne	short n8
   728                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   729 000015AB B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   730 000015AD 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   731 000015B1 EE                  <1> 	out	dx, al
   732                              <1> n8:
   733 000015B2 C3                  <1> 	retn
   734                              <1> 
   735                              <1> 
   736                              <1> test_line_count:
   737                              <1> 	; 12/05/2016
   738                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   739                              <1> 	; 07/09/2014 (scroll_up)
   740 000015B3 08C0                <1> 	or	al, al
   741 000015B5 740E                <1> 	jz	short al_set2
   742 000015B7 6652                <1> 	push	dx
   743 000015B9 28EE                <1> 	sub	dh, ch  ; subtract upper row from lower row number
   744 000015BB FEC6                <1> 	inc	dh	; adjust difference by 1
   745 000015BD 38C6                <1> 	cmp	dh, al 	; line count = amount of rows in window?
   746 000015BF 7502                <1> 	jne	short al_set1 ; if not the we're all set
   747 000015C1 30C0                <1> 	xor	al, al	; otherwise set al to zero
   748                              <1> al_set1:
   749 000015C3 665A                <1> 	pop	dx
   750                              <1> al_set2:
   751 000015C5 C3                  <1> 	retn
   752                              <1> 
   753                              <1> scroll_position:
   754                              <1> 	; 30/01/2016
   755                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   756                              <1> 	; 07/09/2014 (scroll_up)
   757                              <1> 
   758 000015C6 6652                <1> 	push	dx
   759 000015C8 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
   760 000015CB E829FFFFFF          <1> 	call	position
   761 000015D0 01C6                <1> 	add	esi, eax
   762 000015D2 89F7                <1> 	mov	edi, esi
   763 000015D4 665A                <1> 	pop	dx	; lower right position in DX
   764 000015D6 6629CA              <1> 	sub	dx, cx
   765 000015D9 FEC6                <1> 	inc	dh	; dh = #rows 
   766 000015DB FEC2                <1> 	inc	dl	; dl = #cols in block
   767 000015DD 59                  <1> 	pop	ecx 	; return address
   768 000015DE 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
   769 000015E0 51                  <1> 	push	ecx	; return address
   770 000015E1 0FB7C8              <1> 	movzx	ecx, ax
   771                              <1> 	;mov	ah, [CRT_COLS]
   772 000015E4 B450                <1> 	mov	ah, 80
   773 000015E6 F6E4                <1> 	mul	ah	; determine offset to from address
   774 000015E8 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
   775                              <1> 	;
   776 000015EB 6650                <1> 	push	ax	; offset 
   777 000015ED 6652                <1> 	push	dx
   778                              <1> 	;
   779                              <1> 	; 04/04/2014
   780 000015EF 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
   781                              <1> n9:                      ; wait_display_enable
   782 000015F3 EC                  <1>         in      al, dx   ; get port
   783 000015F4 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
   784 000015F6 74FB                <1> 	jz	short n9 ; wait_display_enable
   785 000015F8 B025                <1> 	mov	al, 25h
   786 000015FA B2D8                <1> 	mov	dl, 0D8h ; address control port
   787 000015FC EE                  <1> 	out	dx, al	; turn off video during vertical retrace
   788 000015FD 665A                <1> 	pop	dx	; #rows, #cols
   789 000015FF 6658                <1>        	pop	ax	; offset
   790 00001601 6691                <1> 	xchg	ax, cx	; 
   791                              <1> 	; ecx = offset, al = line count, ah = attribute
   792                              <1> 	;
   793 00001603 08C0                <1> 	or	al, al
   794 00001605 C3                  <1> 	retn
   795                              <1> n10:
   796                              <1> 	; Move rows
   797 00001606 88D1                <1> 	mov	cl, dl	; get # of cols to move
   798 00001608 56                  <1> 	push	esi
   799 00001609 57                  <1> 	push	edi	; save start address
   800                              <1> n10r:
   801 0000160A 66A5                <1> 	movsw		; move that line on screen
   802 0000160C FEC9                <1> 	dec	cl
   803 0000160E 75FA                <1>         jnz     short n10r
   804 00001610 5F                  <1> 	pop	edi
   805 00001611 5E                  <1> 	pop	esi	; recover addresses
   806 00001612 C3                  <1> 	retn
   807                              <1> n11:
   808                              <1> 	; Clear rows
   809                              <1>                 	; dh =  #rows
   810 00001613 88D1                <1>         mov	cl, dl	; get # of cols to clear
   811 00001615 57                  <1>         push    edi     ; save address
   812                              <1> n11r:
   813 00001616 66AB                <1>         stosw           ; store fill character
   814 00001618 FEC9                <1> 	dec	cl
   815 0000161A 75FA                <1>         jnz     short n11r
   816 0000161C 5F                  <1>         pop     edi     ; recover address
   817 0000161D C3                  <1> 	retn
   818                              <1> 
   819                              <1> SCROLL_DOWN:
   820                              <1> 	; 12/05/2016
   821                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   822                              <1> 	;
   823                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   824                              <1> 
   825                              <1> ;------------------------------------------
   826                              <1> ; SCROLL DOWN
   827                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
   828                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
   829                              <1> ;	WITH A DEFINED CHARACTER
   830                              <1> ; INPUT
   831                              <1> ;	(AH) = CURRENT CRT MODE
   832                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
   833                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
   834                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
   835                              <1> ;	(BH) = FILL CHARACTER
   836                              <1> ;	(DS) = DATA SEGMENT
   837                              <1> ;	(ES) = REGEN SEGMENT
   838                              <1> ; OUTPUT
   839                              <1> ;	NONE -- SCREEN IS SCROLLED
   840                              <1> ;------------------------------------------
   841                              <1> 
   842                              <1> 	; cl = left upper column
   843                              <1> 	; ch = left upper row
   844                              <1> 	; dl = right lower column
   845                              <1> 	; dh = right lower row
   846                              <1> 	;
   847                              <1> 	; al = line count 
   848                              <1> 	; bl = attribute to be used on blanked line	
   849                              <1> 	; bh = video page number (0 to 7)
   850                              <1> 
   851                              <1> 	; !!!!
   852 0000161E FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
   853                              <1> 	; !!!!
   854 0000161F E88FFFFFFF          <1> 	call	test_line_count ; 16/01/2016
   855                              <1> 	
   856                              <1> 	;mov	ah, [CRT_MODE] ; current video mode
   857                              <1> 	;cmp	ah, 4
   858                              <1>  	;jb	short n12
   859                              <1> 
   860                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
   861                              <1> 	;jne	GRAPHICS_DOWN
   862                              <1> 
   863                              <1> n12:			; CONTINUE_DOWN
   864 00001624 88DC                <1> 	mov	ah, bl
   865 00001626 6650                <1> 	push	ax	; * ; save attribute in ah
   866 00001628 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
   867 0000162B E896FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
   868 00001630 741D                <1> 	jz	short n14
   869 00001632 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
   870 00001634 88F5                <1> 	mov	ch, dh  ; #rows in block
   871 00001636 28C5                <1> 	sub	ch, al	; #rows to be moved
   872                              <1> n13:
   873 00001638 E8C9FFFFFF          <1> 	call	n10	; MOVE ONE ROW
   874                              <1> 
   875                              <1> 	;push	ecx
   876                              <1> 	;mov	cl, [CRT_COLS] 
   877                              <1> 	;add	cl, cl
   878                              <1>         ;mov	ecx, 80*2
   879                              <1> 	;sub	esi, ecx  ; next line
   880                              <1>         ;sub	edi, ecx
   881                              <1>         ;pop	ecx
   882                              <1> 	
   883 0000163D 81EEA0000000        <1> 	sub     esi, 80*2  ; next line
   884 00001643 81EFA0000000        <1>         sub     edi, 80*2
   885 00001649 FECD                <1> 	dec	ch	 ; count of lines to move
   886 0000164B 75EB                <1> 	jnz	short n13 ; row loop
   887                              <1> 	; ch = 0
   888 0000164D 88C6                <1> 	mov	dh, al	 ; #rows
   889                              <1> n14:
   890                              <1> 	; attribute in ah
   891 0000164F B020                <1> 	mov	al, ' '	 ; fill with blanks
   892                              <1> n15:
   893 00001651 E8BDFFFFFF          <1> 	call	n11 ; 16/01/2016
   894                              <1> 
   895                              <1> 	;push	ecx
   896                              <1> 	;mov	cl, [CRT_COLS]
   897                              <1> 	;add	cl, cl
   898                              <1>         ;mov	ecx, 80*2
   899                              <1> 	;sub	edi, ecx
   900                              <1>         ;pop	ecx
   901                              <1> 
   902 00001656 81EFA0000000        <1> 	sub	edi, 80*2
   903 0000165C FECE                <1> 	dec	dh
   904 0000165E 75F1                <1> 	jnz	short n15
   905                              <1> 	;
   906 00001660 3A3D[E6D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
   907 00001666 7507                <1> 	jne	short n16
   908                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   909 00001668 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   910 0000166A 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   911 0000166E EE                  <1> 	out	dx, al
   912                              <1> n16:
   913                              <1> 	; !!!!
   914 0000166F FC                  <1> 	cld		; Clear direction flag !
   915                              <1> 	; !!!!
   916 00001670 C3                  <1> 	retn
   917                              <1> 
   918                              <1> READ_AC_CURRENT:
   919                              <1> 	; 12/05/2016
   920                              <1> 	; 18/01/2016
   921                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   922                              <1> 	;
   923                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   924                              <1> 	;
   925                              <1> 
   926 00001671 E805000000          <1> 	call	_read_ac_current
   927                              <1> 	; 12/05/2016
   928                              <1>         ;jmp     VIDEO_RETURN
   929 00001676 E975FDFFFF          <1> 	jmp	_video_return
   930                              <1> 
   931                              <1> ;------------------------------------------------------------------------
   932                              <1> ; READ_AC_CURRENT							:
   933                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
   934                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
   935                              <1> ; INPUT									:
   936                              <1> ;	(AH) = CURRENT CRT MODE						:
   937                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
   938                              <1> ;	(DS) = DATA SEGMENT						:
   939                              <1> ;	(ES) = REGEN SEGMENT						:
   940                              <1> ; OUTPUT								:
   941                              <1> ;	(AL) = CHARACTER READ						:
   942                              <1> ;	(AH) = ATTRIBUTE READ						:
   943                              <1> ;------------------------------------------------------------------------
   944                              <1> 
   945                              <1> _read_ac_current:
   946                              <1> 	; 12/05/2016 
   947                              <1> 	; 18/01/2016
   948                              <1> p10:
   949 0000167B E888FEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
   950                              <1> 	;
   951                              <1> 	; esi = regen location
   952                              <1> 	; dx = status port
   953                              <1> 	;
   954                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
   955                              <1> 	;
   956                              <1> p11:			; wait for horizontal retrace is low or vertical
   957 00001680 FB                  <1> 	sti		; enable interrupts first
   958 00001681 3A3D[E6D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
   959 00001687 750C                <1> 	jne	short p14 
   960 00001689 FA                  <1> 	cli 		; block interrupts for single loop
   961 0000168A EC                  <1> 	in	al, dx	; get status from the adapter
   962 0000168B A801                <1> 	test	al, RHRZ ; is horizontal retrace low
   963 0000168D 75F1                <1> 	jnz	short p11 ; wait until it is
   964                              <1> p12:			;  wait for either retrace high
   965 0000168F EC                  <1> 	in	al, dx ; get status again
   966 00001690 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
   967 00001692 74FB                <1> 	jz	short p12 ; wait until either retrace active
   968 00001694 FB                  <1> 	sti
   969                              <1> p14:
   970 00001695 81C600800B00        <1> 	add	esi, 0B8000h 
   971 0000169B 668B06              <1> 	mov	ax, [esi]
   972                              <1> 
   973 0000169E C3                  <1> 	retn	; 18/01/2016
   974                              <1> 
   975                              <1> WRITE_AC_CURRENT:
   976                              <1> 	; 12/05/2016
   977                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   978                              <1> 	;
   979                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   980                              <1> 	;
   981                              <1> ;----------------------------------------------------------------
   982                              <1> ; WRITE_AC_CURRENT						:
   983                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
   984                              <1> ;	AT THE CURRENT CURSOR POSITION				:
   985                              <1> ; INPUT								:
   986                              <1> ;	(AH) = CURRENT CRT MODE					:
   987                              <1> ;	(BH) = DISPLAY PAGE					:
   988                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   989                              <1> ;	(AL) = CHAR TO WRITE					:
   990                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
   991                              <1> ;	(DS) = DATA SEGMENT					:
   992                              <1> ;	(ES) = REGEN SEGMENT					:
   993                              <1> ; OUTPUT							:
   994                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   995                              <1> ;----------------------------------------------------------------
   996                              <1> 
   997 0000169F E821000000          <1> 	call	_write_c_current
   998                              <1> 
   999 000016A4 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
  1000 000016A7 889E[28CD0000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  1001                              <1> 
  1002 000016AD E939FDFFFF          <1>         jmp     VIDEO_RETURN
  1003                              <1> 
  1004                              <1> WRITE_C_CURRENT:
  1005                              <1> 	; 12/05/2016
  1006                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1007                              <1> 	;
  1008                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1009                              <1> 	;
  1010                              <1> 
  1011                              <1> 	;and	bh, 7 ; video page number (<= 7)
  1012 000016B2 0FB6F7              <1> 	movzx	esi, bh	
  1013 000016B5 8A9E[28CD0000]      <1> 	mov	bl, [esi+chr_attrib]
  1014                              <1> 
  1015 000016BB E805000000          <1> 	call	_write_c_current
  1016 000016C0 E926FDFFFF          <1>         jmp     VIDEO_RETURN
  1017                              <1> 
  1018                              <1> ;----------------------------------------------------------------
  1019                              <1> ; WRITE_C_CURRENT						:
  1020                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
  1021                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
  1022                              <1> ; INPUT								:
  1023                              <1> ;	(AH) = CURRENT CRT MODE					:
  1024                              <1> ;	(BH) = DISPLAY PAGE					:
  1025                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  1026                              <1> ;	(AL) = CHAR TO WRITE					:
  1027                              <1> ;	(DS) = DATA SEGMENT					:
  1028                              <1> ;	(ES) = REGEN SEGMENT					:
  1029                              <1> ; OUTPUT							:
  1030                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  1031                              <1> ;----------------------------------------------------------------
  1032                              <1> 
  1033                              <1> _write_c_current:  ; from 'write_tty'
  1034                              <1> 	; 12/05/2016
  1035                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1036                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1037                              <1> 	; 18/01/2014
  1038                              <1> 	; 04/12/2013
  1039                              <1> 	;
  1040                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1041                              <1> 	;
  1042                              <1> 
  1043 000016C5 FA                  <1> 	cli		
  1044                              <1> 	; al = character
  1045                              <1> 	; bl = color/attribute
  1046                              <1> 	; bh = video page
  1047 000016C6 6652                <1> 	push	dx
  1048 000016C8 88DC                <1> 	mov	ah, bl ; color/attribute (12/05/2016)
  1049 000016CA 6650                <1> 	push	ax	; save character & attribute/color
  1050 000016CC E837FEFFFF          <1> 	call 	find_position  ; get regen location and port address
  1051                              <1> 	; esi = regen location
  1052                              <1> 	; dx = status port
  1053                              <1> 	;
  1054                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
  1055                              <1> 	;
  1056                              <1> p41:			; wait for horizontal retrace is low or vertical
  1057 000016D1 FB                  <1> 	sti		; enable interrupts first
  1058 000016D2 3A3D[E6D20000]      <1>         cmp     bh, [ACTIVE_PAGE]
  1059 000016D8 7510                <1> 	jne	short p44 
  1060 000016DA FA                  <1> 	cli 		; block interrupts for single loop
  1061 000016DB EC                  <1> 	in	al, dx	; get status from the adapter
  1062 000016DC A808                <1> 	test	al, RVRT ; check for vertical retrace first
  1063 000016DE 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  1064 000016E0 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1065 000016E2 75ED                <1> 	jnz	short p41 ; wait until it is
  1066                              <1> p42:			;  wait for either retrace high
  1067 000016E4 EC                  <1> 	in	al, dx ; get status again
  1068 000016E5 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1069 000016E7 74FB                <1> 	jz	short p42 ; wait until either retrace active
  1070                              <1> p43:	
  1071 000016E9 FB                  <1> 	sti
  1072                              <1> p44:
  1073 000016EA 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  1074 000016EC 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  1075                              <1> 				; Retro UNIX 386 v1 feature only!
  1076 000016F2 668906              <1> 	mov	[esi], ax
  1077 000016F5 665A                <1> 	pop	dx
  1078 000016F7 C3                  <1> 	retn
  1079                              <1> 
  1080                              <1> ; 12/05/2016
  1081                              <1> ; 18/01/2016
  1082                              <1> ; 16/01/2016 - TRDOS 386 (TRDOS v2.0)
  1083                              <1> ; 30/06/2015
  1084                              <1> ; 27/06/2015
  1085                              <1> ; 11/03/2015
  1086                              <1> ; 02/09/2014
  1087                              <1> ; 30/08/2014
  1088                              <1> ; VIDEO FUNCTIONS
  1089                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1090                              <1> 
  1091                              <1> WRITE_TTY:
  1092                              <1> 	; 13/05/2016
  1093                              <1> 	; 12/05/2016
  1094                              <1> 	; 30/01/2016
  1095                              <1> 	; 18/01/2016
  1096                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1097                              <1> 	; 13/08/2015
  1098                              <1> 	; 02/09/2014
  1099                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1100                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1101                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1102                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1103                              <1> 	;
  1104                              <1> 	; INPUT -> AL = Character to be written
  1105                              <1> 	;	   BL = Color (Forecolor, Backcolor)
  1106                              <1> 	;	   BH = Video Page (0 to 7)
  1107                              <1> 
  1108                              <1> 	; 13/05/2016
  1109 000016F8 E805000000          <1> 	call	_write_tty
  1110 000016FD E9E9FCFFFF          <1> 	jmp	VIDEO_RETURN
  1111                              <1> 
  1112                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1113                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1114                              <1> 
  1115                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1116                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1117                              <1> ;
  1118                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1119                              <1> ;
  1120                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1121                              <1> ;										:
  1122                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1123                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1124                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1125                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1126                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1127                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1128                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1129                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1130                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1131                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1132                              <1> ;   THE 0 COLOR IS USED.							:
  1133                              <1> ;   ENTRY --									:
  1134                              <1> ;     (AH) = CURRENT CRT MODE							:
  1135                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1136                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1137                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1138                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1139                              <1> ;   EXIT -- 									:
  1140                              <1> ;     ALL REGISTERS SAVED							:
  1141                              <1> ;--------------------------------------------------------------------------------
  1142                              <1> 
  1143                              <1> _write_tty:	; 13/05/2016
  1144                              <1> 
  1145 00001702 FA                  <1> 	cli
  1146                              <1> 	;
  1147                              <1> 	; 01/09/2014
  1148 00001703 803D[16CD0000]03    <1> 	cmp	byte [CRT_MODE], 3
  1149 0000170A 7405                <1> 	je	short m3
  1150                              <1> 	;
  1151 0000170C E8A6FCFFFF          <1> 	call	set_mode_3 ; 16/01/2016
  1152                              <1> m3:
  1153 00001711 0FB6F7              <1> 	movzx 	esi, bh ; 12/05/2016
  1154 00001714 66D1E6              <1> 	shl	si, 1
  1155 00001717 81C6[D6D20000]      <1> 	add	esi, CURSOR_POSN
  1156 0000171D 668B16              <1> 	mov	dx, [esi]
  1157                              <1> 	;
  1158                              <1> 	; dx now has the current cursor position
  1159                              <1> 	;
  1160 00001720 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  1161 00001722 762F                <1> 	jbe	short u8
  1162                              <1> 	;
  1163                              <1> 	; write the char to the screen
  1164                              <1> u0:	
  1165                              <1> 	; al = character
  1166                              <1> 	; bl = attribute/color
  1167                              <1> 	; bh = video page number (0 to 7)
  1168                              <1> 	;
  1169 00001724 E89CFFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  1170                              <1> 	;
  1171                              <1> 	; position the cursor for next char
  1172 00001729 FEC2                <1> 	inc	dl		; next column
  1173                              <1> 	;cmp	dl, [CRT_COLS]
  1174 0000172B 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  1175 0000172E 755D                <1>         jne     _set_cpos
  1176 00001730 B200                <1> 	mov	dl, 0		; column = 0
  1177                              <1> u10:				; (line feed found)
  1178 00001732 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1179 00001735 7218                <1> 	jb 	short u6
  1180                              <1> 	;
  1181                              <1> 	; scroll required
  1182                              <1> u1:	
  1183                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1184 00001737 E851000000          <1> 	call	_set_cpos
  1185                              <1> 	;
  1186                              <1> 	; determine value to fill with during scroll
  1187                              <1> u2:
  1188                              <1> 	; bh = video page number
  1189                              <1> 	;
  1190 0000173C E83AFFFFFF          <1> 	call _read_ac_current ; 18/01/2016
  1191                              <1> 	;
  1192                              <1> 	; al = character, ah = attribute
  1193                              <1> 	; bh = video page number 	
  1194                              <1> u3:
  1195                              <1> 	;;mov	ax, 0601h 	; scroll one line
  1196                              <1> 	;;sub	cx, cx		; upper left corner
  1197                              <1> 	;;mov	dh, 25-1 	; lower right row
  1198                              <1> 	;;;mov	dl, [CRT_COLS]
  1199                              <1> 	;mov	dl, 80		; lower right column	
  1200                              <1> 	;;dec	dl
  1201                              <1> 	;;mov	dl, 79
  1202                              <1> 
  1203                              <1> 	;;call	scroll_up	; 04/12/2013
  1204                              <1> 	;;; 11/03/2015
  1205                              <1> 	; 02/09/2014
  1206                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  1207                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  1208                              <1> 	; 11/03/2015
  1209 00001741 6629C9              <1> 	sub	cx, cx
  1210 00001744 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  1211                              <1> 	;
  1212 00001748 B001                <1> 	mov	al, 1		; scroll 1 line up
  1213                              <1> 		; ah = attribute
  1214                              <1> 	;mov	bl, al ; 12/05/2016
  1215 0000174A E9EFFDFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  1216                              <1> ;u4:
  1217                              <1> 	;;int	10h		; video-call return
  1218                              <1> 				; scroll up the screen
  1219                              <1> 				; tty return
  1220                              <1> ;u5:
  1221                              <1> 	;retn			; return to the caller
  1222                              <1> 
  1223                              <1> u6:				; set-cursor-inc
  1224 0000174F FEC6                <1> 	inc	dh		; next row
  1225                              <1> 				; set cursor
  1226                              <1> ;u7:					
  1227                              <1> 	;;mov	ah, 02h
  1228                              <1> 	;;jmp	short u4 	; establish the new cursor
  1229                              <1> 	;call	_set_cpos
  1230                              <1> 	;jmp 	short u5
  1231 00001751 EB3A                <1> 	jmp     _set_cpos
  1232                              <1> 
  1233                              <1> 	; check for control characters
  1234                              <1> u8:
  1235 00001753 7436                <1> 	je	short u9
  1236 00001755 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  1237 00001757 74D9                <1> 	je	short u10
  1238 00001759 3C07                <1> 	cmp	al, 07h 	; is it a bell
  1239 0000175B 747A                <1> 	je	short u11
  1240 0000175D 3C08                <1> 	cmp	al, 08h		; is it a backspace
  1241                              <1> 	;jne	short u0
  1242 0000175F 7422                <1> 	je	short bs	; 12/12/2013
  1243                              <1> 	; 12/12/2013 (tab stop)
  1244 00001761 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  1245 00001763 75BF                <1> 	jne	short u0
  1246 00001765 88D0                <1> 	mov	al, dl
  1247 00001767 6698                <1> 	cbw
  1248 00001769 B108                <1> 	mov	cl, 8
  1249 0000176B F6F1                <1> 	div	cl
  1250 0000176D 28E1                <1> 	sub	cl, ah
  1251                              <1> ts:
  1252                              <1> 	; 02/09/2014
  1253                              <1> 	; 01/09/2014
  1254 0000176F B020                <1> 	mov	al, 20h
  1255                              <1> tsloop:
  1256 00001771 6651                <1> 	push	cx
  1257 00001773 6650                <1> 	push	ax
  1258                              <1> 	;mov	bh, [ACTIVE_PAGE]
  1259 00001775 E897FFFFFF          <1> 	call	m3
  1260 0000177A 6658                <1> 	pop	ax  ; ah = attribute/color
  1261 0000177C 6659                <1> 	pop	cx
  1262 0000177E FEC9                <1> 	dec	cl
  1263 00001780 75EF                <1> 	jnz	short tsloop
  1264 00001782 C3                  <1> 	retn
  1265                              <1> bs:	
  1266                              <1> 	; back space found
  1267                              <1> 
  1268 00001783 08D2                <1> 	or	dl, dl 		; is it already at start of line
  1269                              <1> 	;je	short u7 	; set_cursor
  1270 00001785 7406                <1> 	jz	short _set_cpos
  1271 00001787 664A                <1> 	dec	dx     		; no -- just move it back
  1272                              <1> 	;jmp	short u7
  1273 00001789 EB02                <1> 	jmp	short _set_cpos
  1274                              <1> 
  1275                              <1> 	; carriage return found
  1276                              <1> u9:
  1277 0000178B B200                <1> 	mov	dl, 0 		; move to first column
  1278                              <1> 	;jmp	short u7
  1279                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  1280                              <1> 
  1281                              <1> 	; line feed found
  1282                              <1> ;u10:
  1283                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  1284                              <1> ;	jne	short u6 	; no, just set the cursor
  1285                              <1> ;       jmp     u1              ; yes, scroll the screen
  1286                              <1> 
  1287                              <1> _set_cpos:
  1288                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1289                              <1> 	; 27/06/2015
  1290                              <1> 	; 01/09/2014
  1291                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1292                              <1> 	;
  1293                              <1> 	; 04/12/2013 - 12/12/2013 (Retro UNIX 8086 v1) 
  1294                              <1> 	;
  1295                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1296                              <1> 	;
  1297                              <1> ;----------------------------------------------
  1298                              <1> ; SET_CPOS
  1299                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  1300                              <1> ;	NEW X-Y VALUES PASSED
  1301                              <1> ; INPUT
  1302                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  1303                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  1304                              <1> ; OUTPUT
  1305                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  1306                              <1> ;----------------------------------------------
  1307                              <1> 	;
  1308 0000178D BE[D6D20000]        <1> 	mov	esi, CURSOR_POSN
  1309 00001792 0FB6C7              <1>         movzx   eax, bh	; BH = video page number
  1310                              <1> ;	or	al, al
  1311                              <1> ;	jz	short _set_cpos_0
  1312 00001795 D0E0                <1>         shl     al, 1   ; word offset
  1313 00001797 01C6                <1>         add     esi, eax
  1314                              <1> ;_set_cpos_0:
  1315 00001799 668916              <1> 	mov	[esi], dx ; save the pointer
  1316 0000179C 383D[E6D20000]      <1> 	cmp	[ACTIVE_PAGE], bh
  1317 000017A2 7532                <1> 	jne	short m17
  1318                              <1> 	;call	m18	; CURSOR SET
  1319                              <1> ;m17:			; SET_CPOS_RETURN
  1320                              <1> 	; 01/09/2014
  1321                              <1> ;	retn
  1322                              <1> 		; DX  = row/column
  1323                              <1> m18:
  1324 000017A4 E850FDFFFF          <1> 	call	position ; determine location in regen buffer	
  1325 000017A9 668B0D[D4D20000]    <1> 	mov	cx, [CRT_START]
  1326 000017B0 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  1327                              <1> 			; to the start address (offset) for this page
  1328 000017B3 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  1329 000017B6 B40E                <1> 	mov	ah, 14	; register number for cursor
  1330                              <1> 	;call	m16	; output value to the 6845	
  1331                              <1> 	;retn
  1332                              <1> 
  1333                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  1334                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  1335                              <1> m16:
  1336 000017B8 FA                  <1> 	cli
  1337                              <1> 	;mov	dx, [addr_6845] ; address register
  1338 000017B9 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  1339 000017BD 88E0                <1> 	mov	al, ah	; get value
  1340 000017BF EE                  <1> 	out	dx, al	; register set
  1341 000017C0 6642                <1> 	inc	dx	; data register
  1342 000017C2 EB00                <1> 	jmp	$+2	; i/o delay
  1343 000017C4 88E8                <1> 	mov	al, ch	; data
  1344 000017C6 EE                  <1> 	out	dx, al	
  1345 000017C7 664A                <1> 	dec	dx	
  1346 000017C9 88E0                <1> 	mov	al, ah
  1347 000017CB FEC0                <1> 	inc	al	; point to other data register
  1348 000017CD EE                  <1> 	out	dx, al	; set for second register
  1349 000017CE 6642                <1> 	inc	dx
  1350 000017D0 EB00                <1> 	jmp	$+2	; i/o delay
  1351 000017D2 88C8                <1> 	mov	al, cl	; second data value
  1352 000017D4 EE                  <1> 	out	dx, al
  1353 000017D5 FB                  <1> 	sti
  1354                              <1> m17:
  1355 000017D6 C3                  <1> 	retn
  1356                              <1> 
  1357                              <1> beeper: 
  1358                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1359                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1360                              <1> 	; 18/01/2014
  1361                              <1> 	; 03/12/2013
  1362                              <1> 	; bell found
  1363                              <1> u11:
  1364 000017D7 FB                  <1> 	sti
  1365 000017D8 3A3D[E6D20000]      <1> 	cmp	bh, [ACTIVE_PAGE]
  1366 000017DE 7551                <1> 	jne	short u12	; Do not sound the beep 
  1367                              <1> 				; if it is not written on the active page
  1368 000017E0 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  1369 000017E4 B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  1370                              <1> 	;call	beep		; sound the pod bell
  1371                              <1> 	;jmp	short u5 	; tty_return
  1372                              <1> 	;retn
  1373                              <1> 	
  1374                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  1375                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  1376                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  1377                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  1378                              <1> 
  1379                              <1> beep:
  1380                              <1> 	; 07/02/2015
  1381                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1382                              <1> 	; 18/01/2014
  1383                              <1> 	; 03/12/2013
  1384                              <1> 	;
  1385                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  1386                              <1> 	;
  1387                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  1388                              <1> 	;
  1389                              <1> 	; ENTRY:
  1390                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  1391                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  1392                              <1> 	; EXIT:				:
  1393                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  1394                              <1> 
  1395 000017E6 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  1396 000017E7 FA                  <1> 	cli			; block interrupts during update
  1397 000017E8 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  1398 000017EA E643                <1> 	out	TIMER+3, al 	; write timer mode register
  1399 000017EC EB00                <1> 	jmp	$+2		; I/O delay
  1400 000017EE 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  1401 000017F0 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  1402 000017F2 EB00                <1> 	jmp	$+2		; I/O delay
  1403 000017F4 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  1404 000017F6 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  1405 000017F8 E461                <1> 	in	al, PORT_B	; get current setting of port
  1406 000017FA 88C4                <1> 	mov	ah, al		; save that setting
  1407 000017FC 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  1408 000017FE E661                <1> 	out	PORT_B, al	; and restore interrupt status
  1409                              <1> 	;popf	; 18/01/2014
  1410 00001800 FB                  <1> 	sti
  1411                              <1> g7:				; 1/64 second per count (bl)
  1412 00001801 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  1413 00001806 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  1414 0000180B FECB                <1> 	dec	bl		; (bl) length count expired?
  1415 0000180D 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  1416                              <1> 	;
  1417                              <1> 	;pushf			; save interrupt status
  1418 0000180F FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  1419 00001810 E461                <1> 	in	al, PORT_B	; get current port value
  1420                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  1421 00001812 0CFC                <1>         or      al, ~(GATE2+SPK2)
  1422 00001814 20C4                <1>         and	ah, al		; someone turned them off during beep
  1423 00001816 88E0                <1> 	mov	al, ah		; recover value of port
  1424                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  1425 00001818 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  1426 0000181A E661                <1> 	out	PORT_B, al	; and stop speaker timer
  1427                              <1> 	;popf			; restore interrupt flag state
  1428 0000181C FB                  <1> 	sti
  1429 0000181D B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  1430 00001822 E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  1431                              <1> 	;pushf			; save interrupt status
  1432 00001827 FA                  <1> 	cli			; block interrupts during update
  1433 00001828 E461                <1> 	in	al, PORT_B	; get current port value in case	
  1434 0000182A 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  1435 0000182C 08E0                <1> 	or	al, ah		; recover value of port_b
  1436 0000182E E661                <1> 	out	PORT_B, al	; restore speaker status
  1437 00001830 9D                  <1> 	popf			; restore interrupt flag state
  1438                              <1> u12:	
  1439 00001831 C3                  <1> 	retn
  1440                              <1> 
  1441                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  1442                              <1> 
  1443                              <1> WAITF:
  1444                              <1> waitf:
  1445                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1446                              <1> 	; 03/12/2013
  1447                              <1> 	;
  1448                              <1> ;	push ax			; save work register (ah)	
  1449                              <1> ;waitf1:
  1450                              <1> 				; use timer 1 output bits
  1451                              <1> ;	in	al, PORT_B	; read current counter output status
  1452                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  1453                              <1> ;	cmp	al, ah		; did it just change
  1454                              <1> ;	je	short waitf1	; wait for a change in output line
  1455                              <1> ;	;
  1456                              <1> ;	mov	ah, al		; save new lflag state
  1457                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  1458                              <1> ;	;
  1459                              <1> ;	pop	ax		; restore (ah)
  1460                              <1> ;	retn			; return (cx)=0
  1461                              <1> 
  1462                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  1463                              <1> ; 17/12/2014 (dsectrm2.s)
  1464                              <1> ; WAITF
  1465                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  1466                              <1> ;
  1467                              <1> ;---WAITF-----------------------------------------------------------------------
  1468                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  1469                              <1> ; ENTRY:
  1470                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  1471                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  1472                              <1> ; EXIT:
  1473                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  1474                              <1> ;	(CX) = 0	
  1475                              <1> ;-------------------------------------------------------------------------------
  1476                              <1> 
  1477                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  1478                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  1479                              <1> 
  1480                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  1481 00001832 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  1482                              <1> 	; 16/12/2014
  1483                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  1484 00001834 D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  1485                              <1> ;17/12/2014	
  1486                              <1> ;WAITF1:
  1487                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  1488                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  1489                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  1490                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  1491                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  1492                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  1493                              <1> 	;
  1494                              <1> 	; 17/12/2014
  1495                              <1> 	;
  1496                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  1497                              <1> 	;
  1498                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  1499                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  1500                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  1501                              <1> WR_STATE_0:
  1502 00001836 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1503 00001838 A810                <1> 	TEST	AL,010H
  1504 0000183A 74FA                <1> 	JZ	SHORT WR_STATE_0
  1505                              <1> WR_STATE_1:
  1506 0000183C E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1507 0000183E A810                <1> 	TEST	AL,010H
  1508 00001840 75FA                <1> 	JNZ	SHORT WR_STATE_1
  1509 00001842 E2F2                <1>         LOOP    WR_STATE_0
  1510                              <1> 	;
  1511 00001844 6658                <1> 	POP	AX			; RESTORE (AH)
  1512 00001846 C3                  <1> 	RETn				; (CX) = 0
  1513                              <1> 
  1514                              <1> ; % include 'vidata.s' ; VIDEO DATA
  1515                              <1> 
  1516                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1682                                  
  1683                                  setup_rtc_int:
  1684                                  ; source: http://wiki.osdev.org/RTC
  1685 00001847 FA                      	cli		; disable interrupts
  1686                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  1687                                  	; in order to change this ...
  1688                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  1689                                  	; (rate must be above 2 and not over 15)
  1690                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  1691 00001848 B08A                    	mov	al, 8Ah 
  1692 0000184A E670                    	out	70h, al ; set index to register A, disable NMI
  1693 0000184C 90                      	nop
  1694 0000184D E471                    	in	al, 71h ; get initial value of register A
  1695 0000184F 88C4                    	mov 	ah, al
  1696 00001851 80E4F0                  	and	ah, 0F0h
  1697 00001854 B08A                    	mov	al, 8Ah 
  1698 00001856 E670                    	out	70h, al ; reset index to register A
  1699 00001858 88E0                    	mov	al, ah
  1700 0000185A 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1701 0000185C E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1702                                  	; enable RTC interrupt
  1703 0000185E B08B                    	mov	al, 8Bh ;
  1704 00001860 E670                    	out	70h, al ; select register B and disable NMI
  1705 00001862 90                      	nop
  1706 00001863 E471                    	in	al, 71h ; read the current value of register B
  1707 00001865 88C4                    	mov	ah, al  ;
  1708 00001867 B08B                    	mov 	al, 8Bh ;
  1709 00001869 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1710 0000186B 88E0                    	mov	al, ah  ;
  1711 0000186D 0C40                    	or	al, 40h ;
  1712 0000186F E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1713 00001871 FB                      	sti
  1714 00001872 C3                      	retn
  1715                                  
  1716                                  ; Write memory information
  1717                                  ; 29/01/2016
  1718                                  ; 06/11/2014
  1719                                  ; 14/08/2015 
  1720                                  memory_info:	
  1721 00001873 A1[BCD20000]            	mov	eax, [memory_size] ; in pages
  1722 00001878 50                      	push	eax
  1723 00001879 C1E00C                  	shl	eax, 12		   ; in bytes
  1724 0000187C BB0A000000              	mov	ebx, 10
  1725 00001881 89D9                    	mov	ecx, ebx	   ; 10
  1726 00001883 BE[C3CE0000]            	mov	esi, mem_total_b_str	
  1727 00001888 E8BD000000              	call	bintdstr
  1728 0000188D 58                      	pop	eax
  1729 0000188E B107                    	mov	cl, 7
  1730 00001890 BE[E7CE0000]            	mov	esi, mem_total_p_str
  1731 00001895 E8B0000000              	call	bintdstr	
  1732                                  	; 14/08/2015
  1733 0000189A E8C8000000              	call	calc_free_mem
  1734                                  	; edx = calculated free pages
  1735                                  	; ecx = 0
  1736 0000189F A1[C0D20000]            	mov 	eax, [free_pages]
  1737 000018A4 39D0                    	cmp	eax, edx ; calculated free mem value 
  1738                                  		; and initial free mem value are same or not?
  1739 000018A6 751D                    	jne 	short pmim ; print mem info with '?' if not
  1740 000018A8 52                      	push 	edx ; free memory in pages	
  1741                                  	;mov 	eax, edx
  1742 000018A9 C1E00C                  	shl	eax, 12 ; convert page count
  1743                                  			; to byte count
  1744 000018AC B10A                    	mov	cl, 10
  1745 000018AE BE[07CF0000]            	mov	esi, free_mem_b_str
  1746 000018B3 E892000000              	call	bintdstr
  1747 000018B8 58                      	pop	eax
  1748 000018B9 B107                    	mov	cl, 7
  1749 000018BB BE[2BCF0000]            	mov	esi, free_mem_p_str
  1750 000018C0 E885000000              	call	bintdstr
  1751                                  pmim:
  1752 000018C5 BE[B1CE0000]            	mov	esi, msg_memory_info
  1753                                  	;
  1754 000018CA B407                    	mov	ah, 07h ; Black background, 
  1755                                  			; light gray forecolor
  1756                                  print_kmsg: ; 29/01/2016
  1757 000018CC 8825[E7D20000]          	mov	[ccolor], ah
  1758                                  pkmsg_loop:
  1759 000018D2 AC                      	lodsb
  1760 000018D3 08C0                    	or	al, al
  1761 000018D5 7410                    	jz	short pkmsg_ok
  1762 000018D7 56                      	push	esi
  1763                                  	; 13/05/2016
  1764 000018D8 0FB61D[E7D20000]        	movzx	ebx, byte [ccolor]
  1765                                  			; Video page 0 (bh=0)
  1766 000018DF E81EFEFFFF              	call	_write_tty
  1767 000018E4 5E                      	pop	esi
  1768 000018E5 EBEB                    	jmp	short pkmsg_loop
  1769                                  pkmsg_ok:
  1770 000018E7 C3                      	retn
  1771                                  
  1772                                  ; Convert binary number to hexadecimal string
  1773                                  ; 10/05/2015  
  1774                                  ; dsectpm.s (28/02/2015)
  1775                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  1776                                  ; 01/12/2014
  1777                                  ; 25/11/2014
  1778                                  ;
  1779                                  bytetohex:
  1780                                  	; INPUT ->
  1781                                  	; 	AL = byte (binary number)
  1782                                  	; OUTPUT ->
  1783                                  	;	AX = hexadecimal string
  1784                                  	;
  1785 000018E8 53                      	push	ebx
  1786 000018E9 31DB                    	xor	ebx, ebx
  1787 000018EB 88C3                    	mov	bl, al
  1788 000018ED C0EB04                  	shr	bl, 4
  1789 000018F0 8A9B[3A190000]          	mov	bl, [ebx+hexchrs] 	 	
  1790 000018F6 86D8                    	xchg	bl, al
  1791 000018F8 80E30F                  	and	bl, 0Fh
  1792 000018FB 8AA3[3A190000]          	mov	ah, [ebx+hexchrs] 
  1793 00001901 5B                      	pop	ebx	
  1794 00001902 C3                      	retn
  1795                                  
  1796                                  wordtohex:
  1797                                  	; INPUT ->
  1798                                  	; 	AX = word (binary number)
  1799                                  	; OUTPUT ->
  1800                                  	;	EAX = hexadecimal string
  1801                                  	;
  1802 00001903 53                      	push	ebx
  1803 00001904 31DB                    	xor	ebx, ebx
  1804 00001906 86E0                    	xchg	ah, al
  1805 00001908 6650                    	push	ax
  1806 0000190A 88E3                    	mov	bl, ah
  1807 0000190C C0EB04                  	shr	bl, 4
  1808 0000190F 8A83[3A190000]          	mov	al, [ebx+hexchrs] 	 	
  1809 00001915 88E3                    	mov	bl, ah
  1810 00001917 80E30F                  	and	bl, 0Fh
  1811 0000191A 8AA3[3A190000]          	mov	ah, [ebx+hexchrs]
  1812 00001920 C1E010                  	shl	eax, 16
  1813 00001923 6658                    	pop	ax
  1814 00001925 5B                      	pop	ebx
  1815 00001926 EBC0                    	jmp	short bytetohex
  1816                                  	;mov	bl, al
  1817                                  	;shr	bl, 4
  1818                                  	;mov	bl, [ebx+hexchrs] 	 	
  1819                                  	;xchg	bl, al	 	
  1820                                  	;and	bl, 0Fh
  1821                                  	;mov	ah, [ebx+hexchrs] 
  1822                                  	;pop	ebx	
  1823                                  	;retn
  1824                                  
  1825                                  dwordtohex:
  1826                                  	; INPUT ->
  1827                                  	; 	EAX = dword (binary number)
  1828                                  	; OUTPUT ->
  1829                                  	;	EDX:EAX = hexadecimal string
  1830                                  	;
  1831 00001928 50                      	push	eax
  1832 00001929 C1E810                  	shr	eax, 16
  1833 0000192C E8D2FFFFFF              	call	wordtohex
  1834 00001931 89C2                    	mov	edx, eax
  1835 00001933 58                      	pop	eax
  1836 00001934 E8CAFFFFFF              	call	wordtohex
  1837 00001939 C3                      	retn
  1838                                  
  1839                                  ; 10/05/2015
  1840                                  hex_digits:
  1841                                  hexchrs:
  1842 0000193A 303132333435363738-     	db '0123456789ABCDEF'
  1842 00001943 39414243444546     
  1843                                  
  1844                                  ; Convert binary number to decimal/numeric string
  1845                                  ; 06/11/2014
  1846                                  ; Temporary Code
  1847                                  ;
  1848                                  
  1849                                  bintdstr:
  1850                                  	; EAX = binary number
  1851                                  	; ESI = decimal/numeric string address
  1852                                  	; EBX = divisor (10)
  1853                                  	; ECX = string length (<=10)
  1854 0000194A 01CE                    	add	esi, ecx
  1855                                  btdstr0:
  1856 0000194C 4E                      	dec	esi
  1857 0000194D 31D2                    	xor	edx, edx
  1858 0000194F F7F3                    	div	ebx
  1859 00001951 80C230                  	add	dl, 30h
  1860 00001954 8816                    	mov	[esi], dl
  1861 00001956 FEC9                    	dec	cl
  1862 00001958 740C                    	jz	btdstr2
  1863 0000195A 09C0                    	or	eax, eax
  1864 0000195C 75EE                    	jnz	short btdstr0
  1865                                  btdstr1:
  1866 0000195E 4E                      	dec	esi
  1867 0000195F C60620                          mov     byte [esi], 20h ; blank space
  1868 00001962 FEC9                    	dec	cl
  1869 00001964 75F8                    	jnz	short btdstr1
  1870                                  btdstr2:
  1871 00001966 C3                      	retn
  1872                                  
  1873                                  ; Calculate free memory pages on M.A.T.
  1874                                  ; 06/11/2014
  1875                                  ; Temporary Code
  1876                                  ;
  1877                                  
  1878                                  calc_free_mem:
  1879 00001967 31D2                    	xor	edx, edx
  1880                                  	;xor	ecx, ecx
  1881 00001969 668B0D[D0D20000]        	mov	cx, [mat_size] ; in pages
  1882 00001970 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  1883 00001973 BE00001000              	mov	esi, MEM_ALLOC_TBL
  1884                                  cfm0:
  1885 00001978 AD                      	lodsd
  1886 00001979 51                      	push	ecx
  1887 0000197A B920000000              	mov	ecx, 32
  1888                                  cfm1:
  1889 0000197F D1E8                    	shr	eax, 1
  1890 00001981 7301                    	jnc	short cfm2
  1891 00001983 42                      	inc	edx
  1892                                  cfm2:
  1893 00001984 E2F9                    	loop	cfm1
  1894 00001986 59                      	pop	ecx
  1895 00001987 E2EF                    	loop	cfm0
  1896 00001989 C3                      	retn
  1897                                  
  1898                                  %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: 01/06/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 0000198A 9C                  <1> 	pushfd
    31 0000198B 0E                  <1> 	push 	cs
    32 0000198C E809000000          <1> 	call 	DISKETTE_IO_1
    33 00001991 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 00001992 9C                  <1> 	pushfd
   457 00001993 0E                  <1> 	push 	cs
   458 00001994 E801000000          <1> 	call 	DISKETTE_IO_1
   459 00001999 C3                  <1> 	retn	
   460                              <1> 
   461                              <1> DISKETTE_IO_1:
   462                              <1> 
   463 0000199A FB                  <1> 	STI				; INTERRUPTS BACK ON
   464 0000199B 55                  <1> 	PUSH	eBP			; USER REGISTER
   465 0000199C 57                  <1> 	PUSH	eDI			; USER REGISTER
   466 0000199D 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   467 0000199E 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   468 0000199F 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   469 000019A0 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 000019A2 06                  <1> 	push	es ; 06/02/2015	
   484 000019A3 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   485 000019A4 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 000019A5 66B91000            <1> 	mov	cx, KDATA
   490 000019A9 8ED9                <1>         mov     ds, cx
   491 000019AB 8EC1                <1>         mov     es, cx
   492                              <1> 
   493                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   494 000019AD 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4  ; 18/02/2015
   495 000019B0 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   496 000019B2 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   497                              <1> OK_FUNC:
   498 000019B4 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   499 000019B7 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   500 000019B9 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   501 000019BC 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   502 000019BE 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   503 000019C1 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   504 000019C3 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   505                              <1> OK_DRV:
   506 000019C5 31C9                <1> 	xor	ecx, ecx
   507                              <1> 	;mov	esi, ecx ; 08/02/2015
   508 000019C7 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   509 000019C9 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   510                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   511                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   512 000019CB C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   513 000019CE BB[061A0000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   514 000019D3 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   515 000019D5 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   516 000019D7 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   517 000019D9 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   518 000019DC 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   519                              <1> 	;
   520                              <1> 	; 11/12/2014
   521 000019DF 8815[B3CD0000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   522                              <1> 	;
   523 000019E5 8A25[40D30000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   524 000019EB C605[40D30000]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 000019F2 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   545 000019F4 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   546 000019F5 1F                  <1> 	POP	DS
   547 000019F6 07                  <1> 	pop	es	; 06/02/2015
   548 000019F7 59                  <1> 	POP	eCX
   549 000019F8 5B                  <1> 	POP	eBX
   550 000019F9 5A                  <1> 	POP	eDX
   551 000019FA 5F                  <1> 	POP	eDI
   552 000019FB 89E5                <1> 	MOV	eBP, eSP
   553 000019FD 50                  <1> 	PUSH	eAX
   554 000019FE 9C                  <1> 	PUSHFd
   555 000019FF 58                  <1> 	POP	eAX
   556                              <1> 	;MOV	[BP+6], AX
   557 00001A00 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   558 00001A03 58                  <1> 	POP	eAX
   559 00001A04 5D                  <1> 	POP	eBP
   560 00001A05 CF                  <1> 	IRETd
   561                              <1> 
   562                              <1> ;-------------------------------------------------------------------------------
   563                              <1> ; DW --> dd (06/02/2015)
   564 00001A06 [6A1A0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   565 00001A0A [E31A0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   566 00001A0E [F41A0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   567 00001A12 [051B0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   568 00001A16 [161B0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   569 00001A1A [271B0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   570 00001A1E [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   571 00001A22 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   572 00001A26 [B91B0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   573 00001A2A [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   574 00001A2E [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   575 00001A32 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   576 00001A36 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   577 00001A3A [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   578 00001A3E [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   579 00001A42 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   580 00001A46 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   581 00001A4A [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   582 00001A4E [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   583 00001A52 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   584 00001A56 [AC1B0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   585 00001A5A [911C0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   586 00001A5E [BC1C0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   587 00001A62 [F61C0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   588 00001A66 [791D0000]          <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 00001A6A 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   599 00001A6E FA                  <1> 	CLI				; NO INTERRUPTS
   600 00001A6F A0[3ED30000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   601 00001A74 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   602 00001A76 C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   603                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   604 00001A79 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   605 00001A7B EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   606 00001A7C C605[3DD30000]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 00001A83 E6EB                <2>  out 0ebh,al
   612                              <1> 
   613                              <1> 	; 17/12/2014 
   614                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   615 00001A85 B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   616                              <1> wdw1:
   617                              <1> 	NEWIODELAY   ; 27/02/2015
   617 00001A8A E6EB                <2>  out 0ebh,al
   618 00001A8C E2FC                <1> 	loop	wdw1
   619                              <1> 	;
   620 00001A8E 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   621 00001A90 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   622                              <1> 	; 16/12/2014
   623                              <1> 	IODELAY
   623 00001A91 EB00                <2>  jmp short $+2
   623 00001A93 EB00                <2>  jmp short $+2
   624                              <1> 	;
   625                              <1> 	;STI				; ENABLE THE INTERRUPTS
   626 00001A95 E83C0C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   627 00001A9A 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   628 00001A9C 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   629                              <1> NXT_DRV:
   630 00001AA0 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   631 00001AA2 B8[D81A0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   632 00001AA7 50                  <1> 	PUSH	eAX			; "
   633 00001AA8 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   634 00001AAA E81A0B0000          <1> 	CALL	NEC_OUTPUT
   635 00001AAF 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   636 00001AB0 E8510C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   637 00001AB5 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   638 00001AB7 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   639 00001AB9 3A0D[41D30000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   640 00001ABF 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   641 00001AC1 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   642 00001AC3 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   643 00001AC6 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   644                              <1> 	;
   645 00001AC8 E869030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   646                              <1> RESBAC:
   647 00001ACD E81D090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   648 00001AD2 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   649 00001AD5 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   650 00001AD7 C3                  <1> 	RETn		
   651                              <1> DR_POP_ERR:
   652 00001AD8 6659                <1> 	POP	CX			; CLEAR STACK
   653                              <1> DR_ERR:
   654 00001ADA 800D[40D30000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   655 00001AE1 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 00001AE3 8825[40D30000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   667 00001AE9 E801090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   668 00001AEE 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   669 00001AF1 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   670 00001AF3 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 00001AF4 8025[3ED30000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   691 00001AFB 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   692 00001AFF E83C040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   693 00001B04 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 00001B05 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   714 00001B09 800D[3ED30000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   715 00001B10 E82B040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   716 00001B15 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 00001B16 8025[3ED30000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   734 00001B1D 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   735 00001B21 E81A040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   736 00001B26 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 00001B27 E853030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   755 00001B2C E84F050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   756 00001B31 800D[3ED30000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   757 00001B38 E897050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   758 00001B3D 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   759 00001B3F E8F2020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   760 00001B44 E8FD050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   761 00001B49 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   762 00001B4B E8D4050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   763                              <1> FM_WR:
   764 00001B50 E88A060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   765 00001B55 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   766 00001B57 B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   767 00001B59 E8E7060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   768 00001B5E 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   769 00001B60 B8[9C1B0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   770 00001B65 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   771 00001B66 B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   772 00001B68 E856090000          <1> 	CALL	GET_PARM
   773 00001B6D E8570A0000          <1> 	CALL	NEC_OUTPUT
   774 00001B72 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   775 00001B74 E84A090000          <1> 	CALL	GET_PARM
   776 00001B79 E84B0A0000          <1> 	CALL	NEC_OUTPUT
   777 00001B7E B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   778 00001B80 E83E090000          <1> 	CALL	GET_PARM
   779 00001B85 E83F0A0000          <1> 	CALL	NEC_OUTPUT
   780 00001B8A B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   781 00001B8C E832090000          <1> 	CALL	GET_PARM
   782 00001B91 E8330A0000          <1> 	CALL	NEC_OUTPUT
   783 00001B96 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   784 00001B97 E827070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   785                              <1> FM_DON:
   786 00001B9C E80F030000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   787 00001BA1 E849080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   788 00001BA6 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   789 00001BA9 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   790 00001BAB 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 00001BAC 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   801 00001BAF B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   802 00001BB1 8825[40D30000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   803 00001BB7 F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   804 00001BB8 C3                  <1> 	RETn
   805                              <1> 
   806                              <1> ; 01/06/2016
   807                              <1> ; 28/05/2016
   808                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v.2.0)
   809                              <1> ;-------------------------------------------------------------------------------
   810                              <1> ; DISK_PARMS	(AH = 08H)	
   811                              <1> ;	READ DRIVE PARAMETERS.
   812                              <1> ;
   813                              <1> ; ON ENTRY:	DI : DRIVE #
   814                              <1> ;		; 27/05/2016
   815                              <1> ;		EBX = Buffer Address for floppy disk parameters table (16 bytes)
   816                              <1> ;
   817                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
   818                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
   819                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
   820                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
   821                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
   822                              <1> ;		BH/[BP+3] = 0
   823                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
   824                              <1> ;		DH/[BP+5] = MAX HEAD #
   825                              <1> ;	     ** 27/05/2016 - TRDOS 386 (TRDOS v2.0) **	
   826                              <1> ;            ** EBX = Buffer address for floppy disk parameters table **
   827                              <1> ;		;DI/[BP+6] = OFFSET TO DISK_BASE
   828                              <1> ;		;ES        = SEGMENT OF DISK_BASE
   829                              <1> ;
   830                              <1> ;		AX        = 0
   831                              <1> ;
   832                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
   833                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
   834                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
   835                              <1> ;		       CALLER.
   836                              <1> ;-------------------------------------------------------------------------------
   837                              <1> DSK_PARMS:
   838 00001BB9 E8C1020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
   839                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
   840                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
   841                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
   842                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
   843                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
   844                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
   845                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
   846                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
   847                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
   848 00001BBE 29D2                <1> 	sub	edx, edx
   849 00001BC0 66A1[C0CD0000]      <1> 	mov     ax, [fd0_type]
   850 00001BC6 6621C0              <1> 	and     ax, ax
   851 00001BC9 0F848A000000        <1>         jz      NON_DRV
   852 00001BCF FEC2                <1> 	inc     dl
   853 00001BD1 20E4                <1> 	and     ah, ah
   854 00001BD3 7402                <1> 	jz      short STO_DL
   855 00001BD5 FEC2                <1> 	inc     dl
   856                              <1> STO_DL:
   857                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   858 00001BD7 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   859 00001BDA 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   860 00001BDE 777C                <1> 	JA	short NON_DRV1		; DRIVE INVALID
   861                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   862 00001BE0 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   863 00001BE4 E8D1080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
   864                              <1> 	;;20/02/2015
   865                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
   866                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
   867 00001BE9 740F                <1> 	JZ	short CHK_EST		; JUMP IF SO
   868 00001BEB E81B020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   869 00001BF0 7208                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
   870                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
   871                              <1>         ;mov	[ebp+4], al ; 06/02/2015
   872 00001BF2 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   873 00001BF5 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   874 00001BF8 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   875                              <1> CHK_EST:
   876 00001BFA 8AA7[4DD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   877 00001C00 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   878 00001C03 7457                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   879                              <1> USE_EST:
   880 00001C05 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   881 00001C08 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   882 00001C0B 7570                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
   883                              <1> 
   884                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
   885                              <1> 
   886 00001C0D B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   887 00001C0F E8F7010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   888 00001C14 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   889 00001C17 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   890 00001C1A F687[4DD30000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   891 00001C21 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
   892                              <1> 
   893                              <1> ;-----	IT IS 1.44 MB DRIVE
   894                              <1> 
   895                              <1> PARM144:
   896 00001C23 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   897 00001C25 E8E1010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   898 00001C2A 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   899 00001C2D 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   900                              <1> STO_CX:
   901 00001C30 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
   902                              <1> ES_DI:
   903                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
   904                              <1> 	;mov	[ebp+12], ebx ; 06/02/2015
   905                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
   906                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   907                              <1> 	;
   908                              <1> 	; 28/05/2016
   909                              <1> 	; 27/05/2016
   910                              <1> 	; return floppy disk parameters table to user
   911                              <1> 	; in user's buffer, which is pointed by EBX
   912                              <1> 	;
   913 00001C33 57                  <1> 	push	edi
   914 00001C34 8B7D04              <1> 	mov	edi, [ebp+4]  		; ebx (input), user's buffer address
   915 00001C37 0FB6C0              <1> 	movzx	eax, al
   916 00001C3A 894504              <1>         mov	[ebp+4], eax   ; ebx	; drive type (for floppy drives)
   917                              <1> 	; 01/06/2016 (INT 33h, disk type return for floppy disks, in BL)
   918 00001C3D A3[3CE00000]        <1> 	mov	[user_buffer], eax	; 01/06/2016 (overwrite ebx return value)
   919                              <1> 	;(INT 33h, Function 08h will replace user's buffer addr with disk type!)
   920                              <1> 	;
   921 00001C42 89DE                <1> 	mov	esi, ebx 		; floppy disk parameter table (16 bytes)
   922 00001C44 B910000000          <1> 	mov	ecx, 16 ; 16 bytes
   923 00001C49 E837A10000          <1>         call    transfer_to_user_buffer ; trdosk6.s (16/05/2016)
   924 00001C4E 5F                  <1> 	pop	edi	
   925                              <1> DP_OUT:
   926 00001C4F E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   927 00001C54 6631C0              <1> 	XOR	AX,AX			; CLEAR
   928 00001C57 F8                  <1> 	CLC
   929 00001C58 C3                  <1> 	RETn
   930                              <1> 
   931                              <1> ;-----	NO DRIYE PRESENT HANDLER
   932                              <1> 
   933                              <1> NON_DRV:
   934                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
   935 00001C59 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   936                              <1> NON_DRV1:
   937 00001C5C 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   938 00001C61 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
   939                              <1> 
   940                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
   941                              <1> 	
   942 00001C63 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   943 00001C68 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   944 00001C6B B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   945 00001C6D F9                  <1> 	STC
   946 00001C6E C3                  <1> 	RETn
   947                              <1> 
   948                              <1> NON_DRV2:
   949                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   950 00001C6F 31C0                <1> 	xor	eax, eax	
   951 00001C71 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   952                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   953 00001C75 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   954                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   955 00001C78 89450C              <1> 	mov	[ebp+12], eax
   956                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   957 00001C7B EBD2                <1> 	JMP	SHORT DP_OUT
   958                              <1> 
   959                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
   960                              <1> 
   961                              <1> USE_EST2:
   962 00001C7D B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   963 00001C7F E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   964 00001C84 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   965 00001C87 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   966 00001C8A 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   967 00001C8D 74A1                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   968 00001C8F EB92                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
   969                              <1> 
   970                              <1> ;-------------------------------------------------------------------------------
   971                              <1> ; DISK_TYPE (AH = 15H)	
   972                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
   973                              <1> ;
   974                              <1> ;  ON ENTRY:	DI = DRIVE #
   975                              <1> ;
   976                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
   977                              <1> ;-------------------------------------------------------------------------------
   978                              <1> DSK_TYPE:
   979 00001C91 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   980 00001C96 8A87[4DD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
   981 00001C9C 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
   982 00001C9E 7418                <1> 	JZ	short NO_DRV
   983 00001CA0 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
   984 00001CA2 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
   985 00001CA4 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
   986 00001CA6 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
   987                              <1> DT_BACK:
   988 00001CA8 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
   989 00001CAA E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   990 00001CAF 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
   991 00001CB1 F8                  <1> 	CLC				; NO ERROR
   992 00001CB2 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   993 00001CB5 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   994 00001CB7 C3                  <1> 	RETn
   995                              <1> NO_DRV:	
   996 00001CB8 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
   997 00001CBA EBEC                <1> 	JMP	SHORT DT_BACK
   998                              <1> 
   999                              <1> ;-------------------------------------------------------------------------------
  1000                              <1> ; DISK_CHANGE	(AH = 16H)
  1001                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  1002                              <1> ;
  1003                              <1> ; ON ENTRY:	DI = DRIVE #
  1004                              <1> ;
  1005                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  1006                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  1007                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  1008                              <1> ;-------------------------------------------------------------------------------
  1009                              <1> DSK_CHANGE:
  1010 00001CBC E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1011 00001CC1 8A87[4DD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  1012 00001CC7 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  1013 00001CC9 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  1014 00001CCB A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  1015 00001CCD 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  1016                              <1> DC0:
  1017 00001CCF E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  1018 00001CD4 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  1019                              <1> 
  1020 00001CD6 C605[40D30000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  1021                              <1> 
  1022 00001CDD E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1023 00001CE2 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1024 00001CE7 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  1025 00001CEA 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1026 00001CEC C3                  <1> 	RETn
  1027                              <1> DC_NON:
  1028 00001CED 800D[40D30000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  1029 00001CF4 EBE7                <1> 	JMP	SHORT FINIS
  1030                              <1> 
  1031                              <1> ;-------------------------------------------------------------------------------
  1032                              <1> ; FORMAT_SET	(AH = 17H)
  1033                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  1034                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  1035                              <1> ;
  1036                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  1037                              <1> ;		DI     = DRIVE #
  1038                              <1> ;
  1039                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  1040                              <1> ;		AH = @DSKETTE_STATUS
  1041                              <1> ;		CY = 1 IF ERROR
  1042                              <1> ;-------------------------------------------------------------------------------
  1043                              <1> FORMAT_SET:
  1044 00001CF6 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1045 00001CFB 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1046 00001CFD 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1047 00001D00 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1048 00001D02 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1049 00001D05 80A7[4DD30000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1050 00001D0C 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1051 00001D0E 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1052 00001D10 808F[4DD30000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1053 00001D17 EB48                <1> 	JMP	SHORT S0
  1054                              <1> 
  1055                              <1> NOT_320:
  1056 00001D19 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1057 00001D1E 803D[40D30000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1058 00001D25 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1059                              <1> S3:
  1060 00001D27 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1061 00001D29 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1062 00001D2B 808F[4DD30000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1063 00001D32 EB2D                <1> 	JMP	SHORT S0
  1064                              <1> 
  1065                              <1> NOT_320_12:
  1066 00001D34 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1067 00001D36 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1068 00001D38 808F[4DD30000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1069 00001D3F EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1070                              <1> 
  1071                              <1> NOT_12:	
  1072 00001D41 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1073 00001D43 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1074                              <1> 
  1075 00001D45 F687[4DD30000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1076 00001D4C 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1077 00001D4E B050                <1> 	MOV	AL,MED_DET+RATE_300
  1078 00001D50 F687[4DD30000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1079 00001D57 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1080                              <1> 
  1081                              <1> ASSUME:
  1082 00001D59 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1083                              <1> 
  1084                              <1> OR_IT_IN:
  1085 00001D5B 0887[4DD30000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1086                              <1> S0:
  1087 00001D61 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1088 00001D66 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1089 00001D6B 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1090 00001D6D 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1091 00001D6F C3                  <1> 	RETn
  1092                              <1> 
  1093                              <1> FS_ERR:
  1094 00001D70 C605[40D30000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1095 00001D77 EBE8                <1> 	JMP	SHORT S0
  1096                              <1> 
  1097                              <1> ;-------------------------------------------------------------------------------
  1098                              <1> ; SET_MEDIA	(AH = 18H)
  1099                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  1100                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  1101                              <1> ;
  1102                              <1> ; ON ENTRY:
  1103                              <1> ;	[BP]	= SECTOR PER TRACK
  1104                              <1> ;	[BP+1]	= TRACK #
  1105                              <1> ;	DI	= DRIVE #
  1106                              <1> ;
  1107                              <1> ; ON EXIT:
  1108                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  1109                              <1> ;	IF NO ERROR:
  1110                              <1> ;		AH = 0
  1111                              <1> ;		CY = 0
  1112                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1113                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  1114                              <1> ;	IF ERROR:	
  1115                              <1> ;		AH = @DSKETTE_STATUS
  1116                              <1> ;		CY = 1
  1117                              <1> ;-------------------------------------------------------------------------------
  1118                              <1> SET_MEDIA:
  1119 00001D79 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1120 00001D7E F687[4DD30000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1121 00001D85 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1122 00001D87 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1123 00001D8C 803D[40D30000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1124 00001D93 746B                <1> 	JE	short SM_RTN
  1125 00001D95 C605[40D30000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1126                              <1> SM_CMOS:
  1127 00001D9C E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1128                              <1> 	;;20/02/2015
  1129                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  1130                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  1131 00001DA1 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1132 00001DA3 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1133 00001DA8 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1134 00001DAA 57                  <1> 	PUSH	eDI			; SAVE REG.
  1135 00001DAB 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1136 00001DAD B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1137                              <1> DR_SEARCH:
  1138 00001DB2 8AA3[3ECD0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1139 00001DB8 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1140 00001DBB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1141 00001DBD 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1142                              <1> DR_FND:
  1143 00001DBF 8BBB[3FCD0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1144                              <1> MD_SEARCH:
  1145 00001DC5 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1146 00001DC8 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1147 00001DCB 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1148 00001DCD 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1149 00001DD0 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1150 00001DD3 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1151                              <1> NXT_MD:
  1152                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1153 00001DD5 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1154 00001DD8 E2D8                <1> 	LOOP    DR_SEARCH
  1155 00001DDA 5F                  <1> 	POP	eDI			; RESTORE REG.
  1156                              <1> MD_NOT_FND:
  1157 00001DDB C605[40D30000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1158 00001DE2 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1159                              <1> MD_FND:
  1160 00001DE4 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1161 00001DE7 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1162 00001DE9 7502                <1> 	JNE	short MD_SET
  1163 00001DEB 0C20                <1> 	OR	AL,DBL_STEP
  1164                              <1> MD_SET:
  1165                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1166 00001DED 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1167 00001DF0 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1168 00001DF2 5F                  <1> 	POP	eDI
  1169 00001DF3 80A7[4DD30000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1170 00001DFA 0887[4DD30000]      <1> 	OR	[DSK_STATE+eDI], AL
  1171                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1172                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  1173                              <1> SM_RTN:
  1174 00001E00 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1175 00001E05 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1176 00001E0A C3                  <1> 	RETn
  1177                              <1> 
  1178                              <1> ;----------------------------------------------------------------
  1179                              <1> ; DR_TYPE_CHECK							:
  1180                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  1181                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  1182                              <1> ; ON ENTRY:							:
  1183                              <1> ;	AL = DRIVE TYPE						:
  1184                              <1> ; ON EXIT:							:
  1185                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  1186                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  1187                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  1188                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  1189                              <1> ; REGISTERS ALTERED: eBX						:
  1190                              <1> ;----------------------------------------------------------------		
  1191                              <1> DR_TYPE_CHECK:
  1192 00001E0B 6650                <1> 	PUSH	AX			
  1193 00001E0D 51                  <1> 	PUSH	eCX
  1194 00001E0E 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1195 00001E10 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1196                              <1> TYPE_CHK:	
  1197 00001E15 8AA3[3ECD0000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1198 00001E1B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1199 00001E1D 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1200                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1201 00001E1F 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1202 00001E22 E2F1                <1> 	LOOP    TYPE_CHK
  1203                              <1> 	;
  1204 00001E24 BB[9DCD0000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1205                              <1> 					; Default for GET_PARM (11/12/2014)
  1206                              <1> 	;
  1207 00001E29 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1208 00001E2A EB06                <1> 	JMP	SHORT TYPE_RTN
  1209                              <1> DR_TYPE_VALID:
  1210 00001E2C 8B9B[3FCD0000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1211                              <1> TYPE_RTN:
  1212 00001E32 59                  <1> 	POP	eCX
  1213 00001E33 6658                <1> 	POP	AX
  1214 00001E35 C3                  <1> 	RETn	
  1215                              <1> 		
  1216                              <1> ;----------------------------------------------------------------
  1217                              <1> ; SEND_SPEC							:
  1218                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1219                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  1220                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  1221                              <1> ; ON EXIT:	NONE						:	
  1222                              <1> ; REGISTERS ALTERED: CX, DX					:
  1223                              <1> ;----------------------------------------------------------------		
  1224                              <1> SEND_SPEC:
  1225 00001E36 50                  <1> 	PUSH	eAX			; SAVE AX
  1226 00001E37 B8[5D1E0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1227 00001E3C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1228 00001E3D B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1229 00001E3F E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1230 00001E44 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1231 00001E46 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1232 00001E4B E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1233 00001E50 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1234 00001E52 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1235 00001E57 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1236 00001E5C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1237                              <1> SPECBAC:
  1238 00001E5D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1239 00001E5E C3                  <1> 	RETn
  1240                              <1> 
  1241                              <1> ;----------------------------------------------------------------
  1242                              <1> ; SEND_SPEC_MD							:
  1243                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1244                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  1245                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  1246                              <1> ; ON EXIT:	NONE						:	
  1247                              <1> ; REGISTERS ALTERED: AX						:
  1248                              <1> ;----------------------------------------------------------------		
  1249                              <1> SEND_SPEC_MD:
  1250 00001E5F 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1251 00001E60 B8[7D1E0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1252 00001E65 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1253 00001E66 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1254 00001E68 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1255 00001E6D 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1256 00001E6F E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1257 00001E74 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1258 00001E77 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1259 00001E7C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1260                              <1> SPEC_ESBAC:
  1261 00001E7D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1262 00001E7E C3                  <1> 	RETn
  1263                              <1> 
  1264                              <1> ;-------------------------------------------------------------------------------
  1265                              <1> ; XLAT_NEW  
  1266                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  1267                              <1> ;	MODE TO NEW ARCHITECTURE.
  1268                              <1> ;
  1269                              <1> ; ON ENTRY:	DI = DRIVE #
  1270                              <1> ;-------------------------------------------------------------------------------
  1271                              <1> XLAT_NEW:
  1272 00001E7F 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1273 00001E82 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1274 00001E84 80BF[4DD30000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1275 00001E8B 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1276 00001E8D 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1277 00001E90 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1278 00001E93 A0[4CD30000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1279 00001E98 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1280 00001E9A 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1281 00001E9C 80A7[4DD30000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1282 00001EA3 0887[4DD30000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1283                              <1> XN_OUT:
  1284 00001EA9 C3                  <1> 	RETn
  1285                              <1> DO_DET:
  1286 00001EAA E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1287 00001EAF C3                  <1> 	RETn
  1288                              <1> 
  1289                              <1> ;-------------------------------------------------------------------------------
  1290                              <1> ; XLAT_OLD 
  1291                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  1292                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  1293                              <1> ;
  1294                              <1> ; ON ENTRY:	DI = DRIVE
  1295                              <1> ;-------------------------------------------------------------------------------
  1296                              <1> XLAT_OLD:
  1297 00001EB0 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1298                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1299 00001EB3 0F8786000000        <1>         ja      XO_OUT
  1300 00001EB9 80BF[4DD30000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1301 00001EC0 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  1302                              <1> 
  1303                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  1304                              <1> 
  1305 00001EC2 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1306 00001EC5 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1307 00001EC8 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1308 00001ECA D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1309 00001ECC 8425[4CD30000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1310 00001ED2 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  1311                              <1> 
  1312                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  1313                              <1> 
  1314 00001ED4 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1315 00001ED6 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1316 00001ED8 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1317 00001EDA 2025[4CD30000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  1318                              <1> 
  1319                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  1320                              <1> 
  1321 00001EE0 8A87[4DD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1322 00001EE6 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1323 00001EE8 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1324 00001EEA 0805[4CD30000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1325                              <1> 
  1326                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1327                              <1> 
  1328                              <1> SAVE_SET:
  1329 00001EF0 8AA7[4DD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1330 00001EF6 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1331 00001EF8 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1332 00001EFB 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1333 00001EFE 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1334 00001F00 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1335 00001F02 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1336 00001F05 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1337 00001F07 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1338 00001F0A 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1339                              <1> UNKNO:
  1340 00001F0C B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1341 00001F0E EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1342                              <1> CHK_144:
  1343 00001F10 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1344                              <1> 	;;20/02/2015
  1345                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  1346 00001F15 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1347 00001F17 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1348 00001F19 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1349 00001F1B B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1350 00001F1D EB0C                <1> 	JMP	SHORT TST_DET
  1351                              <1> CHK_250:
  1352 00001F1F B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1353 00001F21 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1354 00001F24 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1355 00001F26 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1356 00001F29 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1357                              <1> TST_DET:
  1358 00001F2B F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1359 00001F2E 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1360 00001F30 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1361                              <1> AL_SET:
  1362 00001F32 80A7[4DD30000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1363 00001F39 0887[4DD30000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1364                              <1> XO_OUT:
  1365 00001F3F C3                  <1> 	RETn
  1366                              <1> 
  1367                              <1> ;-------------------------------------------------------------------------------
  1368                              <1> ; RD_WR_VF
  1369                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  1370                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  1371                              <1> ;
  1372                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  1373                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  1374                              <1> ;
  1375                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1376                              <1> ;-------------------------------------------------------------------------------
  1377                              <1> RD_WR_VF:
  1378 00001F40 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1379 00001F42 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1380 00001F47 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1381 00001F4C 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1382                              <1> DO_AGAIN:
  1383 00001F4E 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1384 00001F50 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1385 00001F55 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1386 00001F57 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1387                              <1> RWV:
  1388 00001F5D 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1389 00001F5F 8AB7[4DD30000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1390 00001F65 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1391 00001F68 E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  1392                              <1> 	;;20/02/2015
  1393                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  1394 00001F6D 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1395 00001F6F 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1396 00001F71 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1397 00001F73 F687[4DD30000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1398 00001F7A 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1399 00001F7C B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1400 00001F7E EB0F                <1> 	JMP	SHORT RWV_2
  1401                              <1> RWV_1:
  1402 00001F80 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1403 00001F82 F687[4DD30000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1404 00001F89 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1405 00001F8B B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1406 00001F8D EB04                <1> 	jmp	short rwv_3
  1407                              <1> RWV_2:
  1408 00001F8F 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1409 00001F91 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1410                              <1> rwv_3:
  1411 00001F93 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1412 00001F98 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  1413                              <1> 
  1414                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  1415                              <1> 
  1416 00001F9A 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1417 00001F9B 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1418 00001F9D B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1419                              <1> RWV_DR_SEARCH:
  1420 00001FA2 8AA3[3ECD0000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1421 00001FA8 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1422 00001FAB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1423 00001FAD 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1424                              <1> RWV_DR_FND:
  1425 00001FAF 8BBB[3FCD0000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1426                              <1> RWV_MD_SEARH:
  1427 00001FB5 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1428 00001FB8 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  1429                              <1> RWV_NXT_MD:
  1430                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1431 00001FBA 83C305              <1> 	add	eBX, 5
  1432 00001FBD E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1433 00001FBF 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1434                              <1> 
  1435                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1436                              <1> 
  1437                              <1> RWV_ASSUME:
  1438 00001FC0 BB[5CCD0000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1439 00001FC5 F687[4DD30000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1440 00001FCC 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1441 00001FCE BB[76CD0000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1442 00001FD3 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  1443                              <1> 
  1444                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  1445                              <1> 	 			
  1446                              <1> RWV_MD_FND:
  1447 00001FD5 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1448 00001FD7 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1449                              <1> 	
  1450                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  1451                              <1> 
  1452                              <1> RWV_MD_FND1:
  1453 00001FD8 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1454 00001FDD E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1455 00001FE2 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1456 00001FE4 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1457                              <1> RWV_DBL:
  1458 00001FE9 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1459 00001FEA E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1460 00001FEF 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1461 00001FF0 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1462 00001FF2 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1463 00001FF4 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1464 00001FF6 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1465 00001FF7 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1466 00001FFC 5B                  <1> 	POP	eBX 
  1467 00001FFD 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1468 00001FFF 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1469 00002001 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1470 00002003 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1471 00002004 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1472 00002009 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1473 0000200A 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1474 0000200C E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1475 00002011 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1476 00002013 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1477                              <1> CHK_RET:
  1478 00002018 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1479 0000201D 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1480 0000201F 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1481 00002021 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1482                              <1> RWV_END:
  1483 00002026 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1484 0000202B E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1485                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1486 00002030 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1487 00002032 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1488 00002037 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1489 00002039 E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1490 0000203E C3                  <1> 	RETn
  1491                              <1> 
  1492                              <1> ;-------------------------------------------------------------------------------
  1493                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1494                              <1> ;-------------------------------------------------------------------------------
  1495                              <1> SETUP_STATE:
  1496 0000203F F687[4DD30000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1497 00002046 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1498 00002048 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1499 0000204C F687[4DD30000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1500 00002053 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1501 00002055 F687[4DD30000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1502 0000205C 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1503 0000205E 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1504                              <1> AX_SET:	
  1505 00002062 80A7[4DD30000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1506 00002069 08A7[4DD30000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1507 0000206F 8025[48D30000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1508 00002076 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1509 00002079 0805[48D30000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1510                              <1> J1C:	
  1511 0000207F C3                  <1> 	RETn
  1512                              <1> 
  1513                              <1> ;-------------------------------------------------------------------------------
  1514                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  1515                              <1> ;-------------------------------------------------------------------------------
  1516                              <1> FMT_INIT:
  1517 00002080 F687[4DD30000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1518 00002087 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1519 00002089 E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  1520                              <1> 	;; 20/02/2015
  1521                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  1522 0000208E 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1523 00002090 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1524                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1525 00002092 8AA7[4DD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1526 00002098 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1527 0000209B 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1528 0000209D 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1529 0000209F 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1530 000020A2 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1531                              <1> N_360:	
  1532 000020A4 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1533 000020A6 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1534                              <1> F1_RATE:
  1535 000020A8 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1536 000020AB EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1537                              <1> N_12:	
  1538 000020AD FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1539 000020AF 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1540 000020B1 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1541 000020B4 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1542 000020B6 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1543 000020B9 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1544 000020BB 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1545 000020BE EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1546                              <1> N_720:
  1547 000020C0 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1548 000020C2 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1549 000020C4 EBE2                <1> 	JMP	SHORT F1_RATE
  1550                              <1> ISNT_12: 
  1551 000020C6 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1552                              <1> 
  1553                              <1> SKP_STATE:
  1554 000020C9 88A7[4DD30000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1555                              <1> F1_OUT:
  1556 000020CF C3                  <1> 	RETn
  1557                              <1> CL_DRV:	
  1558 000020D0 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1559 000020D2 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  1560                              <1> 
  1561                              <1> ;-------------------------------------------------------------------------------
  1562                              <1> ; MED_CHANGE	
  1563                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  1564                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  1565                              <1> ;
  1566                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  1567                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  1568                              <1> ;-------------------------------------------------------------------------------
  1569                              <1> MED_CHANGE:
  1570 000020D4 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1571 000020D9 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1572 000020DB 80A7[4DD30000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  1573                              <1> 
  1574                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  1575                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  1576                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  1577                              <1> 
  1578 000020E2 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1579 000020E5 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1580 000020E7 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1581 000020E9 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1582 000020EB FA                  <1> 	CLI				; NO INTERRUPTS
  1583 000020EC 2005[3ED30000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1584 000020F2 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1585 000020F3 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  1586                              <1> 
  1587                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  1588                              <1> 
  1589 000020F8 E86DF9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1590 000020FD B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1591 000020FF E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1592 00002104 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1593 00002106 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1594 0000210B C605[40D30000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1595                              <1> OK1:
  1596 00002112 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1597 00002117 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1598                              <1> OK4:
  1599 00002119 C605[40D30000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1600                              <1> OK2:		
  1601 00002120 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1602 00002121 C3                  <1> 	RETn
  1603                              <1> MC_OUT:
  1604 00002122 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1605 00002123 C3                  <1> 	RETn
  1606                              <1> 
  1607                              <1> ;-------------------------------------------------------------------------------
  1608                              <1> ; SEND_RATE
  1609                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  1610                              <1> ; ON ENTRY:	DI = DRIVE #
  1611                              <1> ; ON EXIT:	NONE
  1612                              <1> ; REGISTERS ALTERED: DX
  1613                              <1> ;-------------------------------------------------------------------------------
  1614                              <1> SEND_RATE:
  1615 00002124 6650                <1> 	PUSH	AX			; SAVE REG.
  1616 00002126 8025[48D30000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1617 0000212D 8A87[4DD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1618 00002133 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1619 00002135 0805[48D30000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1620 0000213B C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1621 0000213E 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1622 00002142 EE                  <1> 	OUT	DX,AL
  1623 00002143 6658                <1> 	POP	AX			; RESTORE REG.
  1624 00002145 C3                  <1> 	RETn
  1625                              <1> 
  1626                              <1> ;-------------------------------------------------------------------------------
  1627                              <1> ; CHK_LASTRATE
  1628                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  1629                              <1> ; ON ENTRY:
  1630                              <1> ;	DI = DRIVE #
  1631                              <1> ; ON EXIT:
  1632                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  1633                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  1634                              <1> ; REGISTERS ALTERED: DX
  1635                              <1> ;-------------------------------------------------------------------------------
  1636                              <1> CHK_LASTRATE:
  1637 00002146 6650                <1> 	PUSH	AX			; SAVE REG
  1638 00002148 2225[48D30000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1639 0000214E 8A87[4DD30000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1640 00002154 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1641 00002158 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1642                              <1> 					; ZF = 1 RATE IS THE SAME
  1643 0000215A 6658                <1> 	POP	AX			; RESTORE REG.
  1644 0000215C C3                  <1> 	RETn
  1645                              <1> 
  1646                              <1> ;-------------------------------------------------------------------------------
  1647                              <1> ; DMA_SETUP
  1648                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  1649                              <1> ;
  1650                              <1> ; ON ENTRY:	AL = DMA COMMAND
  1651                              <1> ;
  1652                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1653                              <1> ;-------------------------------------------------------------------------------
  1654                              <1> 
  1655                              <1> ; SI = Head #, # of Sectors or DASD Type
  1656                              <1> 
  1657                              <1> ; 22/08/2015
  1658                              <1> ; 08/02/2015 - Protected Mode Modification
  1659                              <1> ; 06/02/2015 - 07/02/2015
  1660                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  1661                              <1> ; (DMA Addres = Physical Address)
  1662                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  1663                              <1> ;
  1664                              <1> 
  1665                              <1> 
  1666                              <1> ; 04/02/2016 (clc)
  1667                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  1668                              <1> ; 16/12/2014 (IODELAY)
  1669                              <1> 
  1670                              <1> DMA_SETUP:
  1671                              <1> 
  1672                              <1> ;; 20/02/2015
  1673 0000215D 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1674 00002160 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1675 00002166 756E                <1> 	jnz	short dma_bnd_err_stc
  1676                              <1> 	;
  1677 00002168 6650                <1> 	push	ax			; DMA command
  1678 0000216A 52                  <1> 	push	edx			; *
  1679 0000216B B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1680 0000216D E851030000          <1> 	call	GET_PARM		; 
  1681 00002172 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1682 00002174 6689F0              <1> 	mov	ax, si			; Sector count
  1683 00002177 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1684 00002179 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1685 0000217B 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1686 0000217E 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1687 00002181 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1688 00002183 6689C1              <1> 	mov	cx, ax
  1689 00002186 5A                  <1> 	pop	edx			; *
  1690 00002187 6658                <1> 	pop	ax
  1691 00002189 3C42                <1> 	cmp	al, 42h
  1692 0000218B 7507                <1>         jne     short NOT_VERF
  1693 0000218D BA0000FF00          <1> 	mov	edx, 0FF0000h
  1694 00002192 EB08                <1> 	jmp	short J33
  1695                              <1> NOT_VERF:
  1696 00002194 6601CA              <1> 	add	dx, cx			; check for overflow
  1697 00002197 723E                <1> 	jc	short dma_bnd_err
  1698                              <1> 	;
  1699 00002199 6629CA              <1> 	sub	dx, cx			; Restore start address
  1700                              <1> J33:
  1701 0000219C FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1702 0000219D E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1703                              <1> 	IODELAY				; WAIT FOR I/O
  1703 0000219F EB00                <2>  jmp short $+2
  1703 000021A1 EB00                <2>  jmp short $+2
  1704 000021A3 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1705 000021A5 89D0                <1> 	mov	eax, edx		; Buffer address
  1706 000021A7 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1707                              <1> 	IODELAY				; WAIT FOR I/O
  1707 000021A9 EB00                <2>  jmp short $+2
  1707 000021AB EB00                <2>  jmp short $+2
  1708 000021AD 88E0                <1> 	MOV	AL,AH
  1709 000021AF E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1710 000021B1 C1E810              <1> 	shr	eax, 16
  1711                              <1> 	IODELAY				; I/O WAIT STATE
  1711 000021B4 EB00                <2>  jmp short $+2
  1711 000021B6 EB00                <2>  jmp short $+2
  1712 000021B8 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1713                              <1> 	IODELAY
  1713 000021BA EB00                <2>  jmp short $+2
  1713 000021BC EB00                <2>  jmp short $+2
  1714 000021BE 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1715 000021C1 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1716                              <1> 	IODELAY				; WAIT FOR I/O
  1716 000021C3 EB00                <2>  jmp short $+2
  1716 000021C5 EB00                <2>  jmp short $+2
  1717 000021C7 88E0                <1> 	MOV	AL, AH
  1718 000021C9 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1719                              <1> 	IODELAY
  1719 000021CB EB00                <2>  jmp short $+2
  1719 000021CD EB00                <2>  jmp short $+2
  1720 000021CF FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1721 000021D0 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1722 000021D2 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1723                              <1> 
  1724 000021D4 F8                  <1> 	clc	; 04/02/2016
  1725 000021D5 C3                  <1> 	retn
  1726                              <1> 
  1727                              <1> dma_bnd_err_stc:
  1728 000021D6 F9                  <1> 	stc
  1729                              <1> dma_bnd_err:
  1730 000021D7 C605[40D30000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1731 000021DE C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  1732                              <1> 
  1733                              <1> ;; 16/12/2014
  1734                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1735                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1736                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1737                              <1> ;;	IODELAY
  1738                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1739                              <1> ;;	;SIODELAY
  1740                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  1741                              <1> ;;      ;JNE	short NOT_VERF		; NO
  1742                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  1743                              <1> ;;      ;JMP	SHORT J33
  1744                              <1> ;;;NOT_VERF:	
  1745                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1746                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1747                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1748                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1749                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1750                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  1751                              <1> ;;	;JNC	short J33
  1752                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1753                              <1> ;;;J33:
  1754                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  1755                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1756                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1757                              <1> ;;	IODELAY
  1758                              <1> ;;	MOV	AL,AH
  1759                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1760                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  1761                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1762                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1763                              <1> ;;	IODELAY
  1764                              <1> ;;	;AND	AL,00001111B
  1765                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1766                              <1> ;;	;SIODELAY
  1767                              <1> ;;
  1768                              <1> ;;;----- DETERMINE COUNT
  1769                              <1> ;;	sub	eax, eax ; 08/02/2015
  1770                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  1771                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  1772                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  1773                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  1774                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  1775                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  1776                              <1> ;;	CALL	GET_PARM		; "
  1777                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1778                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  1779                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  1780                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1781                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  1782                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1783                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1784                              <1> ;;	IODELAY
  1785                              <1> ;;	MOV	AL, AH
  1786                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1787                              <1> ;;	;IODELAY
  1788                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1789                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  1790                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  1791                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1792                              <1> ;;	add	ecx, eax ; 08/02/2015
  1793                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1794                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1795                              <1> ;;	SIODELAY
  1796                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1797                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  1798                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  1799                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  1800                              <1> ;;	jz	short NO_BAD
  1801                              <1> ;;dma_bnd_err:
  1802                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1803                              <1> ;;NO_BAD:
  1804                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1805                              <1> 
  1806                              <1> ;-------------------------------------------------------------------------------
  1807                              <1> ; FMTDMA_SET
  1808                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  1809                              <1> ;
  1810                              <1> ; ON ENTRY:	NOTHING REQUIRED
  1811                              <1> ;
  1812                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1813                              <1> ;-------------------------------------------------------------------------------
  1814                              <1> 
  1815                              <1> FMTDMA_SET:
  1816                              <1> ;; 20/02/2015 modification	
  1817 000021DF 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1818 000021E2 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1819 000021E8 75EC                <1> 	jnz	short dma_bnd_err_stc
  1820                              <1> 	;
  1821 000021EA 6652                <1> 	push	dx			; *
  1822 000021EC B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1823 000021EE E8D0020000          <1> 	call	GET_PARM		; "
  1824 000021F3 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1825 000021F5 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1826 000021F7 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1827 000021FB 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1828 000021FD 6689C1              <1> 	mov	cx, ax
  1829 00002200 665A                <1> 	pop	dx			; *
  1830 00002202 6601CA              <1> 	add	dx, cx			; check for overflow
  1831 00002205 72D0                <1> 	jc	short dma_bnd_err
  1832                              <1> 	;
  1833 00002207 6629CA              <1> 	sub	dx, cx			; Restore start address
  1834                              <1> 	;
  1835 0000220A B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1836 0000220C FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1837 0000220D E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1838                              <1> 	IODELAY				; WAIT FOR I/O
  1838 0000220F EB00                <2>  jmp short $+2
  1838 00002211 EB00                <2>  jmp short $+2
  1839 00002213 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1840 00002215 89D0                <1> 	mov	eax, edx		; Buffer address
  1841 00002217 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1842                              <1> 	IODELAY				; WAIT FOR I/O
  1842 00002219 EB00                <2>  jmp short $+2
  1842 0000221B EB00                <2>  jmp short $+2
  1843 0000221D 88E0                <1> 	MOV	AL,AH
  1844 0000221F E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1845 00002221 C1E810              <1> 	shr	eax, 16
  1846                              <1> 	IODELAY				; I/O WAIT STATE
  1846 00002224 EB00                <2>  jmp short $+2
  1846 00002226 EB00                <2>  jmp short $+2
  1847 00002228 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1848                              <1> 	IODELAY
  1848 0000222A EB00                <2>  jmp short $+2
  1848 0000222C EB00                <2>  jmp short $+2
  1849 0000222E 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1850 00002231 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1851                              <1> 	IODELAY				; WAIT FOR I/O
  1851 00002233 EB00                <2>  jmp short $+2
  1851 00002235 EB00                <2>  jmp short $+2
  1852 00002237 88E0                <1> 	MOV	AL, AH
  1853 00002239 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1854                              <1> 	IODELAY
  1854 0000223B EB00                <2>  jmp short $+2
  1854 0000223D EB00                <2>  jmp short $+2
  1855 0000223F FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1856 00002240 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1857 00002242 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1858 00002244 C3                  <1> 	retn
  1859                              <1> 
  1860                              <1> ;; 08/02/2015 - Protected Mode Modification
  1861                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1862                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1863                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1864                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1865                              <1> ;;	IODELAY
  1866                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1867                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1868                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1869                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1870                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1871                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1872                              <1> ;;	;JNC	short J33A
  1873                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1874                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  1875                              <1> ;;;J33A:
  1876                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  1877                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1878                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1879                              <1> ;;	IODELAY
  1880                              <1> ;;	MOV	AL,AH
  1881                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1882                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  1883                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1884                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1885                              <1> ;;	IODELAY
  1886                              <1> ;;	;AND	AL,00001111B
  1887                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1888                              <1> ;;
  1889                              <1> ;;;----- DETERMINE COUNT
  1890                              <1> ;;	sub	eax, eax ; 08/02/2015
  1891                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1892                              <1> ;;	CALL	GET_PARM		; "
  1893                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  1894                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  1895                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1896                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1897                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  1898                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1899                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1900                              <1> ;;	IODELAY
  1901                              <1> ;;	MOV	AL, AH
  1902                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1903                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1904                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  1905                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  1906                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1907                              <1> ;;	add	ecx, eax ; 08/02/2015
  1908                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1909                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1910                              <1> ;;	SIODELAY
  1911                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1912                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  1913                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  1914                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  1915                              <1> ;;	jz	short FMTDMA_OK
  1916                              <1> ;;	stc	; 20/02/2015
  1917                              <1> ;;fmtdma_bnd_err:
  1918                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1919                              <1> ;;FMTDMA_OK:
  1920                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1921                              <1> 
  1922                              <1> ;-------------------------------------------------------------------------------
  1923                              <1> ; NEC_INIT	
  1924                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  1925                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  1926                              <1> ;
  1927                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  1928                              <1> ;
  1929                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1930                              <1> ;-------------------------------------------------------------------------------
  1931                              <1> NEC_INIT:
  1932 00002245 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1933 00002247 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1934                              <1> 
  1935                              <1> ;-----	DO THE SEEK OPERATION
  1936                              <1> 
  1937 0000224C 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1938 0000224F E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1939 00002254 6658                <1> 	POP	AX			; RECOVER COMMAND
  1940 00002256 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1941 00002258 BB[76220000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1942 0000225D 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1943                              <1> 
  1944                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1945                              <1> 
  1946 0000225E E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1947 00002263 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1948 00002266 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1949 00002268 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1950 0000226B 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1951 0000226E 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1952 00002270 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1953 00002275 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1954                              <1> ER_1:
  1955 00002276 C3                  <1> 	RETn
  1956                              <1> 
  1957                              <1> ;-------------------------------------------------------------------------------
  1958                              <1> ; RWV_COM
  1959                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  1960                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  1961                              <1> ;
  1962                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  1963                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1964                              <1> ;-------------------------------------------------------------------------------
  1965                              <1> RWV_COM:
  1966 00002277 B8[C2220000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1967 0000227C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1968 0000227D 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1969 00002280 E844030000          <1> 	CALL	NEC_OUTPUT
  1970 00002285 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  1971 00002288 E83C030000          <1> 	CALL	NEC_OUTPUT
  1972 0000228D 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  1973 00002290 E834030000          <1> 	CALL	NEC_OUTPUT
  1974 00002295 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  1975 00002297 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1976 0000229C E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1977 000022A1 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  1978 000022A3 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1979 000022A8 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1980 000022AD 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  1981                              <1> _R15:
  1982 000022B0 E814030000          <1> 	CALL	NEC_OUTPUT
  1983 000022B5 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  1984 000022B7 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  1985 000022BC E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1986 000022C1 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  1987                              <1> ER_2:
  1988 000022C2 C3                  <1> 	RETn
  1989                              <1> 
  1990                              <1> ;-------------------------------------------------------------------------------
  1991                              <1> ; NEC_TERM
  1992                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  1993                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  1994                              <1> ;
  1995                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1996                              <1> ;-------------------------------------------------------------------------------
  1997                              <1> NEC_TERM:
  1998                              <1> 
  1999                              <1> ;-----	LET THE OPERATION HAPPEN
  2000                              <1> 
  2001 000022C3 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  2002 000022C4 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2003 000022C9 9C                  <1> 	PUSHF
  2004 000022CA E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  2005 000022CF 724B                <1> 	JC	short SET_END_POP
  2006 000022D1 9D                  <1> 	POPF
  2007 000022D2 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  2008                              <1> 
  2009                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  2010                              <1> 
  2011 000022D4 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  2012 000022D5 BE[41D30000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  2013 000022DA AC                  <1> 	lodsb				; GET ST0
  2014 000022DB 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  2015 000022DD 7433                <1> 	JZ	short SET_END
  2016 000022DF 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  2017 000022E1 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  2018                              <1> 
  2019                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  2020                              <1> 
  2021 000022E3 AC                  <1> 	lodsb				; GET ST1
  2022 000022E4 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  2023 000022E6 B404                <1> 	MOV	AH,RECORD_NOT_FND
  2024 000022E8 7222                <1> 	JC	short J19
  2025 000022EA C0E002              <1> 	SAL	AL,2
  2026 000022ED B410                <1> 	MOV	AH,BAD_CRC
  2027 000022EF 721B                <1> 	JC	short J19
  2028 000022F1 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  2029 000022F3 B408                <1> 	MOV	AH,BAD_DMA
  2030 000022F5 7215                <1> 	JC	short J19
  2031 000022F7 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2032 000022FA B404                <1> 	MOV	AH,RECORD_NOT_FND
  2033 000022FC 720E                <1> 	JC	short J19
  2034 000022FE D0E0                <1> 	SAL	AL,1
  2035 00002300 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2036 00002302 7208                <1> 	JC	short J19
  2037 00002304 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2038 00002306 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2039 00002308 7202                <1> 	JC	short J19
  2040                              <1> 
  2041                              <1> ;----- 	NEC MUST HAVE FAILED
  2042                              <1> J18:
  2043 0000230A B420                <1> 	MOV	AH,BAD_NEC
  2044                              <1> J19:
  2045 0000230C 0825[40D30000]      <1> 	OR	[DSKETTE_STATUS], AH
  2046                              <1> SET_END:
  2047 00002312 803D[40D30000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2048 00002319 F5                  <1> 	CMC
  2049 0000231A 5E                  <1> 	POP	eSI
  2050 0000231B C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2051                              <1> 
  2052                              <1> SET_END_POP:
  2053 0000231C 9D                  <1> 	POPF
  2054 0000231D EBF3                <1> 	JMP	SHORT SET_END
  2055                              <1> 
  2056                              <1> ;-------------------------------------------------------------------------------
  2057                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2058                              <1> ;-------------------------------------------------------------------------------
  2059                              <1> DSTATE:
  2060 0000231F 803D[40D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2061 00002326 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2062 00002328 808F[4DD30000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2063 0000232F F687[4DD30000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2064 00002336 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2065 00002338 8A87[4DD30000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2066 0000233E 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2067 00002340 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2068 00002342 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  2069                              <1> 
  2070                              <1> ;----- 	CHECK IF IT IS 1.44M
  2071                              <1> 
  2072 00002344 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2073                              <1> 	;;20/02/2015
  2074                              <1> 	;;JC	short M_12		; CMOS BAD
  2075 00002349 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2076 0000234B 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2077 0000234D 7410                <1> 	JE	short M_12		; YES
  2078                              <1> M_720:
  2079 0000234F 80A7[4DD30000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2080 00002356 808F[4DD30000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2081 0000235D EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2082                              <1> M_12:	
  2083 0000235F 808F[4DD30000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2084                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2085                              <1> SETBAC:
  2086 00002366 C3                  <1> 	RETn
  2087                              <1> 
  2088                              <1> ;-------------------------------------------------------------------------------
  2089                              <1> ; RETRY	
  2090                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  2091                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  2092                              <1> ;
  2093                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  2094                              <1> ;-------------------------------------------------------------------------------
  2095                              <1> RETRY:
  2096 00002367 803D[40D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2097 0000236E 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2098 00002370 803D[40D30000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2099 00002377 743C                <1> 	JZ	short NO_RETRY
  2100 00002379 8AA7[4DD30000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2101 0000237F F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2102 00002382 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2103 00002384 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2104 00002387 8A2D[48D30000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2105 0000238D C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2106 00002390 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2107 00002393 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2108 00002395 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  2109                              <1> 
  2110                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  2111                              <1> ;	 00000000B (500) -> 10000000B	(250)
  2112                              <1> ;	 10000000B (250) -> 01000000B	(300)
  2113                              <1> ;	 01000000B (300) -> 00000000B	(500)
  2114                              <1> 
  2115 00002397 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2116 0000239A D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2117 0000239C 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2118 0000239F 80A7[4DD30000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2119                              <1> 					; RATE, DBL STEP OFF
  2120 000023A6 08A7[4DD30000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2121 000023AC C605[40D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2122 000023B3 F9                  <1> 	STC				; SET CARRY FOR RETRY
  2123 000023B4 C3                  <1> 	RETn				; RETRY RETURN
  2124                              <1> 
  2125                              <1> NO_RETRY:
  2126 000023B5 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2127 000023B6 C3                  <1> 	RETn				; NO RETRY RETURN
  2128                              <1> 
  2129                              <1> ;-------------------------------------------------------------------------------
  2130                              <1> ; NUM_TRANS
  2131                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  2132                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  2133                              <1> ;
  2134                              <1> ; ON ENTRY:	[BP+1] = TRACK
  2135                              <1> ;		SI-HI  = HEAD
  2136                              <1> ;		[BP]   = START SECTOR
  2137                              <1> ;
  2138                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  2139                              <1> ;-------------------------------------------------------------------------------
  2140                              <1> NUM_TRANS:
  2141 000023B7 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2142 000023B9 803D[40D30000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2143 000023C0 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2144 000023C2 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2145 000023C4 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2146 000023C9 8A1D[46D30000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2147 000023CF 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2148 000023D2 3A2D[45D30000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2149 000023D8 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2150 000023DA 8A2D[44D30000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2151 000023E0 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2152 000023E3 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2153 000023E5 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2154                              <1> DIF_HD:
  2155 000023E7 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2156                              <1> SAME_TRK:
  2157 000023E9 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2158 000023EC 88D8                <1> 	MOV	AL,BL			; TO AL
  2159                              <1> NT_OUT:
  2160 000023EE C3                  <1> 	RETn
  2161                              <1> 
  2162                              <1> ;-------------------------------------------------------------------------------
  2163                              <1> ; SETUP_END
  2164                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2165                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2166                              <1> ;
  2167                              <1> ; ON EXIT:
  2168                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2169                              <1> ;-------------------------------------------------------------------------------
  2170                              <1> SETUP_END:
  2171 000023EF B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2172 000023F1 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2173 000023F3 E8CB000000          <1> 	CALL	GET_PARM
  2174 000023F8 8825[3FD30000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2175 000023FE 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2176 00002400 8A25[40D30000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2177 00002406 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2178 00002408 7402                <1> 	JZ	short NUN_ERR		; NO ERROR
  2179 0000240A 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2180                              <1> NUN_ERR: 
  2181 0000240C 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2182 0000240F F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2183 00002410 C3                  <1> 	RETn
  2184                              <1> 
  2185                              <1> ;-------------------------------------------------------------------------------
  2186                              <1> ; SETUP_DBL
  2187                              <1> ;	CHECK DOUBLE STEP.
  2188                              <1> ;
  2189                              <1> ; ON ENTRY :	DI = DRIVE
  2190                              <1> ;
  2191                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  2192                              <1> ;-------------------------------------------------------------------------------
  2193                              <1> SETUP_DBL:
  2194 00002411 8AA7[4DD30000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2195 00002417 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2196 0000241A 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  2197                              <1> 
  2198                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  2199                              <1> 
  2200 0000241C C605[3DD30000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2201 00002423 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2202 00002428 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2203 0000242A E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2204 0000242F E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2205 00002434 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  2206                              <1> 
  2207                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  2208                              <1> 
  2209 00002436 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2210 0000243A F687[4DD30000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2211 00002441 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2212 00002443 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  2213                              <1> 
  2214                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  2215                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  2216                              <1> ;	THEN SET DOUBLE STEP ON.
  2217                              <1> 
  2218                              <1> CNT_OK:
  2219 00002445 C605[3FD30000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2220 0000244C 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2221 0000244E C605[40D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2222 00002455 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2223 00002458 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2224 0000245A C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2225 0000245D 6650                <1> 	PUSH	AX			; SAVE HEAD
  2226 0000245F E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2227 00002464 6658                <1> 	POP	AX			; RESTORE HEAD
  2228 00002466 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2229 00002469 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2230 0000246E 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2231 0000246F 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2232 00002474 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2233 00002475 6659                <1> 	POP	CX			; RESTORE COUNT
  2234 00002477 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2235 00002479 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2236 0000247B 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2237 0000247D 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  2238                              <1> 
  2239                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  2240                              <1> 
  2241                              <1> SD_ERR:	
  2242 0000247F F9                  <1> 	STC				; SET CARRY FOR ERROR
  2243 00002480 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2244                              <1> 
  2245                              <1> DO_CHK:
  2246 00002481 8A0D[44D30000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2247 00002487 888F[51D30000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2248 0000248D D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2249 0000248F 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2250 00002491 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2251 00002493 808F[4DD30000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2252                              <1> NO_DBL:
  2253 0000249A F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2254 0000249B C3                  <1> 	RETn
  2255                              <1> 
  2256                              <1> ;-------------------------------------------------------------------------------
  2257                              <1> ; READ_ID
  2258                              <1> ;	READ ID FUNCTION.
  2259                              <1> ;
  2260                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  2261                              <1> ;
  2262                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  2263                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2264                              <1> ;-------------------------------------------------------------------------------
  2265                              <1> READ_ID:
  2266 0000249C B8[B9240000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2267 000024A1 50                  <1> 	PUSH	eAX
  2268 000024A2 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2269 000024A4 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2270 000024A9 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2271 000024AC 88C4                <1> 	MOV	AH,AL
  2272 000024AE E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2273 000024B3 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2274 000024B8 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2275                              <1> ER_3:
  2276 000024B9 C3                  <1> 	RETn
  2277                              <1> 
  2278                              <1> ;-------------------------------------------------------------------------------
  2279                              <1> ; CMOS_TYPE
  2280                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  2281                              <1> ;
  2282                              <1> ; ON ENTRY:	DI = DRIVE #
  2283                              <1> ;
  2284                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  2285                              <1> ;-------------------------------------------------------------------------------
  2286                              <1> 
  2287                              <1> CMOS_TYPE: ; 11/12/2014
  2288 000024BA 8A87[C0CD0000]      <1> mov	al, [eDI+fd0_type]
  2289 000024C0 20C0                <1> and 	al, al ; 18/12/2014
  2290 000024C2 C3                  <1> retn
  2291                              <1> 
  2292                              <1> ;CMOS_TYPE:
  2293                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  2294                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  2295                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  2296                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  2297                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  2298                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  2299                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  2300                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  2301                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  2302                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  2303                              <1> ;TB:
  2304                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  2305                              <1> ;BAD_CM:
  2306                              <1> ;	RETn				; CY, STATUS OF READ
  2307                              <1> 
  2308                              <1> ;-------------------------------------------------------------------------------
  2309                              <1> ; GET_PARM
  2310                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  2311                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  2312                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  2313                              <1> ;	THE PARAMETER IN DL.
  2314                              <1> ;
  2315                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  2316                              <1> ;
  2317                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  2318                              <1> ;		AL,DH DESTROYED
  2319                              <1> ;-------------------------------------------------------------------------------
  2320                              <1> GET_PARM:
  2321                              <1> 	;PUSH	DS
  2322 000024C3 56                  <1> 	PUSH	eSI
  2323                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  2324                              <1>     	;MOV	DS,AX
  2325                              <1> 	;;mov	ax, cs
  2326                              <1> 	;;mov	ds, ax
  2327                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  2328 000024C4 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2329                              <1> 	;SUB	BH,BH			; BX = INDEX
  2330 000024C6 81E3FF000000        <1> 	and	ebx, 0FFh
  2331                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2332                              <1> 	;
  2333                              <1> 	; 17/12/2014
  2334 000024CC 66A1[B3CD0000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2335 000024D2 38E0                <1> 	cmp	al, ah
  2336 000024D4 7425                <1> 	je	short gpndc
  2337 000024D6 A2[B4CD0000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2338 000024DB 53                  <1> 	push	ebx ; 08/02/2015
  2339 000024DC 88C3                <1> 	mov	bl, al 
  2340                              <1> 	; 11/12/2014
  2341 000024DE 8A83[C0CD0000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2342                              <1> 	; 18/12/2014
  2343 000024E4 20C0                <1> 	and	al, al
  2344 000024E6 7507                <1> 	jnz	short gpdtc
  2345 000024E8 BB[9DCD0000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2346 000024ED EB05                <1>         jmp     short gpdpu
  2347                              <1> gpdtc:	
  2348 000024EF E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2349                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2350                              <1> gpdpu:
  2351 000024F4 891D[3ACD0000]      <1> 	mov	[DISK_POINTER], ebx
  2352 000024FA 5B                  <1> 	pop	ebx
  2353                              <1> gpndc:
  2354 000024FB 8B35[3ACD0000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2355 00002501 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2356 00002504 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2357 00002506 5E                  <1> 	POP	eSI
  2358                              <1> 	;POP	DS
  2359 00002507 C3                  <1> 	RETn
  2360                              <1> 
  2361                              <1> ;-------------------------------------------------------------------------------
  2362                              <1> ; MOTOR_ON
  2363                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  2364                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  2365                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  2366                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  2367                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  2368                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  2369                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  2370                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  2371                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  2372                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  2373                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  2374                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  2375                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  2376                              <1> ;
  2377                              <1> ; ON ENTRY:	DI = DRIVE #
  2378                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  2379                              <1> ;-------------------------------------------------------------------------------
  2380                              <1> MOTOR_ON:
  2381 00002508 53                  <1> 	PUSH	eBX			; SAVE REG.
  2382 00002509 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2383 0000250E 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2384 00002510 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2385 00002515 E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  2386                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  2387                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  2388                              <1> M_WAIT:
  2389 0000251A B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2390 0000251C E8A2FFFFFF          <1> 	CALL	GET_PARM
  2391                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  2392                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  2393                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  2394 00002521 80FC08              <1> 	cmp	ah, 8
  2395                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2396 00002524 7702                <1> 	ja	short J13
  2397                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2398 00002526 B408                <1> 	mov	ah, 8
  2399                              <1> 
  2400                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  2401                              <1> GP2:	
  2402                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  2403                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  2404 00002528 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2405 0000252D E800F3FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2406                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2407 00002532 FECC                <1> 	dec	ah
  2408 00002534 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2409                              <1> MOT_IS_ON:
  2410 00002536 5B                  <1> 	POP	eBX			; RESTORE REG.
  2411 00002537 C3                  <1> 	RETn
  2412                              <1> 
  2413                              <1> ;-------------------------------------------------------------------------------
  2414                              <1> ; TURN_ON
  2415                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  2416                              <1> ;
  2417                              <1> ; ON ENTRY:	DI = DRIVE #
  2418                              <1> ;
  2419                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  2420                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  2421                              <1> ;		AX,BX,CX,DX DESTROYED
  2422                              <1> ;-------------------------------------------------------------------------------
  2423                              <1> TURN_ON:
  2424 00002538 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2425 0000253A 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2426 0000253C C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2427 0000253F FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2428 00002540 C605[3FD30000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2429 00002547 A0[3ED30000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2430 0000254C 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2431 0000254E B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2432 00002550 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  2433                              <1> 
  2434                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  2435                              <1> ;  BL = DRIVE SELECT DESIRED
  2436                              <1> ;  AH = MOTOR ON MASK DESIRED
  2437                              <1> 
  2438 00002552 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2439 00002554 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2440 00002556 8425[3ED30000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2441 0000255C 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2442                              <1> 
  2443                              <1> TURN_IT_ON:
  2444 0000255E 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2445 00002560 8A3D[3ED30000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2446 00002566 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2447 00002569 8025[3ED30000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2448 00002570 0825[3ED30000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2449 00002576 A0[3ED30000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2450 0000257B 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2451 0000257D 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2452 00002580 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2453 00002581 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2454 00002583 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2455 00002586 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2456 00002588 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2457 0000258C EE                  <1> 	OUT	DX,AL
  2458 0000258D 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2459                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2460 0000258F 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2461 00002591 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2462 00002592 C3                  <1> 	RETn
  2463                              <1> 
  2464                              <1> NO_MOT_WAIT:
  2465 00002593 FB                  <1> 	sti
  2466                              <1> no_mot_w1: ; 27/02/2015
  2467 00002594 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2468                              <1> 	;STI				; INTERRUPTS BACK ON
  2469 00002595 C3                  <1> 	RETn
  2470                              <1> 
  2471                              <1> ;-------------------------------------------------------------------------------
  2472                              <1> ; HD_WAIT
  2473                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  2474                              <1> ;
  2475                              <1> ; ON ENTRY:	DI = DRIVE #
  2476                              <1> ;
  2477                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  2478                              <1> ;-------------------------------------------------------------------------------
  2479                              <1> HD_WAIT:
  2480 00002596 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2481 00002598 E826FFFFFF          <1> 	CALL	GET_PARM
  2482 0000259D 08E4                <1> 	or	ah, ah	; 17/12/2014
  2483 0000259F 7519                <1> 	jnz	short DO_WAT
  2484 000025A1 F605[3ED30000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  2485                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  2486                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  2487                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  2488 000025A8 741E                <1> 	jz	short HW_DONE
  2489 000025AA B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2490 000025AC 8A87[4DD30000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2491 000025B2 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2492 000025B4 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2493 000025B6 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2494                              <1> ;GP3:
  2495 000025B8 B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  2496                              <1> ;	JMP	SHORT DO_WAT
  2497                              <1> 
  2498                              <1> ;ISNT_WRITE:
  2499                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  2500                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  2501                              <1> 
  2502                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  2503                              <1> DO_WAT:
  2504                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  2505                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  2506                              <1> J29:					; 	1 MILLISECOND LOOP
  2507                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  2508 000025BA B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2509 000025BF E86EF2FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2510                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2511 000025C4 FECC                <1> 	dec	ah
  2512 000025C6 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2513                              <1> HW_DONE:
  2514 000025C8 C3                  <1> 	RETn
  2515                              <1> 
  2516                              <1> ;-------------------------------------------------------------------------------
  2517                              <1> ; NEC_OUTPUT
  2518                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  2519                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  2520                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  2521                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  2522                              <1> ; 
  2523                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  2524                              <1> ;
  2525                              <1> ; ON EXIT:	CY = 0  SUCCESS
  2526                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  2527                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  2528                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  2529                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  2530                              <1> ;		AX,CX,DX DESTROYED
  2531                              <1> ;-------------------------------------------------------------------------------
  2532                              <1> 
  2533                              <1> ; 09/12/2014 [Erdogan Tan] 
  2534                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  2535                              <1> ; Diskette Drive Controller Status Register (3F4h)
  2536                              <1> ;	This read only register facilitates the transfer of data between
  2537                              <1> ;	the system microprocessor and the controller.
  2538                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  2539                              <1> ;	  with the system micrprocessor.
  2540                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  2541                              <1> ;	  the transfer is to the controller.
  2542                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  2543                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  2544                              <1> ; Bit 3 - Reserved.
  2545                              <1> ; Bit 2 - Reserved.
  2546                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2547                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2548                              <1> 
  2549                              <1> ; Data Register (3F5h)
  2550                              <1> ; This read/write register passes data, commands and parameters, and provides
  2551                              <1> ; diskette status information.
  2552                              <1>   		
  2553                              <1> NEC_OUTPUT:
  2554                              <1> 	;PUSH	BX			; SAVE REG.
  2555 000025C9 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2556                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  2557                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  2558                              <1> 	; 16/12/2014
  2559                              <1> 	; waiting for (max.) 0.5 seconds
  2560                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  2561                              <1> 	;
  2562                              <1> 	; 17/12/2014
  2563                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  2564                              <1> 	;
  2565                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  2566                              <1> 	;		go on.
  2567                              <1> 	;INPUT:
  2568                              <1> 	;	AH=Mask for isolation bits.
  2569                              <1> 	;	AL=pattern to look for.
  2570                              <1> 	;	DX=Port to test for
  2571                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2572                              <1> 	;	     (normally 30 microseconds per period.)
  2573                              <1> 	;
  2574                              <1> 	;WFP_SHORT:  
  2575                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  2576                              <1> 	;
  2577                              <1> 
  2578                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  2579                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  2580 000025CD B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  2581                              <1> ;
  2582                              <1> ;WFPS_OUTER_LP:
  2583                              <1> ;	;
  2584                              <1> ;WFPS_CHECK_PORT:
  2585                              <1> J23:
  2586 000025D2 EC                  <1> 	IN	AL,DX			; GET STATUS
  2587 000025D3 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2588 000025D5 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2589 000025D7 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2590                              <1> WFPS_HI:
  2591 000025D9 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2592 000025DB A810                <1> 	TEST	AL,010H			; transition on memory
  2593 000025DD 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2594                              <1> WFPS_LO:
  2595 000025DF E461                <1> 	IN	AL, PORT_B		; SYS1
  2596 000025E1 A810                <1> 	TEST	AL,010H
  2597 000025E3 74FA                <1> 	JZ	SHORT WFPS_LO
  2598                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2599 000025E5 E2EB                <1> 	loop	J23	; 27/02/2015
  2600                              <1> ;	;
  2601                              <1> ;	dec	bl
  2602                              <1> ;	jnz	short WFPS_OUTER_LP
  2603                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  2604                              <1> ;J23:
  2605                              <1> ;	IN	AL,DX			; GET STATUS
  2606                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2607                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2608                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  2609                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  2610                              <1> 	;DEC	BL			; DECREMENT COUNTER
  2611                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  2612                              <1>    
  2613                              <1> 	;;27/02/2015
  2614                              <1> 	;16/12/2014
  2615                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  2616                              <1> 	;;jb	short J23
  2617                              <1> 
  2618                              <1> ;WFPS_TIMEOUT:
  2619                              <1> 
  2620                              <1> ;-----	FALL THRU TO ERROR RETURN
  2621                              <1> 
  2622 000025E7 800D[40D30000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2623                              <1> 	;POP	BX			; RESTORE REG.
  2624 000025EE 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2625 000025EF F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2626 000025F0 C3                  <1> 	RETn
  2627                              <1> 
  2628                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2629                              <1> 
  2630                              <1> J27:	
  2631 000025F1 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2632 000025F3 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2633 000025F5 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2634                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2635                              <1> 	; 27/02/2015
  2636 000025F6 9C                  <1> 	PUSHF				; SAVE FLAGS
  2637 000025F7 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2638 000025FC E831F2FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2639 00002601 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2640                              <1> 	;POP	BX			; RESTORE REG
  2641 00002602 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  2642                              <1> 
  2643                              <1> ;-------------------------------------------------------------------------------
  2644                              <1> ; SEEK
  2645                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  2646                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  2647                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  2648                              <1> ;
  2649                              <1> ; ON ENTRY:	DI = DRIVE #
  2650                              <1> ;		CH = TRACK #
  2651                              <1> ;
  2652                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2653                              <1> ;		AX,BX,CX DX DESTROYED
  2654                              <1> ;-------------------------------------------------------------------------------
  2655                              <1> SEEK:
  2656 00002603 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2657 00002605 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2658 00002607 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2659 00002609 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2660 0000260B 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2661 0000260D 8405[3DD30000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2662 00002613 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2663                              <1> 
  2664 00002615 0805[3DD30000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2665 0000261B E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2666 00002620 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2667                              <1> 
  2668                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2669                              <1> 
  2670 00002622 C605[40D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2671 00002629 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2672 0000262E 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2673                              <1> 
  2674                              <1> AFT_RECAL:
  2675 00002630 C687[51D30000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2676 00002637 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2677 00002639 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  2678                              <1> 
  2679                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  2680                              <1> 
  2681 0000263B F687[4DD30000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2682 00002642 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2683 00002644 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2684                              <1> 
  2685 00002646 3AAF[51D30000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2686 0000264C 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2687                              <1> 
  2688 0000264E BA[81260000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2689 00002653 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2690 00002654 88AF[51D30000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2691 0000265A B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2692 0000265C E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2693 00002661 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2694 00002663 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2695 00002665 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2696 0000266A 8AA7[51D30000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2697 00002670 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2698 00002675 E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  2699                              <1> 
  2700                              <1> ;-----	WAIT FOR HEAD SETTLE
  2701                              <1> 
  2702                              <1> DO_WAIT:
  2703 0000267A 9C                  <1> 	PUSHF				; SAVE STATUS
  2704 0000267B E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2705 00002680 9D                  <1> 	POPF				; RESTORE STATUS
  2706                              <1> RB:
  2707                              <1> NEC_ERR:
  2708                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  2709                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  2710 00002681 C3                  <1> 	RETn				; RETURN TO CALLER
  2711                              <1> 
  2712                              <1> ;-------------------------------------------------------------------------------
  2713                              <1> ; RECAL
  2714                              <1> ;	RECALIBRATE DRIVE
  2715                              <1> ;
  2716                              <1> ; ON ENTRY:	DI = DRIVE #
  2717                              <1> ;
  2718                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  2719                              <1> ;-------------------------------------------------------------------------------
  2720                              <1> RECAL:
  2721 00002682 6651                <1> 	PUSH	CX
  2722 00002684 B8[A0260000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2723 00002689 50                  <1> 	PUSH	eAX
  2724 0000268A B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2725 0000268C E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2726 00002691 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2727 00002693 88DC                <1> 	MOV	AH,BL
  2728 00002695 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2729 0000269A E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2730 0000269F 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2731                              <1> RC_BACK:
  2732 000026A0 6659                <1> 	POP	CX
  2733 000026A2 C3                  <1> 	RETn
  2734                              <1> 
  2735                              <1> ;-------------------------------------------------------------------------------
  2736                              <1> ; CHK_STAT_2
  2737                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  2738                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  2739                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  2740                              <1> ;
  2741                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2742                              <1> ;-------------------------------------------------------------------------------
  2743                              <1> CHK_STAT_2:
  2744 000026A3 B8[CB260000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2745 000026A8 50                  <1> 	PUSH	eAX
  2746 000026A9 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2747 000026AE 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2748 000026B0 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2749 000026B2 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2750 000026B7 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2751 000026BC 720C                <1> 	JC	short J34
  2752 000026BE A0[41D30000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2753 000026C3 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2754 000026C5 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2755 000026C7 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2756 000026C9 F8                  <1> 	CLC				; GOOD RETURN
  2757                              <1> J34:
  2758 000026CA 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2759                              <1> CS_BACK:
  2760 000026CB C3                  <1> 	RETn
  2761                              <1> J35:
  2762 000026CC 800D[40D30000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2763 000026D3 F9                  <1> 	STC				; ERROR RETURN CODE
  2764 000026D4 EBF4                <1> 	JMP	SHORT J34
  2765                              <1> 
  2766                              <1> ;-------------------------------------------------------------------------------
  2767                              <1> ; WAIT_INT
  2768                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  2769                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  2770                              <1> ;	IF THE DRIVE IS NOT READY.
  2771                              <1> ;
  2772                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2773                              <1> ;-------------------------------------------------------------------------------
  2774                              <1> 
  2775                              <1> ; 17/12/2014
  2776                              <1> ; 2.5 seconds waiting !
  2777                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  2778                              <1> ; amount of time to wait for completion interrupt from NEC.
  2779                              <1> 
  2780                              <1> 
  2781                              <1> WAIT_INT:
  2782 000026D6 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2783 000026D7 F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  2784                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  2785                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  2786                              <1> 
  2787                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  2788                              <1> 	;
  2789                              <1> 	;WAIT_FOR_MEM:	
  2790                              <1> 	;	Waits for a bit at a specified memory location pointed
  2791                              <1> 	;	to by ES:[DI] to become set.
  2792                              <1> 	;INPUT:
  2793                              <1> 	;	AH=Mask to test with.
  2794                              <1> 	;	ES:[DI] = memory location to watch.
  2795                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2796                              <1> 	;	     (normally 30 microseconds per period.)
  2797                              <1> 
  2798                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  2799                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  2800                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  2801                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  2802                              <1> 	; 27/02/2015
  2803 000026D8 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2804                              <1> WFMS_CHECK_MEM:
  2805 000026DD F605[3DD30000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2806 000026E4 7516                <1>         jnz     short J37
  2807                              <1> WFMS_HI:
  2808 000026E6 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2809 000026E8 A810                <1> 	TEST	AL,010H			; transition on memory
  2810 000026EA 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2811                              <1> WFMS_LO:
  2812 000026EC E461                <1> 	IN	AL,PORT_B		;SYS1
  2813 000026EE A810                <1> 	TEST	AL,010H
  2814 000026F0 74FA                <1> 	JZ	SHORT WFMS_LO
  2815 000026F2 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  2816                              <1> ;WFMS_OUTER_LP:
  2817                              <1> ;;	or	bl, bl			; check outer counter
  2818                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  2819                              <1> ;	dec	bl
  2820                              <1> ;	jz	short J36A	
  2821                              <1> ;	jmp	short WFMS_CHECK_MEM
  2822                              <1> 
  2823                              <1> 	;17/12/2014
  2824                              <1> 	;16/12/2014
  2825                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  2826                              <1> ;J36:
  2827                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2828                              <1> ;	JNZ	short J37
  2829                              <1> 	;16/12/2014
  2830                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  2831                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  2832                              <1> 	;JNZ	short J36
  2833                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  2834                              <1> ;	jb	short J36
  2835                              <1> 
  2836                              <1> ;WFMS_TIMEOUT:
  2837                              <1> ;J36A:
  2838 000026F4 800D[40D30000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2839 000026FB F9                  <1> 	STC				; ERROR RETURN
  2840                              <1> J37:
  2841 000026FC 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2842 000026FD 8025[3DD30000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2843 00002704 9D                  <1> 	POPF				; RECOVER CARRY
  2844 00002705 C3                  <1> 	RETn				; GOOD RETURN CODE
  2845                              <1> 
  2846                              <1> ;-------------------------------------------------------------------------------
  2847                              <1> ; RESULTS
  2848                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  2849                              <1> ;	FOLLOWING AN INTERRUPT.
  2850                              <1> ;
  2851                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2852                              <1> ;		AX,BX,CX,DX DESTROYED
  2853                              <1> ;-------------------------------------------------------------------------------
  2854                              <1> RESULTS:
  2855 00002706 57                  <1> 	PUSH	eDI
  2856 00002707 BF[41D30000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2857 0000270C B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2858 0000270E 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2859                              <1> 
  2860                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  2861                              <1> 
  2862                              <1> _R10: 
  2863                              <1> 	; 16/12/2014
  2864                              <1> 	; wait for (max) 0.5 seconds
  2865                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  2866                              <1> 	;XOR	CX,CX			; COUNTER
  2867                              <1> 
  2868                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  2869                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2870                              <1> 	; 27/02/2015
  2871 00002712 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  2872                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  2873                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  2874                              <1> 
  2875                              <1> WFPSR_OUTER_LP:
  2876                              <1> 	;
  2877                              <1> WFPSR_CHECK_PORT:
  2878                              <1> J39:					; WAIT FOR MASTER
  2879 00002717 EC                  <1> 	IN	AL,DX			; GET STATUS
  2880 00002718 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2881 0000271A 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2882 0000271C 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2883                              <1> WFPSR_HI:
  2884 0000271E E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2885 00002720 A810                <1> 	TEST	AL,010H			; transition on memory
  2886 00002722 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2887                              <1> WFPSR_LO:
  2888 00002724 E461                <1> 	IN	AL, PORT_B		; SYS1
  2889 00002726 A810                <1> 	TEST	AL,010H
  2890 00002728 74FA                <1> 	JZ	SHORT WFPSR_LO
  2891 0000272A E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  2892                              <1> 	;; 27/02/2015
  2893                              <1> 	;;dec	bh
  2894                              <1> 	;;jnz	short WFPSR_OUTER_LP
  2895                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  2896                              <1> 
  2897                              <1> 	;;mov	byte [wait_count], 0
  2898                              <1> ;J39:					; WAIT FOR MASTER
  2899                              <1> ;	IN	AL,DX			; GET STATUS
  2900                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2901                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2902                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  2903                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  2904                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  2905                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  2906                              <1> 	;
  2907                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  2908                              <1> 	;;jb	short J39	
  2909                              <1> 
  2910                              <1> ;WFPSR_TIMEOUT:
  2911 0000272C 800D[40D30000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2912 00002733 F9                  <1> 	STC				; SET ERROR RETURN
  2913 00002734 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2914                              <1> 
  2915                              <1> ;-----	READ IN THE STATUS
  2916                              <1> 
  2917                              <1> J42:
  2918 00002736 EB00                <1> 	JMP	$+2			; I/O DELAY
  2919 00002738 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2920 0000273A EC                  <1> 	IN	AL,DX			; GET THE DATA
  2921                              <1> 	; 16/12/2014
  2922                              <1> 	NEWIODELAY
  2922 0000273B E6EB                <2>  out 0ebh,al
  2923 0000273D 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2924 0000273F 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  2925                              <1> 	; 16/12/2014
  2926                              <1> ;	push	cx
  2927                              <1> ;	mov	cx, 30
  2928                              <1> ;wdw2:
  2929                              <1> ;	NEWIODELAY
  2930                              <1> ;	loop	wdw2
  2931                              <1> ;	pop	cx
  2932                              <1> 
  2933 00002740 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2934 00002745 E8E8F0FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2935 0000274A 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2936 0000274C EC                  <1> 	IN	AL,DX			; GET STATUS
  2937                              <1> 	; 16/12/2014
  2938                              <1> 	NEWIODELAY
  2938 0000274D E6EB                <2>  out 0ebh,al
  2939                              <1> 	;
  2940 0000274F A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2941 00002751 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2942                              <1> 
  2943 00002753 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2944 00002755 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2945 00002757 800D[40D30000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2946 0000275E F9                  <1> 	STC				; SET ERROR FLAG
  2947                              <1> 
  2948                              <1> ;-----	RESULT OPERATION IS DONE
  2949                              <1> POPRES:
  2950 0000275F 5F                  <1> 	POP	eDI
  2951 00002760 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  2952                              <1> 
  2953                              <1> ;-------------------------------------------------------------------------------
  2954                              <1> ; READ_DSKCHNG
  2955                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  2956                              <1> ;
  2957                              <1> ; ON ENTRY:	DI = DRIVE #
  2958                              <1> ;
  2959                              <1> ; ON EXIT:	DI = DRIVE #
  2960                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  2961                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  2962                              <1> ;		AX,CX,DX DESTROYED
  2963                              <1> ;-------------------------------------------------------------------------------
  2964                              <1> READ_DSKCHNG:
  2965 00002761 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2966 00002766 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2967 0000276A EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2968 0000276B A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2969 0000276D C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  2970                              <1> 
  2971                              <1> ;-------------------------------------------------------------------------------
  2972                              <1> ; DRIVE_DET
  2973                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  2974                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  2975                              <1> ; ON ENTRY:	DI = DRIVE #
  2976                              <1> ;-------------------------------------------------------------------------------
  2977                              <1> DRIVE_DET:
  2978 0000276E E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  2979 00002773 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2980 00002778 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  2981 0000277A B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  2982 0000277C E882FEFFFF          <1> 	CALL	SEEK
  2983 00002781 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  2984 00002783 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  2985                              <1> SK_GIN:
  2986 00002785 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  2987 00002787 6651                <1> 	PUSH	CX			; SAVE TRACK
  2988 00002789 E875FEFFFF          <1> 	CALL	SEEK
  2989 0000278E 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  2990 00002790 B8[CC270000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  2991 00002795 50                  <1> 	PUSH	eAX
  2992 00002796 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  2993 00002798 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2994 0000279D 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  2995 000027A0 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  2996 000027A2 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2997 000027A7 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  2998 000027AC 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2999 000027AD 6659                <1> 	POP	CX			; RESTORE TRACK
  3000 000027AF F605[41D30000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  3001 000027B6 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  3002 000027B8 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  3003 000027BA 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  3004                              <1> 
  3005                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  3006                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  3007                              <1> 
  3008 000027BC 808F[4DD30000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  3009 000027C3 C3                  <1> 	RETn				; ALL INFORMATION SET
  3010                              <1> IS_80:
  3011 000027C4 808F[4DD30000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  3012                              <1> DD_BAC:
  3013 000027CB C3                  <1> 	RETn
  3014                              <1> POP_BAC:
  3015 000027CC 6659                <1> 	POP	CX			; THROW AWAY
  3016 000027CE C3                  <1> 	RETn
  3017                              <1> 
  3018                              <1> fdc_int:  
  3019                              <1> 	  ; 30/07/2015	
  3020                              <1> 	  ; 16/02/2015
  3021                              <1> ;int_0Eh: ; 11/12/2014
  3022                              <1> 
  3023                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  3024                              <1> ; DISK_INT
  3025                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  3026                              <1> ;
  3027                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  3028                              <1> ;-------------------------------------------------------------------------------
  3029                              <1> DISK_INT_1:
  3030                              <1> 
  3031 000027CF 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3032 000027D1 1E                  <1> 	push	ds
  3033 000027D2 66B81000            <1> 	mov	ax, KDATA
  3034 000027D6 8ED8                <1> 	mov 	ds, ax
  3035 000027D8 800D[3DD30000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3036 000027DF B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3037 000027E1 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3038 000027E3 1F                  <1> 	pop	ds
  3039 000027E4 6658                <1> 	POP	AX			; RECOVER REGISTER
  3040 000027E6 CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  3041                              <1> 
  3042                              <1> ;-------------------------------------------------------------------------------
  3043                              <1> ; DSKETTE_SETUP
  3044                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  3045                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  3046                              <1> ;-------------------------------------------------------------------------------
  3047                              <1> 
  3048                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3049                              <1> 
  3050                              <1> DSKETTE_SETUP:
  3051                              <1> 	;PUSH	AX			; SAVE REGISTERS
  3052                              <1> 	;PUSH	BX
  3053                              <1> 	;PUSH	CX
  3054 000027E7 52                  <1> 	PUSH	eDX
  3055                              <1> 	;PUSH	DI
  3056                              <1> 	;;PUSH	DS
  3057                              <1> 	; 14/12/2014
  3058                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  3059                              <1> 	;mov	[DISK_POINTER+2], cs
  3060                              <1> 	;
  3061                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  3062 000027E8 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3063 000027EA 66C705[4DD30000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3063 000027F2 00                  <1>
  3064 000027F3 8025[48D30000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3065 000027FA 800D[48D30000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3066 00002801 C605[3DD30000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3067 00002808 C605[3FD30000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3068 0000280F C605[3ED30000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3069 00002816 C605[40D30000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3070                              <1> 	;
  3071                              <1> 	; 28/02/2015
  3072                              <1> 	;mov	word [cfd], 100h 
  3073 0000281D E848F2FFFF          <1> 	call	DSK_RESET
  3074 00002822 5A                  <1> 	pop	edx
  3075 00002823 F8                  <1> 	clc	; 29/05/2016
  3076 00002824 C3                  <1> 	retn
  3077                              <1> 
  3078                              <1> ;SUP0:
  3079                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  3080                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3081                              <1> ;	; 02/01/2015
  3082                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  3083                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  3084                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  3085                              <1> ;       cmp     byte [fd1_type], 0	
  3086                              <1> ;	jna	short sup1
  3087                              <1> ;	or	di, di
  3088                              <1> ;	jnz	short sup1
  3089                              <1> ;	inc	di
  3090                              <1> ;       jmp     short SUP0
  3091                              <1> ;sup1:
  3092                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  3093                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  3094                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  3095                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  3096                              <1> ;	;POP	DI
  3097                              <1> ;	POP	eDX
  3098                              <1> ;	;POP	CX
  3099                              <1> ;	;POP	BX
  3100                              <1> ;	;POP	AX
  3101                              <1> ;	RETn
  3102                              <1> 
  3103                              <1> ;//////////////////////////////////////////////////////
  3104                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3105                              <1> ;
  3106                              <1> 
  3107                              <1> int13h: ; 21/02/2015
  3108 00002825 9C                  <1> 	pushfd
  3109 00002826 0E                  <1> 	push 	cs
  3110 00002827 E841010000          <1> 	call 	DISK_IO
  3111 0000282C C3                  <1> 	retn
  3112                              <1> 
  3113                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  3114                              <1> ;/////////////////////////////////////////////////////////////////////
  3115                              <1> 
  3116                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  3117                              <1> ; 18/02/2016
  3118                              <1> ; 17/02/2016
  3119                              <1> ; 23/02/2015
  3120                              <1> ; 21/02/2015 (unix386.s)
  3121                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  3122                              <1> ;
  3123                              <1> ; Original Source Code:
  3124                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  3125                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  3126                              <1> ;
  3127                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  3128                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  3129                              <1> ;
  3130                              <1> 
  3131                              <1> 
  3132                              <1> ;The wait for controller to be not busy is 10 seconds.
  3133                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3134                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  3135                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  3136                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  3137                              <1> 
  3138                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  3139                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3140                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  3141                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  3142                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  3143                              <1> 
  3144                              <1> ;The wait for Data request on read and write longs is
  3145                              <1> ;2000 us. (?)
  3146                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  3147                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  3148                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  3149                              <1> 
  3150                              <1> ; Port 61h (PORT_B)
  3151                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  3152                              <1> 
  3153                              <1> ; 23/12/2014
  3154                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  3155                              <1> 
  3156                              <1> 
  3157                              <1> ;--- INT 13H -------------------------------------------------------------------
  3158                              <1> ;									       :
  3159                              <1> ; FIXED DISK I/O INTERFACE						       :
  3160                              <1> ;									       :
  3161                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  3162                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  3163                              <1> ;									       :
  3164                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  3165                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  3166                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  3167                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  3168                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  3169                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  3170                              <1> ;									       :
  3171                              <1> ;------------------------------------------------------------------------------:
  3172                              <1> ;									       :
  3173                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  3174                              <1> ;									       :
  3175                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  3176                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  3177                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  3178                              <1> ;			  DL > 80H - DISK				       :
  3179                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  3180                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  3181                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  3182                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  3183                              <1> ;	(AH)= 06H  UNUSED						       :
  3184                              <1> ;	(AH)= 07H  UNUSED						       :
  3185                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  3186                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  3187                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  3188                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  3189                              <1> ;	(AH)= 0AH  READ LONG						       :
  3190                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  3191                              <1> ;	(AH)= 0CH  SEEK 						       :
  3192                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  3193                              <1> ;	(AH)= 0EH  UNUSED						       :
  3194                              <1> ;	(AH)= 0FH  UNUSED						       :
  3195                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  3196                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  3197                              <1> ;	(AH)= 12H  UNUSED						       :
  3198                              <1> ;	(AH)= 13H  UNUSED						       :
  3199                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  3200                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  3201                              <1> ;									       :
  3202                              <1> ;-------------------------------------------------------------------------------
  3203                              <1> ;									       :
  3204                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  3205                              <1> ;									       :
  3206                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  3207                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  3208                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  3209                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  3210                              <1> ;									       :
  3211                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  3212                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  3213                              <1> ;				 (10 BITS TOTAL)			       :
  3214                              <1> ;									       :
  3215                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  3216                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  3217                              <1> ;									       :
  3218                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  3219                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  3220                              <1> ;									       :
  3221                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  3222                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  3223                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  3224                              <1> ;			       80H FOR A BAD SECTOR			       :
  3225                              <1> ;			   N = SECTOR NUMBER				       :
  3226                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  3227                              <1> ;			   THE TABLE SHOULD BE: 			       :
  3228                              <1> ;									       :
  3229                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  3230                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  3231                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  3232                              <1> ;									       :
  3233                              <1> ;-------------------------------------------------------------------------------
  3234                              <1> 
  3235                              <1> ;-------------------------------------------------------------------------------
  3236                              <1> ; OUTPUT								       :
  3237                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  3238                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  3239                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  3240                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  3241                              <1> ;									       :
  3242                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  3243                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  3244                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  3245                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  3246                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  3247                              <1> ;		REWRITTEN.						       :
  3248                              <1> ;									       :
  3249                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  3250                              <1> ;	   INPUT:							       :
  3251                              <1> ;	     (DL) = DRIVE NUMBER					       :	
  3252                              <1> ;	     ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)						       :	 	
  3253                              <1> ;	     EBX = Buffer address for fixed disk parameters table (32 bytes)   :
  3254                              <1> ;	   OUTPUT:							       :
  3255                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  3256                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  3257                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  3258                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  3259                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  3260                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  3261                              <1> ;									       :
  3262                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  3263                              <1> ;									       :
  3264                              <1> ;	AH = 0 - NOT PRESENT						       :
  3265                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  3266                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  3267                              <1> ;	     3 - FIXED DISK						       :
  3268                              <1> ;									       :
  3269                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  3270                              <1> ;									       :
  3271                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  3272                              <1> ;	INFORMATION.							       :
  3273                              <1> ;									       :
  3274                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  3275                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  3276                              <1> ;									       :
  3277                              <1> ;-------------------------------------------------------------------------------
  3278                              <1> 
  3279                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  3280                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  3281                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  3282                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  3283                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  3284                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  3285                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  3286                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  3287                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  3288                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  3289                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  3290                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  3291                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  3292                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  3293                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  3294                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  3295                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  3296                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  3297                              <1> 
  3298                              <1> ;--------------------------------------------------------
  3299                              <1> ;							:
  3300                              <1> ; FIXED DISK PARAMETER TABLE				:
  3301                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  3302                              <1> ;							:
  3303                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  3304                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  3305                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  3306                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  3307                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  3308                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  3309                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  3310                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  3311                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  3312                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  3313                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  3314                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  3315                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  3316                              <1> ;							:
  3317                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  3318                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  3319                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  3320                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  3321                              <1> ;							:
  3322                              <1> ;--------------------------------------------------------
  3323                              <1> 
  3324                              <1> ;--------------------------------------------------------
  3325                              <1> ;							:
  3326                              <1> ; HARDWARE SPECIFIC VALUES				:
  3327                              <1> ;							:
  3328                              <1> ;  -  CONTROLLER I/O PORT				:
  3329                              <1> ;							:
  3330                              <1> ;     > WHEN READ FROM: 				:
  3331                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  3332                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  3333                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  3334                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  3335                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  3336                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  3337                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  3338                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  3339                              <1> ;							:
  3340                              <1> ;     > WHEN WRITTEN TO:				:
  3341                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  3342                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  3343                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  3344                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  3345                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  3346                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  3347                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  3348                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  3349                              <1> ;							:
  3350                              <1> ;--------------------------------------------------------
  3351                              <1> 
  3352                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  3353                              <1> ;HF1_PORT	equ	0170h	
  3354                              <1> ;HF_REG_PORT	EQU	03F6H
  3355                              <1> ;HF1_REG_PORT	equ	0376h
  3356                              <1> 
  3357                              <1> HDC1_BASEPORT	equ	1F0h
  3358                              <1> HDC2_BASEPORT	equ	170h		
  3359                              <1> 
  3360 0000282D 90                  <1> align 2
  3361                              <1> 
  3362                              <1> ;-----		STATUS REGISTER
  3363                              <1> 
  3364                              <1> ST_ERROR	EQU	00000001B	;
  3365                              <1> ST_INDEX	EQU	00000010B	;
  3366                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  3367                              <1> ST_DRQ		EQU	00001000B	;
  3368                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  3369                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  3370                              <1> ST_READY	EQU	01000000B	;
  3371                              <1> ST_BUSY 	EQU	10000000B	;
  3372                              <1> 
  3373                              <1> ;-----		ERROR REGISTER
  3374                              <1> 
  3375                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  3376                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  3377                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  3378                              <1> ;		EQU	00001000B	; NOT USED
  3379                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  3380                              <1> ;		EQU	00100000B	; NOT USED
  3381                              <1> ERR_DATA_ECC	EQU	01000000B
  3382                              <1> ERR_BAD_BLOCK	EQU	10000000B
  3383                              <1> 
  3384                              <1> 
  3385                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  3386                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  3387                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  3388                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  3389                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  3390                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  3391                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  3392                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  3393                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  3394                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  3395                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  3396                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  3397                              <1> 
  3398                              <1> ;MAX_FILE	EQU	2
  3399                              <1> ;S_MAX_FILE	EQU	2
  3400                              <1> MAX_FILE	equ	4		; 22/12/2014
  3401                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  3402                              <1> 
  3403                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  3404                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  3405                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  3406                              <1> 
  3407                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  3408                              <1> 
  3409                              <1> ;-----		COMMAND BLOCK REFERENCE
  3410                              <1> 
  3411                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  3412                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  3413                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  3414                              <1> ; 19/12/2014
  3415                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  3416                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  3417                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3418                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3419                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  3420                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  3421                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  3422                              <1> 
  3423                              <1> align 2
  3424                              <1> 
  3425                              <1> ;----------------------------------------------------------------
  3426                              <1> ; FIXED DISK I/O SETUP						:
  3427                              <1> ;								:
  3428                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  3429                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  3430                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  3431                              <1> ;								:
  3432                              <1> ;----------------------------------------------------------------
  3433                              <1> 
  3434                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3435                              <1> 
  3436                              <1> DISK_SETUP:
  3437                              <1> 	;CLI
  3438                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  3439                              <1> 	;xor	ax,ax
  3440                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  3441                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  3442                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  3443                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  3444                              <1> 	;MOV	[DISK_VECTOR+2],AX
  3445                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  3446                              <1> 	;MOV	[ORG_VECTOR+2],CS
  3447                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  3448                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  3449                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  3450                              <1> 	;;MOV	[HDISK_INT+2],CS
  3451                              <1> 	;mov	[HDISK_INT1+2],CS
  3452                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  3453                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  3454                              <1> 	;mov	[HDISK_INT2+2],CS
  3455                              <1> 	;
  3456                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  3457                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  3458                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  3459                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  3460                              <1> 	;push	cs
  3461                              <1> 	;pop	ds
  3462                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  3463                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  3464 0000282E C705[58D30000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3464 00002836 0900                <1>
  3465                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  3466                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  3467 00002838 C705[5CD30000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3467 00002840 0900                <1>
  3468                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  3469                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  3470 00002842 C705[60D30000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3470 0000284A 0900                <1>
  3471                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  3472                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  3473 0000284C C705[64D30000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3473 00002854 0900                <1>
  3474                              <1> 	;
  3475                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  3476                              <1> 	;;;AND	AL,0BFH
  3477                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  3478                              <1> 	;;;JMP	$+2
  3479                              <1> 	;;IODELAY
  3480                              <1> 	;;OUT	INTB01,AL
  3481                              <1> 	;;IODELAY
  3482                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  3483                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  3484                              <1> 	;;;JMP	$+2
  3485                              <1> 	;;IODELAY
  3486                              <1> 	;;OUT	INTA01,AL
  3487                              <1> 	;
  3488                              <1> 	;STI
  3489                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  3490                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  3491                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  3492                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3493                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  3494                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  3495                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  3496                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  3497                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  3498                              <1> 	;mov	si, hd0_type
  3499 00002856 BE[C2CD0000]        <1> 	mov	esi, hd0_type
  3500                              <1> 	;mov	cx, 4
  3501 0000285B B904000000          <1> 	mov	ecx, 4
  3502                              <1> hde_l:
  3503 00002860 AC                  <1> 	lodsb
  3504 00002861 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3505 00002863 7206                <1> 	jb	short _L4
  3506 00002865 FE05[54D30000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3507                              <1> _L4: ; 26/02/2015
  3508 0000286B E2F3                <1> 	loop	hde_l	
  3509                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  3510                              <1> ;L4:
  3511                              <1> 	; 
  3512                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  3513                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  3514                              <1> 	;;mov 	cl, 3
  3515                              <1> 	;;
  3516                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  3517                              <1> ;;hdc_dl:
  3518                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  3519                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  3520                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  3521                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  3522                              <1> 	;;jnc	short hdc_reset0
  3523                              <1> 	;;loop	hdc_dl
  3524                              <1> 	;;; 27/12/2014
  3525                              <1> 	;;stc
  3526                              <1> 	;;retn
  3527                              <1> 	;
  3528                              <1> ;;hdc_reset0:
  3529                              <1> 	; 18/01/2015
  3530 0000286D 8A0D[54D30000]      <1> 	mov	cl, [HF_NUM]
  3531 00002873 20C9                <1> 	and	cl, cl
  3532 00002875 740E                <1> 	jz	short POD_DONE
  3533                              <1> 	;
  3534 00002877 B27F                <1> 	mov	dl, 7Fh
  3535                              <1> hdc_reset1:
  3536 00002879 FEC2                <1> 	inc	dl
  3537                              <1> 	;; 31/12/2015
  3538                              <1> 	;;push	dx
  3539                              <1> 	;;push	cx
  3540                              <1> 	;;push	ds
  3541                              <1> 	;;sub	ax, ax
  3542                              <1> 	;;mov	ds, ax
  3543                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  3544                              <1> 	;;pop	ds
  3545                              <1> 	;;MOV	BX,AX
  3546                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  3547                              <1> 	;;MOV	CX,AX
  3548                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  3549                              <1> 	;;
  3550                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  3551                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  3552                              <1> 	;;pop	cx
  3553                              <1> 	;;pop	dx
  3554                              <1> 	;;
  3555                              <1> 	; 18/01/2015
  3556 0000287B B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3557                              <1> 	;int	13h
  3558 0000287D E8A3FFFFFF          <1> 	call	int13h
  3559 00002882 E2F5                <1> 	loop	hdc_reset1
  3560 00002884 F8                  <1> 	clc 	; 29/05/2016
  3561                              <1> POD_DONE:
  3562 00002885 C3                  <1> 	RETn
  3563                              <1> 
  3564                              <1> ;;-----	POD_ERROR
  3565                              <1> 
  3566                              <1> ;;CTL_ERRX:
  3567                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  3568                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  3569                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3570                              <1> ;	;JMP	short POD_DONE
  3571                              <1> 
  3572                              <1> ;;HD_RESET_1:
  3573                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  3574                              <1> ;;	;PUSH	CX
  3575                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  3576                              <1> ;;	INT	13H
  3577                              <1> ;;	JC	short RES_2
  3578                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  3579                              <1> ;;	INT	13H
  3580                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  3581                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  3582                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3583                              <1> ;;					; (30 seconds)		
  3584                              <1> ;;	;cmc
  3585                              <1> ;;	;JNC	short RES_1
  3586                              <1> ;;	jb	short RES_1
  3587                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  3588                              <1> ;;	;TEST	DL,1
  3589                              <1> ;;	;JNZ	RES_E1
  3590                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  3591                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  3592                              <1> ;;	;JMP	SHORT RES_E1
  3593                              <1> ;;RES_ER: ; 22/12/2014
  3594                              <1> ;;RES_OK:
  3595                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3596                              <1> ;;	;POP	BX
  3597                              <1> ;;	RETn
  3598                              <1> ;;
  3599                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  3600                              <1> ;;	INT	13H
  3601                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  3602                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  3603                              <1> ;;	INT	13H
  3604                              <1> ;;	JC	short RES_ER
  3605                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  3606                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  3607                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  3608                              <1> ;;	INT	13H
  3609                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  3610                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  3611                              <1> ;;	JE	short RES_OK
  3612                              <1> ;;	CMP	AH,DATA_CORRECTED
  3613                              <1> ;;	JE	short RES_OK
  3614                              <1> ;;	CMP	AH,BAD_ECC
  3615                              <1> ;;	JE	short RES_OK
  3616                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  3617                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3618                              <1> ;;					; (60 seconds)		
  3619                              <1> ;;	cmc
  3620                              <1> ;;	JC	short RES_ER		; FAILED
  3621                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  3622                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  3623                              <1> ;;	AND	AL,3FH
  3624                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  3625                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  3626                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  3627                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  3628                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  3629                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  3630                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  3631                              <1> ;;	;TEST	DL,1
  3632                              <1> ;;	;JNZ	short RES_E1
  3633                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  3634                              <1> ;;;RES_E1:
  3635                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3636                              <1> ;;;RES_OK:
  3637                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3638                              <1> ;;	;POP	BX
  3639                              <1> ;;	;RETn
  3640                              <1> ;
  3641                              <1> ;;SET_FAIL:
  3642                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  3643                              <1> ;	;CALL	CMOS_READ
  3644                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  3645                              <1> ;	;XCHG	AH,AL			; SAVE IT
  3646                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  3647                              <1> ;	;RETn
  3648                              <1> ;
  3649                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  3650                              <1> ;	;POP	AX			; SAVE RETURN
  3651                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  3652                              <1> ;	;POP	BX
  3653                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  3654                              <1> ;	;PUSH	CX
  3655                              <1> ;	;PUSH	AX
  3656                              <1> ;	;push	ds
  3657                              <1> ;	;xor	ax, ax
  3658                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  3659                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  3660                              <1> ;	;				; BX = START TIME
  3661                              <1> ;	;				; CX = END TIME
  3662                              <1> ;	;pop	ds
  3663                              <1> ;	;CMP	BX,CX
  3664                              <1> ;	;JB	short TCHK1		; START < END
  3665                              <1> ;	;CMP	BX,AX
  3666                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  3667                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  3668                              <1> ;;TCHK1: CMP	AX,BX
  3669                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  3670                              <1> ;;TCHK2: CMP	AX,CX
  3671                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  3672                              <1> ;;					; OR CURRENT < END < START
  3673                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  3674                              <1> ;;	RETn
  3675                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  3676                              <1> ;;	RETn
  3677                              <1> ;;
  3678                              <1> ;;int_13h:
  3679                              <1> 
  3680                              <1> ;----------------------------------------
  3681                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  3682                              <1> ;----------------------------------------
  3683                              <1> 
  3684                              <1> ; 01/06/2016
  3685                              <1> ; 29/05/2016 
  3686                              <1> ; 28/05/2016
  3687                              <1> ; 27/05/2016
  3688                              <1> ; 16/05/2016
  3689                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  3690                              <1> int33h:  ; DISK I/O
  3691                              <1> 	; 29/05/2016
  3692 00002886 80642408FE          <1> 	and	byte [esp+8], 11111110b  ; clear carry bit of eflags register
  3693                              <1> 	; 16/05/2016
  3694 0000288B 1E                  <1> 	push	ds
  3695 0000288C 53                  <1> 	push	ebx ; user's buffer address (virtual)
  3696 0000288D 66BB1000            <1> 	mov	bx, KDATA ; System (Kernel's) data segment
  3697 00002891 8EDB                <1> 	mov	ds, bx
  3698 00002893 8F05[3CE00000]      <1> 	pop	dword [user_buffer] ; 01/06/2016
  3699 00002899 C605[7ED90000]00    <1> 	mov	byte [scount], 0 ; sector count for transfer
  3700 000028A0 80FC03              <1> 	cmp	ah, 03h ; chs write
  3701 000028A3 7743                <1> 	ja	short int33h_2
  3702 000028A5 7407                <1> 	je	short int33h_0
  3703 000028A7 80FC02              <1> 	cmp	ah, 02h ; chs read
  3704 000028AA 7269                <1> 	jb	short int33h_5
  3705 000028AC EB62                <1> 	jmp	short int33h_4
  3706                              <1> int33h_0:
  3707                              <1> 	; transfer user's buffer content to sector buffer
  3708 000028AE 51                  <1> 	push	ecx
  3709 000028AF 0FB6C8              <1> 	movzx	ecx, al
  3710                              <1> int33h_1:
  3711 000028B2 56                  <1> 	push	esi
  3712 000028B3 8B35[3CE00000]      <1> 	mov	esi, [user_buffer]
  3713                              <1> 	; esi = user's buffer address (virtual, ebx)
  3714 000028B9 57                  <1> 	push	edi
  3715 000028BA 06                  <1> 	push	es
  3716 000028BB 50                  <1> 	push	eax
  3717 000028BC 66B81000            <1> 	mov	ax, KDATA
  3718 000028C0 8EC0                <1> 	mov	es, ax
  3719 000028C2 BF00000700          <1> 	mov	edi, Cluster_Buffer
  3720 000028C7 C1E109              <1> 	shl	ecx, 9 ; * 512
  3721 000028CA E800950000          <1> 	call	transfer_from_user_buffer
  3722 000028CF 58                  <1> 	pop	eax
  3723 000028D0 07                  <1> 	pop	es
  3724 000028D1 5F                  <1> 	pop	edi
  3725 000028D2 5E                  <1> 	pop	esi
  3726 000028D3 59                  <1> 	pop	ecx
  3727 000028D4 733F                <1> 	jnc	short int33h_5
  3728 000028D6 8B1D[3CE00000]      <1> 	mov	ebx, [user_buffer] ; 01/06/2016
  3729 000028DC 1F                  <1> 	pop	ds
  3730                              <1> 
  3731                              <1> 	; (*) 29/05/2016
  3732                              <1> 	; (*) retf 4 ; skip eflags on stack
  3733                              <1> 
  3734                              <1> 	; 29/05/2016 -set carry flag on stack-
  3735                              <1> 	; [esp] = EIP
  3736                              <1> 	; [esp+4] = CS
  3737                              <1> 	; [esp+8] = E-FLAGS
  3738 000028DD 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3739                              <1> 	; [esp+12] = ESP (user)
  3740                              <1> 	; [esp+16] = SS (User)
  3741 000028E2 B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3742 000028E7 CF                  <1> 	iretd
  3743                              <1> 	
  3744                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
  3745                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
  3746                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  3747                              <1> 	; // RETF instruction:
  3748                              <1> 	;
  3749                              <1> 	; IF OperandMode=32 THEN
  3750                              <1>  	;    Load CS:EIP from stack;
  3751                              <1>  	;    Set CS RPL to CPL;
  3752                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
  3753                              <1>  	;    Load SS:eSP from stack;
  3754                              <1>  	; ELSE (* OperandMode=16 *)
  3755                              <1>  	;    Load CS:IP from stack;
  3756                              <1>  	;    Set CS RPL to CPL;
  3757                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
  3758                              <1> 	;    Load SS:eSP from stack;
  3759                              <1>  	; FI;
  3760                              <1> 	;
  3761                              <1> 	; //
  3762                              <1> 
  3763                              <1> int33h_2:
  3764 000028E8 80FC05              <1> 	cmp	ah, 05h ; format track
  3765 000028EB 770A                <1> 	ja	short int33h_3
  3766 000028ED 7226                <1> 	jb	short int33h_5
  3767 000028EF 51                  <1> 	push	ecx
  3768 000028F0 B901000000          <1> 	mov	ecx, 1
  3769 000028F5 EBBB                <1> 	jmp	short int33h_1
  3770                              <1> int33h_3:
  3771 000028F7 80FC1C              <1> 	cmp	ah, 1Ch ; LBA write
  3772 000028FA 7719                <1> 	ja	short int33h_5
  3773 000028FC 74B0                <1> 	je	short int33h_0
  3774 000028FE 80FC1B              <1> 	cmp	ah, 1Bh ; LBA read
  3775 00002901 740D                <1> 	je	short int33h_4
  3776 00002903 80FC08              <1> 	cmp	ah, 08h ; get disk parameters
  3777 00002906 750D                <1> 	jne	short int33h_5
  3778                              <1> 	; 01/06/2016
  3779 00002908 8B1D[3CE00000]      <1> 	mov	ebx, [user_buffer] ; user's buffer address
  3780 0000290E EB0A                <1> 	jmp	short int33h_6
  3781                              <1> int33h_4:
  3782 00002910 A2[7ED90000]        <1> 	mov	byte [scount], al ; <= 128 sectors
  3783                              <1> int33h_5:
  3784 00002915 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; max. 65536 bytes
  3785                              <1> 				    ; buf. addr: 70000h	
  3786                              <1> 	;mov	byte [ClusterBuffer_Valid], 0
  3787                              <1> int33h_6:
  3788 0000291A 1F                  <1> 	pop	ds
  3789 0000291B 9C                  <1> 	pushfd
  3790 0000291C 0E                  <1> 	push 	cs
  3791 0000291D E84B000000          <1> 	call 	DISK_IO
  3792 00002922 2E8B1D[3CE00000]    <1> 	mov	ebx, [CS:user_buffer] ; 01/06/2016
  3793 00002929 723C                <1> 	jc	short int33h_9
  3794                              <1> 	;
  3795 0000292B 2E803D[7ED90000]00  <1> 	cmp	byte [CS:scount], 0
  3796 00002933 762C                <1> 	jna	short int33h_7
  3797                              <1> 	; transfer sector buffer content to user's buffer
  3798 00002935 06                  <1> 	push	es
  3799 00002936 1E                  <1> 	push	ds
  3800 00002937 50                  <1> 	push	eax
  3801 00002938 66B81000            <1> 	mov	ax, KDATA
  3802 0000293C 8ED8                <1> 	mov	ds, ax
  3803 0000293E 8EC0                <1> 	mov	es, ax
  3804 00002940 51                  <1> 	push	ecx
  3805 00002941 56                  <1> 	push	esi
  3806 00002942 57                  <1> 	push	edi
  3807 00002943 0FB60D[7ED90000]    <1> 	movzx	ecx, byte [scount]
  3808 0000294A C1E109              <1> 	shl	ecx, 9 ; * 512 bytes
  3809 0000294D 89DF                <1> 	mov	edi, ebx ; user's buffer address
  3810 0000294F BE00000700          <1> 	mov	esi, Cluster_Buffer
  3811 00002954 E82C940000          <1> 	call	transfer_to_user_buffer
  3812 00002959 5F                  <1> 	pop	edi
  3813 0000295A 5E                  <1> 	pop	esi
  3814 0000295B 59                  <1> 	pop	ecx
  3815 0000295C 58                  <1> 	pop	eax
  3816 0000295D 1F                  <1> 	pop	ds
  3817 0000295E 07                  <1> 	pop	es
  3818 0000295F 7201                <1> 	jc	short int33h_8
  3819                              <1> int33h_7:
  3820                              <1> 	; cf = 0  ; use eflags which is in stack
  3821 00002961 CF                  <1> 	iretd	
  3822                              <1> int33h_8:
  3823 00002962 B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3824                              <1> int33h_9:
  3825                              <1> 	; cf = 1
  3826                              <1> 
  3827                              <1> 	; (*) 29/05/2016	
  3828                              <1> 	; (*) retf 4 ; skip eflags on stack
  3829                              <1> 	; Note: This 'retf 4' was wrong, -it was causing
  3830                              <1> 	;       to stack errors in ring 3-
  3831                              <1> 	;	POP sequence of 'retf 4' is as
  3832                              <1> 	;       "eip, cs, eflags, esp, ss, +4 bytes" 
  3833                              <1>         ;       it is not as "eip, cs, +4 bytes, esp, ss" ! 
  3834                              <1> 
  3835                              <1> 	; 29/05/2016 -set carry flag on stack-
  3836 00002967 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3837 0000296C CF                  <1> 	iretd
  3838                              <1> 
  3839                              <1> ; 29/05/2016
  3840                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  3841                              <1> 
  3842                              <1> DISK_IO:
  3843 0000296D 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  3844                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  3845                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  3846                              <1> 	;;call	int40h
  3847 00002970 0F8224F0FFFF        <1> 	jb	DISKETTE_IO_1
  3848                              <1> ;RET_2:
  3849                              <1> 	;RETf	2			; BACK TO CALLER
  3850                              <1> ;	retf	4
  3851                              <1> A1:
  3852 00002976 FB                  <1> 	STI				; ENABLE INTERRUPTS
  3853                              <1> 	;; 04/01/2015
  3854                              <1> 	;;OR	AH,AH
  3855                              <1> 	;;JNZ	short A2
  3856                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  3857                              <1> 	;;SUB	AH,AH
  3858 00002977 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  3859                              <1> 	;JA	short RET_2
  3860 0000297A 7616                <1> 	jna	short _A0
  3861                              <1> 	; 29/05/2016
  3862 0000297C 1E                  <1> 	push	ds
  3863 0000297D 6650                <1> 	push	ax
  3864 0000297F 66B81000            <1> 	mov	ax, KDATA
  3865 00002983 8ED8                <1> 	mov	ds, ax
  3866 00002985 6658                <1> 	pop	ax
  3867 00002987 B4AA                <1>         mov     ah, 0AAh        ; Hard disk drive not ready !
  3868                              <1> 				; (Programmer's guide to AMIBIOS, 1992)
  3869 00002989 8825[53D30000]      <1> 	mov     byte [DISK_STATUS1], ah
  3870 0000298F 1F                  <1> 	pop	ds
  3871 00002990 EB38                <1> 	jmp	short RET_2
  3872                              <1> _A0:
  3873                              <1> 	; 18/01/2015
  3874 00002992 08E4                <1> 	or	ah,ah
  3875 00002994 743A                <1> 	jz	short A4
  3876 00002996 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  3877 00002999 7504                <1> 	jne	short A2
  3878 0000299B 28E4                <1> 	sub	ah,ah	; Reset
  3879 0000299D EB31                <1> 	jmp	short A4
  3880                              <1> A2:
  3881 0000299F 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3882                              <1> 	;JNZ	short A3
  3883                              <1>         ;JMP    GET_PARM_N
  3884 000029A2 0F8431030000        <1> 	je	GET_PARM_N
  3885 000029A8 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3886                              <1> 	;JNZ	short A4
  3887                              <1>         ;JMP    READ_DASD_TYPE
  3888 000029AB 0F84DA020000        <1>         je      READ_DASD_TYPE
  3889                              <1> 	; 02/02/2015
  3890 000029B1 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3891                              <1> 	; 12/01/2015
  3892 000029B4 F5                  <1> 	cmc
  3893 000029B5 7319                <1> 	jnc	short A4
  3894                              <1> int33h_bad_cmd:
  3895                              <1> 	; 16/05/2016
  3896                              <1> 	; 30/01/2015
  3897                              <1> 	; 29/05/2016
  3898 000029B7 1E                  <1> 	push	ds
  3899 000029B8 6650                <1> 	push	ax
  3900 000029BA 66B81000            <1> 	mov	ax, KDATA
  3901 000029BE 8ED8                <1> 	mov	ds, ax
  3902 000029C0 6658                <1> 	pop	ax
  3903 000029C2 B401                <1> 	mov	ah, BAD_CMD
  3904 000029C4 8825[53D30000]      <1> 	mov     [DISK_STATUS1], ah ; BAD_CMD  ; COMMAND ERROR
  3905                              <1>         ;jmp	short RET_2
  3906                              <1> RET_2:
  3907                              <1> 	; (*) 29/05/2016
  3908                              <1> 	; (*) retf 4
  3909 000029CA 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3910 000029CF CF                  <1> 	iretd
  3911                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3912 000029D0 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3913 000029D4 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3914 000029D5 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3915 000029D6 52                  <1> 	PUSH	eDX
  3916 000029D7 1E                  <1> 	PUSH	DS
  3917 000029D8 06                  <1> 	PUSH	ES
  3918 000029D9 56                  <1> 	PUSH	eSI
  3919 000029DA 57                  <1> 	PUSH	eDI
  3920                              <1> 	;;04/01/2015
  3921                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  3922                              <1> 	;;JNZ	short A5
  3923                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  3924                              <1> ;;A5:	
  3925                              <1> 	;push	cs
  3926                              <1> 	;pop	ds
  3927                              <1> 	; 21/02/2015
  3928 000029DB 6650                <1> 	push	ax
  3929 000029DD 66B81000            <1> 	mov	ax, KDATA
  3930 000029E1 8ED8                <1> 	mov	ds, ax
  3931 000029E3 8EC0                <1> 	mov	es, ax	
  3932 000029E5 6658                <1> 	pop	ax
  3933 000029E7 E88D000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3934                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3935 000029EC 8A25[53D30000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  3936                              <1> 	;(*) CMP AH,1			; SET THE CARRY FLAG TO INDICATE
  3937                              <1> 	;(*) CMC			; SUCCESS OR FAILURE
  3938 000029F2 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  3939 000029F3 5E                  <1> 	POP	eSI
  3940 000029F4 07                  <1>         POP     ES
  3941 000029F5 1F                  <1>         POP     DS
  3942 000029F6 5A                  <1> 	POP	eDX
  3943 000029F7 59                  <1> 	POP	eCX
  3944 000029F8 5B                  <1> 	POP	eBX
  3945 000029F9 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  3946                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  3947                              <1> 	; (*) 29/05/2016
  3948                              <1> 	; (*) retf 4
  3949 000029FA 80FC01              <1> 	cmp	ah, 1
  3950 000029FD 7205                <1> 	jc	short _A5 
  3951 000029FF 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3952                              <1> _A5:
  3953 00002A04 CF                  <1> 	iretd
  3954                              <1> 
  3955                              <1> ; 21/02/2015
  3956                              <1> ;       dw --> dd
  3957                              <1> D1:					; FUNCTION TRANSFER TABLE
  3958 00002A05 [C72B0000]          <1> 	dd	DISK_RESET		; 000H
  3959 00002A09 [3E2C0000]          <1> 	dd	RETURN_STATUS		; 001H
  3960 00002A0D [4B2C0000]          <1> 	dd	DISK_READ		; 002H
  3961 00002A11 [542C0000]          <1> 	dd	DISK_WRITE		; 003H
  3962 00002A15 [5D2C0000]          <1> 	dd	DISK_VERF		; 004H
  3963 00002A19 [752C0000]          <1> 	dd	FMT_TRK 		; 005H
  3964 00002A1D [BD2B0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  3965 00002A21 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  3966 00002A25 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  3967 00002A29 [602D0000]          <1> 	dd	INIT_DRV		; 009H
  3968 00002A2D [BF2D0000]          <1> 	dd	RD_LONG 		; 00AH
  3969 00002A31 [C82D0000]          <1> 	dd	WR_LONG 		; 00BH
  3970 00002A35 [D12D0000]          <1> 	dd	DISK_SEEK		; 00CH
  3971 00002A39 [C72B0000]          <1> 	dd	DISK_RESET		; 00DH
  3972 00002A3D [BD2B0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  3973 00002A41 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  3974 00002A45 [F92D0000]          <1> 	dd	TST_RDY 		; 010H
  3975 00002A49 [1D2E0000]          <1> 	dd	HDISK_RECAL		; 011H
  3976 00002A4D [BD2B0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  3977 00002A51 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  3978 00002A55 [532E0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  3979                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  3980 00002A59 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 015h
  3981 00002A5D [BD2B0000]          <1> 	dd	BAD_COMMAND		; 016h
  3982 00002A61 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 017h
  3983 00002A65 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 018h
  3984 00002A69 [BD2B0000]          <1> 	dd	BAD_COMMAND		; 019h
  3985 00002A6D [BD2B0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  3986 00002A71 [4B2C0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  3987 00002A75 [542C0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  3988                              <1> D1L     EQU    $ - D1
  3989                              <1> 
  3990                              <1> DISK_IO_CONT:
  3991                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3992 00002A79 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  3993                              <1> 	;;JNZ	short SU0
  3994                              <1>         ;;JMP    RETURN_STATUS
  3995 00002A7C 0F84BC010000        <1> 	je	RETURN_STATUS
  3996                              <1> SU0:
  3997 00002A82 C605[53D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3998                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  3999                              <1> 	;mov	si, bx ;; 14/02/2015
  4000 00002A89 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  4001 00002A8B 8A1D[54D30000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4002                              <1> 	;; 04/01/2015
  4003                              <1> 	;;PUSH	AX
  4004 00002A91 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  4005                              <1> 					; (get drive number as 0 to 3)
  4006 00002A94 38D3                <1> 	CMP	BL,DL
  4007                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  4008 00002A96 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  4009                              <1>         ;
  4010                              <1> 	;;03/01/2015
  4011 00002A9C 29DB                <1> 	sub	ebx, ebx
  4012 00002A9E 88D3                <1> 	mov	bl, dl
  4013                              <1> 	;sub	bh, bh
  4014 00002AA0 883D[68D30000]      <1> 	mov	[LBAMode], bh 	; 0
  4015                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  4016                              <1> 	;test	byte [ebx+hd0_type], 1
  4017                              <1> 	;jz	short su1		; no
  4018                              <1> 	;inc	byte [LBAMode]
  4019                              <1> ;su1:
  4020                              <1> 	; 21/02/2015 (32 bit modification)
  4021                              <1> 	;04/01/2015
  4022 00002AA6 6650                <1> 	push	ax ; ***
  4023                              <1> 	;PUSH	ES ; **
  4024 00002AA8 6652                <1> 	PUSH	DX ; *
  4025 00002AAA 6650                <1> 	push	ax
  4026 00002AAC E888060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  4027                              <1> 	; 02/02/2015
  4028                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  4029 00002AB1 668B4310            <1> 	mov	ax, [ebx+16]
  4030 00002AB5 66A3[B6CD0000]      <1> 	mov	[HF_PORT], ax
  4031                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  4032 00002ABB 668B5312            <1> 	mov	dx, [ebx+18]
  4033 00002ABF 668915[B8CD0000]    <1> 	mov	[HF_REG_PORT], dx
  4034                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  4035 00002AC6 8A4314              <1> 	mov	al, [ebx+20]
  4036                              <1> 	; 23/02/2015
  4037 00002AC9 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  4038 00002ACB 7406                <1> 	jz 	short su1
  4039 00002ACD FE05[68D30000]      <1> 	inc	byte [LBAMode] ; 1 
  4040                              <1> su1: 	 
  4041 00002AD3 C0E804              <1> 	shr 	al, 4
  4042 00002AD6 2401                <1> 	and	al, 1			
  4043 00002AD8 A2[BACD0000]        <1> 	mov	[hf_m_s], al 
  4044                              <1> 	;
  4045                              <1> 	; 03/01/2015
  4046                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  4047 00002ADD 8A4308              <1> 	mov	al, [ebx+8]
  4048                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  4049 00002AE0 EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  4050                              <1> 					; Control Byte:  (= 08h, here)
  4051                              <1> 					; bit 0 - 0
  4052                              <1> 					; bit 1 - nIEN (1 = disable irq)
  4053                              <1> 					; bit 2 - SRST (software RESET)
  4054                              <1> 					; bit 3 - use extra heads (8 to 15)
  4055                              <1> 					;         -always set to 1-	
  4056                              <1> 					; (bits 3 to 7 are reserved
  4057                              <1> 					;          for ATA devices)
  4058 00002AE1 8A25[55D30000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4059 00002AE7 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  4060 00002AEA 08C4                <1> 	OR	AH,AL
  4061 00002AEC 8825[55D30000]      <1> 	MOV	[CONTROL_BYTE],AH	
  4062                              <1> 	; 04/01/2015
  4063 00002AF2 6658                <1> 	pop	ax
  4064 00002AF4 665A                <1> 	pop	dx ; * ;; 14/02/2015
  4065 00002AF6 20E4                <1> 	and	ah, ah	; Reset function ?
  4066 00002AF8 7507                <1> 	jnz	short su2
  4067                              <1> 	;;pop	dx ; * ;; 14/02/2015
  4068                              <1> 	;pop	es ; **
  4069 00002AFA 6658                <1> 	pop	ax ; ***
  4070                              <1> 	;;pop	bx
  4071 00002AFC E9C6000000          <1>         jmp     DISK_RESET
  4072                              <1> su2:
  4073 00002B01 803D[68D30000]00    <1> 	cmp	byte [LBAMode], 0
  4074 00002B08 7661                <1> 	jna	short su3
  4075                              <1> 	;
  4076                              <1> 	; 02/02/2015 (LBA read/write function calls)
  4077 00002B0A 80FC1B              <1> 	cmp	ah, 1Bh
  4078 00002B0D 720B                <1> 	jb	short lbarw1
  4079 00002B0F 80FC1C              <1> 	cmp	ah, 1Ch
  4080 00002B12 775C                <1> 	ja 	short invldfnc
  4081                              <1> 	;;pop	dx ; * ; 14/02/2015
  4082                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  4083 00002B14 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  4084                              <1> 	;; 14/02/2015
  4085 00002B16 88D1                <1> 	mov	cl, dl ; 14/02/2015
  4086                              <1> 	;;mov	dx, bx
  4087                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  4088                              <1> 	;;mov	bx, di
  4089                              <1> 	;mov	si, di ; Buffer offset
  4090 00002B18 EB31                <1> 	jmp	short lbarw2
  4091                              <1> lbarw1:
  4092                              <1> 	; convert CHS to LBA
  4093                              <1> 	;
  4094                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  4095                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  4096                              <1> 	;	+ Sector - 1
  4097 00002B1A 6652                <1> 	push	dx ; * ;; 14/02/2015
  4098                              <1> 	;xor	dh, dh
  4099 00002B1C 31D2                <1> 	xor	edx, edx
  4100                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  4101 00002B1E 8A530E              <1> 	mov	dl, [ebx+14]
  4102                              <1> 	;xor	ah, ah
  4103 00002B21 31C0                <1> 	xor	eax, eax
  4104                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  4105 00002B23 8A4302              <1> 	mov	al, [ebx+2]
  4106 00002B26 FEC8                <1> 	dec	al
  4107 00002B28 6640                <1> 	inc	ax		; 0 =  256
  4108 00002B2A 66F7E2              <1> 	mul 	dx
  4109                              <1> 		; AX = # of Heads" * Sectors/Track
  4110 00002B2D 6689CA              <1> 	mov	dx, cx
  4111                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  4112 00002B30 83E13F              <1> 	and	ecx, 3fh
  4113 00002B33 86D6                <1> 	xchg	dl, dh
  4114 00002B35 C0EE06              <1> 	shr	dh, 6
  4115                              <1> 		; DX = cylinder (0 to 1023)
  4116                              <1> 	;mul 	dx
  4117                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  4118 00002B38 F7E2                <1> 	mul	edx
  4119 00002B3A FEC9                <1> 	dec	cl  ; sector - 1
  4120                              <1> 	;add	ax, cx
  4121                              <1> 	;adc	dx, 0
  4122                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  4123 00002B3C 01C8                <1> 	add	eax, ecx
  4124 00002B3E 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  4125                              <1> 	;push	dx
  4126                              <1> 	;push	ax
  4127 00002B40 50                  <1> 	push	eax
  4128                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  4129 00002B41 8A430E              <1> 	mov	al, [ebx+14]
  4130 00002B44 F6E5                <1> 	mul	ch
  4131                              <1> 		;  AX = Head * Sectors/Track
  4132 00002B46 6699                <1>         cwd
  4133                              <1> 	;pop	dx
  4134 00002B48 5A                  <1> 	pop	edx
  4135                              <1> 	;add	ax, dx
  4136                              <1> 	;pop	dx
  4137                              <1> 	;adc	dx, 0 ; add carry bit
  4138 00002B49 01D0                <1> 	add	eax, edx
  4139                              <1> lbarw2:
  4140 00002B4B 29D2                <1> 	sub	edx, edx ; 21/02/2015
  4141 00002B4D 88CA                <1> 	mov	dl, cl ; 21/02/2015
  4142 00002B4F C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  4143                              <1> 				; NOTE: Features register (1F1h, 171h)
  4144                              <1> 				; is not used for ATA device R/W functions. 
  4145                              <1> 				; It is old/obsolete 'write precompensation'
  4146                              <1> 				; register and error register
  4147                              <1> 				; for old ATA/IDE devices.
  4148                              <1> 	; 18/01/2014
  4149                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  4150 00002B53 8A0D[BACD0000]      <1> 	mov	cl, [hf_m_s]
  4151                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  4152                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  4153                              <1> 				; bit 6 = 1 = LBA mode
  4154                              <1> 				; bit 7 = 1
  4155 00002B59 80C90E              <1> 	or	cl, 0Eh ; 1110b
  4156                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  4157 00002B5C 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  4158 00002B61 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  4159                              <1> 	;or	dh, ch
  4160 00002B64 09C8                <1> 	or	eax, ecx	
  4161                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  4162                              <1> 				  ; (Sector Number Register)
  4163                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  4164                              <1> 				  ; (Cylinder Low Register)
  4165                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  4166                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  4167                              <1> 				  ; (Cylinder High Register)
  4168                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  4169                              <1> 				  ; (Drive/Head Register)
  4170                              <1> 	
  4171                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  4172 00002B66 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  4173                              <1> 	;14/02/2015
  4174                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  4175 00002B69 EB38                <1> 	jmp	short su4
  4176                              <1> su3:
  4177                              <1> 	; 02/02/2015 
  4178                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  4179 00002B6B 80FC14              <1> 	cmp 	ah, 14h
  4180 00002B6E 7604                <1> 	jna 	short chsfnc
  4181                              <1> invldfnc:
  4182                              <1>         ; 14/02/2015  
  4183                              <1> 	;pop	es ; **
  4184 00002B70 6658                <1>         pop     ax ; ***
  4185                              <1>         ;jmp     short BAD_COMMAND_POP
  4186 00002B72 EB49                <1>         jmp     short BAD_COMMAND
  4187                              <1> chsfnc:	
  4188                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  4189 00002B74 668B4305            <1> 	mov	ax, [ebx+5]
  4190 00002B78 66C1E802            <1> 	SHR	AX,2
  4191 00002B7C 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  4192                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  4193                              <1> 	;;PUSH	DX
  4194                              <1> 	;;MOV	DX,[HF_REG_PORT]
  4195                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  4196                              <1> 	;;POP	DX ; * 
  4197                              <1> 	;;POP	ES ; **
  4198                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4199                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  4200                              <1> 	;;OR	AH,AL
  4201                              <1> 	;;MOV	[CONTROL_BYTE],AH
  4202                              <1> 	;
  4203 00002B7F 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  4204 00002B81 243F                <1> 	AND	AL,3FH
  4205 00002B83 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  4206 00002B86 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  4207 00002B89 88C8                <1> 	MOV	AL,CL
  4208 00002B8B C0E806              <1> 	SHR	AL,6
  4209 00002B8E 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  4210                              <1> 	;;05/01/2015
  4211                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  4212 00002B91 A0[BACD0000]        <1> 	mov	al, [hf_m_s]
  4213 00002B96 C0E004              <1> 	SHL	AL,4
  4214 00002B99 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  4215 00002B9C 08F0                <1> 	OR	AL,DH
  4216                              <1> 	;OR	AL,80H or 20H
  4217 00002B9E 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  4218 00002BA0 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  4219                              <1> su4:
  4220                              <1> 	;POP	ES ; **
  4221                              <1>         ;; 14/02/2015
  4222                              <1>         ;;POP   AX
  4223                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  4224                              <1>         ;;PUSH  AX
  4225                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  4226                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  4227                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  4228 00002BA3 6658                <1>         pop     ax ; ***
  4229 00002BA5 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4230 00002BA8 29DB                <1>         sub	ebx, ebx
  4231 00002BAA 88E3                <1> 	mov     bl, ah
  4232                              <1>         ;xor     bh, bh
  4233                              <1>         ;sal     bx, 1
  4234 00002BAC 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  4235                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  4236                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  4237                              <1>         ;;JNB   short BAD_COMMAND_POP
  4238                              <1>         ;cmp     bx, D1L
  4239 00002BB0 83FB74              <1> 	cmp	ebx, D1L
  4240 00002BB3 7308                <1> 	jnb	short BAD_COMMAND
  4241                              <1>         ;xchg    bx, si
  4242 00002BB5 87DE                <1>         xchg	ebx, esi
  4243                              <1> 	;;;POP	AX			; RESTORE AX
  4244                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  4245                              <1> 	
  4246                              <1> 	;;PUSH	CX
  4247                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  4248                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  4249                              <1> 	;SHR	CX,4
  4250                              <1> 	;MOV	AX,ES
  4251                              <1> 	;ADD	AX,CX
  4252                              <1> 	;MOV	ES,AX
  4253                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  4254                              <1> 	;;POP	AX
  4255                              <1> 	;;POP	CX
  4256                              <1> 	;;JMP	word [CS:SI+D1]
  4257                              <1> 	;jmp	word [SI+D1]
  4258 00002BB7 FFA6[052A0000]      <1> 	jmp	dword [esi+D1]
  4259                              <1> ;;BAD_COMMAND_POP:
  4260                              <1> ;;	POP	AX
  4261                              <1> ;;	POP	BX
  4262                              <1> BAD_COMMAND:
  4263 00002BBD C605[53D30000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4264 00002BC4 B000                <1> 	MOV	AL,0
  4265 00002BC6 C3                  <1> 	RETn
  4266                              <1> 
  4267                              <1> ;----------------------------------------
  4268                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  4269                              <1> ;----------------------------------------
  4270                              <1> 
  4271                              <1> ; 18-1-2015 : one controller reset (not other one)
  4272                              <1> 
  4273                              <1> DISK_RESET:
  4274 00002BC7 FA                  <1> 	CLI
  4275 00002BC8 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4276                              <1> 	;JMP	$+2
  4277                              <1> 	IODELAY
  4277 00002BCA EB00                <2>  jmp short $+2
  4277 00002BCC EB00                <2>  jmp short $+2
  4278                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4279 00002BCE 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4280 00002BD0 E6A1                <1> 	OUT	INTB01,AL
  4281 00002BD2 FB                  <1> 	STI				; START INTERRUPTS
  4282                              <1> 	; 14/02/2015
  4283 00002BD3 6689D7              <1> 	mov	di, dx	
  4284                              <1> 	; 04/01/2015
  4285                              <1> 	;xor	di,di
  4286                              <1> drst0:
  4287 00002BD6 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4288                              <1> 	;MOV	DX,HF_REG_PORT
  4289 00002BD8 668B15[B8CD0000]    <1> 	MOV	DX,[HF_REG_PORT]
  4290 00002BDF EE                  <1> 	OUT	DX,AL			; RESET
  4291                              <1> ;	MOV	CX,10			; DELAY COUNT
  4292                              <1> ;DRD:	DEC	CX
  4293                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  4294                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  4295 00002BE0 B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4296 00002BE5 E848ECFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4297                              <1>                                         ; 40 micro seconds)
  4298 00002BEA A0[55D30000]        <1> 	mov	al,[CONTROL_BYTE]
  4299 00002BEF 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4300 00002BF1 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4301 00002BF2 E838040000          <1> 	CALL	NOT_BUSY
  4302 00002BF7 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4303 00002BF9 668B15[B6CD0000]    <1> 	MOV	DX,[HF_PORT]
  4304 00002C00 FEC2                <1> 	inc	dl  ; HF_PORT+1
  4305                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4306                              <1>         ;mov     cl, 10
  4307 00002C02 B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4308                              <1> drst1:
  4309 00002C07 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4310 00002C08 3C01                <1> 	CMP	AL,1
  4311                              <1> 	; 04/01/2015
  4312 00002C0A 740A                <1> 	jz	short drst2
  4313                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4314                              <1>         	; Drive/Head Register - bit 4
  4315 00002C0C E2F9                <1> 	loop	drst1
  4316                              <1> DRERR:	
  4317 00002C0E C605[53D30000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4318 00002C15 C3                  <1> 	RETn
  4319                              <1> drst2:
  4320                              <1> 	; 14/02/2015
  4321 00002C16 6689FA              <1> 	mov	dx,di
  4322                              <1> ;drst3:
  4323                              <1> ;	; 05/01/2015
  4324                              <1> ;	shl 	di,1
  4325                              <1> ;	; 04/01/2015
  4326                              <1> ;	mov	ax,[di+hd_cports]
  4327                              <1> ;	cmp	ax,[HF_REG_PORT]
  4328                              <1> ;	je	short drst4
  4329                              <1> ;	mov	[HF_REG_PORT], ax
  4330                              <1> ;	; 03/01/2015
  4331                              <1> ;	mov	ax,[di+hd_ports]
  4332                              <1> ;       mov     [HF_PORT], ax
  4333                              <1> ;	; 05/01/2014
  4334                              <1> ;	shr	di,1
  4335                              <1> ;	; 04/01/2015
  4336                              <1> ;	jmp	short drst0	; reset other controller
  4337                              <1> ;drst4:
  4338                              <1> ;	; 05/01/2015
  4339                              <1> ;	shr	di,1
  4340                              <1> ;	mov	al,[di+hd_dregs]
  4341                              <1> ;	and	al,10h ; bit 4 only
  4342                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  4343                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  4344                              <1> 	;
  4345 00002C19 A0[BACD0000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4346 00002C1E A801                <1> 	test	al,1
  4347                              <1> ;	jnz	short drst6
  4348 00002C20 7516                <1>         jnz     short drst4
  4349 00002C22 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4350                              <1> ;drst5:
  4351                              <1> drst3:
  4352 00002C26 E835010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4353                              <1> 	;mov	dx,di
  4354 00002C2B E8ED010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  4355                              <1> 	; 04/01/2014
  4356                              <1> ;	inc	di
  4357                              <1> ;	mov	dx,di
  4358                              <1> ;	cmp	dl,[HF_NUM]
  4359                              <1> ;	jb	short drst3
  4360                              <1> ;DRE:
  4361 00002C30 C605[53D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4362 00002C37 C3                  <1> 	RETn
  4363                              <1> ;drst6:
  4364                              <1> drst4:		; Drive/Head Register - bit 4
  4365 00002C38 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4366                              <1>         ;jmp    short drst5
  4367 00002C3C EBE8                <1>         jmp     short drst3
  4368                              <1> 
  4369                              <1> ;----------------------------------------
  4370                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  4371                              <1> ;----------------------------------------
  4372                              <1> 
  4373                              <1> RETURN_STATUS:
  4374 00002C3E A0[53D30000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4375 00002C43 C605[53D30000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4376 00002C4A C3                  <1> 	RETn
  4377                              <1> 
  4378                              <1> ;----------------------------------------
  4379                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4380                              <1> ;----------------------------------------
  4381                              <1> 
  4382                              <1> DISK_READ:
  4383 00002C4B C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4384 00002C4F E954020000          <1>         JMP     COMMANDI
  4385                              <1> 
  4386                              <1> ;----------------------------------------
  4387                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4388                              <1> ;----------------------------------------
  4389                              <1> 
  4390                              <1> DISK_WRITE:
  4391 00002C54 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4392 00002C58 E9A6020000          <1>         JMP     COMMANDO
  4393                              <1> 
  4394                              <1> ;----------------------------------------
  4395                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4396                              <1> ;----------------------------------------
  4397                              <1> 
  4398                              <1> DISK_VERF:
  4399 00002C5D C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4400 00002C61 E814030000          <1> 	CALL	COMMAND
  4401 00002C66 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4402 00002C68 E886030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4403 00002C6D 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4404 00002C6F E813040000          <1> 	CALL	CHECK_STATUS
  4405                              <1> VERF_EXIT:
  4406 00002C74 C3                  <1> 	RETn
  4407                              <1> 
  4408                              <1> ;----------------------------------------
  4409                              <1> ;	FORMATTING	     (AH = 05H) :
  4410                              <1> ;----------------------------------------
  4411                              <1> 
  4412                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  4413 00002C75 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4414                              <1> 	;PUSH	ES
  4415                              <1> 	;PUSH	BX
  4416 00002C79 53                  <1> 	push	ebx
  4417 00002C7A E8BA040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4418                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4419 00002C7F 8A430E              <1> 	mov	al, [ebx+14]
  4420 00002C82 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4421 00002C85 5B                  <1> 	pop	ebx
  4422                              <1> 	;POP	BX
  4423                              <1> 	;POP	ES
  4424 00002C86 E97F020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  4425                              <1> 
  4426                              <1> ;----------------------------------------
  4427                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  4428                              <1> ;----------------------------------------
  4429                              <1> 
  4430                              <1> READ_DASD_TYPE:
  4431                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  4432 00002C8B 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4433                              <1> 	;PUSH	ES
  4434 00002C8C 53                  <1> 	PUSH	eBX
  4435                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4436                              <1> 	;push	cs
  4437                              <1> 	;pop	ds
  4438 00002C8D 66BB1000            <1>         mov	bx, KDATA
  4439 00002C91 8EDB                <1> 	mov	ds, bx
  4440                              <1> 	;mov	es, bx
  4441 00002C93 C605[53D30000]00    <1> 	MOV     byte [DISK_STATUS1],0
  4442 00002C9A 8A1D[54D30000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4443 00002CA0 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4444 00002CA3 38D3                <1> 	CMP	BL,DL
  4445 00002CA5 7627                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4446 00002CA7 E88D040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  4447                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4448 00002CAC 8A4302              <1> 	mov	al, [ebx+2]
  4449                              <1> 	;MOV	CL,[ES:BX+14]
  4450 00002CAF 8A4B0E              <1> 	mov	cl, [ebx+14]
  4451 00002CB2 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4452                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4453 00002CB4 668B0B              <1> 	mov	cx ,[ebx]
  4454                              <1> 	;
  4455                              <1> 	; 02/01/2015 
  4456                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  4457                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  4458 00002CB7 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4459                              <1> 	;
  4460 00002CB9 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4461 00002CBC 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4462 00002CBF 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4463                              <1> 	;SUB	AX,AX
  4464 00002CC2 28C0                <1> 	sub	al, al
  4465 00002CC4 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4466 00002CC6 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  4467                              <1> 	;POP	ES
  4468 00002CC7 1F                  <1> 	POP	DS
  4469                              <1> 	; (*) CLC			; CLEAR CARRY
  4470                              <1> 	;RETf	2
  4471                              <1> 	; (*) 29/05/2016
  4472                              <1> 	; (*) retf 4
  4473 00002CC8 80642408FE          <1> 	and	byte [esp+8], 0FEh ; clear carry bit of eflags register
  4474 00002CCD CF                  <1> 	iretd
  4475                              <1> 
  4476                              <1> RDT_NOT_PRESENT:
  4477 00002CCE 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4478 00002CD1 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4479 00002CD4 6689C2              <1> 	MOV	DX,AX
  4480 00002CD7 EBED                <1> 	JMP	short RDT2
  4481                              <1> 
  4482                              <1> ; 28/05/2016
  4483                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  4484                              <1> 
  4485                              <1> ;----------------------------------------
  4486                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  4487                              <1> ;----------------------------------------
  4488                              <1> 
  4489                              <1> GET_PARM_N:
  4490                              <1> 	; ebx = user's buffer address for parameters table
  4491                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  4492 00002CD9 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4493 00002CDA 06                  <1> 	PUSH	ES
  4494 00002CDB 53                  <1> 	PUSH	eBX
  4495                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  4496                              <1> 	;MOV	DS,AX
  4497                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  4498                              <1> 	;JZ	short G0
  4499                              <1> 	;LES	BX,@HF1_TBL_VEC
  4500                              <1> 	;JMP	SHORT G1
  4501                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  4502                              <1> ;G1:
  4503                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  4504                              <1> 	; 22/12/2014
  4505                              <1> 	;push	cs
  4506                              <1> 	;pop	ds
  4507 00002CDC 66BB1000            <1> 	mov	bx, KDATA
  4508 00002CE0 8EDB                <1> 	mov	ds, bx
  4509 00002CE2 8EC3                <1> 	mov	es, bx	; 27/05/2016
  4510                              <1> 	;
  4511 00002CE4 80EA80              <1> 	SUB	DL,80H
  4512 00002CE7 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4513 00002CEA 7361                <1> 	JAE	short G4
  4514                              <1> 	;
  4515 00002CEC 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4516                              <1> 	; 22/12/2014
  4517 00002CEE 88D3                <1> 	mov	bl, dl
  4518                              <1> 	;xor	bh, bh  
  4519 00002CF0 C0E302              <1> 	shl	bl, 2			; convert index to offset
  4520                              <1> 	;add	bx, HF_TBL_VEC
  4521 00002CF3 81C3[58D30000]      <1> 	add	ebx, HF_TBL_VEC
  4522                              <1> 	;mov	ax, [bx+2]
  4523                              <1> 	;mov	es, ax			; dpt segment
  4524                              <1> 	;mov	bx, [bx]		; dpt offset
  4525 00002CF9 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4526                              <1> 
  4527 00002CFB C605[53D30000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4528                              <1>         ;MOV     AX,[ES:BX]             ; MAX NUMBER OF CYLINDERS
  4529 00002D02 668B03              <1> 	mov	ax, [ebx]
  4530                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4531 00002D05 6648                <1> 	dec	ax			; max. cylinder number
  4532 00002D07 88C5                <1> 	MOV	CH,AL
  4533 00002D09 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4534 00002D0D 66D1E8              <1> 	SHR	AX,1
  4535 00002D10 66D1E8              <1> 	SHR	AX,1
  4536                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4537 00002D13 0A430E              <1> 	or	al, [ebx+14]
  4538 00002D16 88C1                <1> 	MOV	CL,AL
  4539                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4540 00002D18 8A7302              <1> 	mov	dh, [ebx+2]
  4541 00002D1B FECE                <1> 	DEC	DH			; 0-N RANGE
  4542 00002D1D 8A15[54D30000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4543 00002D23 6629C0              <1> 	SUB	AX,AX
  4544                              <1>         ;27/12/2014 
  4545                              <1> 	;mov	di, bx			; HDPT offset
  4546                              <1> 	
  4547                              <1> 	; 27/05/2016
  4548                              <1> 	; return fixed disk parameters table to user
  4549                              <1> 	; in user's buffer, which is pointed by EBX
  4550                              <1> 	;
  4551 00002D26 873C24              <1> 	xchg	edi, [esp]		; ebx (input)-> edi, edi -> [esp]
  4552 00002D29 56                  <1> 	push	esi
  4553 00002D2A 89DE                <1> 	mov	esi, ebx		; hard disk parameter table (32 bytes)	
  4554 00002D2C 89FB                <1> 	mov	ebx, edi		; ebx = user's buffer address
  4555 00002D2E 51                  <1> 	push	ecx
  4556 00002D2F 50                  <1> 	push	eax
  4557 00002D30 B920000000          <1> 	mov	ecx, 32 ; 32 bytes
  4558 00002D35 E84B900000          <1> 	call	transfer_to_user_buffer ; trdosk6.s (16/05/2016)
  4559 00002D3A 58                  <1> 	pop	eax
  4560 00002D3B 59                  <1> 	pop	ecx
  4561 00002D3C 5E                  <1> 	pop	esi
  4562 00002D3D 5F                  <1> 	pop	edi
  4563 00002D3E 730A                <1> 	jnc	short G5
  4564                              <1> 	; 29/05/2016 (*)
  4565 00002D40 B8FF000000          <1> 	mov	eax, 0FFh ; unknown error !
  4566                              <1> _G6:
  4567 00002D45 804C241001          <1> 	or	byte [esp+16], 1 ; set carry bit of eflags register
  4568                              <1> G5:
  4569                              <1> 	; 27/05/2016
  4570                              <1> 	;POP	eBX			; RESTORE REGISTERS
  4571 00002D4A 07                  <1> 	POP	ES
  4572 00002D4B 1F                  <1> 	POP	DS
  4573                              <1> 	;RETf	2
  4574                              <1> 	; (*) 29/05/2016
  4575                              <1> 	; (*) retf 4
  4576                              <1> 	; (*) or byte [esp+8], 1 ; set carry bit of eflags register
  4577 00002D4C CF                  <1> 	iretd
  4578                              <1> G4:
  4579 00002D4D C605[53D30000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4580 00002D54 B407                <1> 	MOV	AH,INIT_FAIL
  4581 00002D56 28C0                <1> 	SUB	AL,AL
  4582 00002D58 6629D2              <1> 	SUB	DX,DX
  4583 00002D5B 6629C9              <1> 	SUB	CX,CX
  4584                              <1> 	; 29/05/2016 (*)
  4585                              <1> 	;STC				; SET ERROR FLAG
  4586                              <1> 	;JMP	short G5
  4587 00002D5E EBE5                <1> 	jmp	short _G6
  4588                              <1> 
  4589                              <1> ;----------------------------------------
  4590                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  4591                              <1> ;----------------------------------------
  4592                              <1> 	; 03/01/2015
  4593                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  4594                              <1> 	; logical sector per logical track
  4595                              <1> 	; and logical heads - 1 would be set but
  4596                              <1> 	; it is seen as it will be good
  4597                              <1> 	; if physical parameters will be set here
  4598                              <1> 	; because, number of heads <= 16.
  4599                              <1> 	; (logical heads usually more than 16)
  4600                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  4601                              <1> 	;	== INT 13h physical parameters
  4602                              <1> 
  4603                              <1> ;INIT_DRV:
  4604                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  4605                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  4606                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  4607                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  4608                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  4609                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  4610                              <1> ;	OR	AH,AL			; TO MAX HEAD
  4611                              <1> ;	MOV	[CMD_BLOCK+5],AH
  4612                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  4613                              <1> ;	MOV	[CMD_BLOCK+1],AL
  4614                              <1> ;	SUB	AX,AX
  4615                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  4616                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  4617                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  4618                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  4619                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  4620                              <1> ;	CALL	CHECK_STATUS
  4621                              <1> ;INIT_EXIT:
  4622                              <1> ;	RETn
  4623                              <1> 
  4624                              <1> ; 04/01/2015
  4625                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  4626                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  4627                              <1> INIT_DRV:
  4628                              <1> 	;xor	ah,ah
  4629 00002D60 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4630 00002D62 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4631 00002D64 3825[68D30000]      <1>         cmp     [LBAMode], ah   ; 0
  4632 00002D6A 7702                <1> 	ja	short idrv0
  4633 00002D6C B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4634                              <1> idrv0:
  4635                              <1> 	; DL = drive number (0 based)
  4636 00002D6E E8C6030000          <1> 	call	GET_VEC
  4637                              <1> 	;push	bx
  4638 00002D73 53                  <1> 	push	ebx ; 21/02/2015
  4639                              <1> 	;add	bx,ax
  4640 00002D74 01C3                <1> 	add	ebx, eax
  4641                              <1> 	;; 05/01/2015
  4642 00002D76 8A25[BACD0000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4643                              <1> 	;;and 	ah,1 
  4644 00002D7C C0E404              <1> 	shl	ah,4
  4645 00002D7F 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4646                              <1> 	;mov	al,[es:bx]
  4647 00002D82 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4648 00002D84 FEC8                <1> 	dec	al	 ; last head number 
  4649                              <1> 	;and	al,0Fh
  4650 00002D86 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4651                              <1> 	;
  4652 00002D88 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4653 00002D8C 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4654                              <1> 	;pop	bx
  4655 00002D8F 5B                  <1> 	pop	ebx
  4656 00002D90 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4657 00002D92 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4658 00002D94 803D[68D30000]00    <1> 	cmp	byte [LBAMode], 0
  4659 00002D9B 7702                <1> 	ja	short idrv1
  4660 00002D9D B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  4661                              <1> idrv1:
  4662                              <1> 	;xor	ah,ah
  4663                              <1> 	;add	bx,ax
  4664 00002D9F 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4665                              <1> 	;mov	al,[es:bx]
  4666                              <1> 			; sector number
  4667 00002DA1 8A03                <1> 	mov	al, [ebx]
  4668 00002DA3 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4669 00002DA6 28C0                <1> 	sub	al,al
  4670 00002DA8 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4671 00002DAB E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4672 00002DB0 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4673 00002DB2 E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4674 00002DB7 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4675 00002DB9 E8C9020000          <1> 	call	CHECK_STATUS
  4676                              <1> INIT_EXIT:
  4677 00002DBE C3                  <1> 	RETn
  4678                              <1> 
  4679                              <1> ;----------------------------------------
  4680                              <1> ;	READ LONG	     (AH = 0AH) :
  4681                              <1> ;----------------------------------------
  4682                              <1> 
  4683                              <1> RD_LONG:
  4684                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  4685 00002DBF C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4686 00002DC3 E9E0000000          <1>         JMP     COMMANDI
  4687                              <1> 
  4688                              <1> ;----------------------------------------
  4689                              <1> ;	WRITE LONG	     (AH = 0BH) :
  4690                              <1> ;----------------------------------------
  4691                              <1> 
  4692                              <1> WR_LONG:
  4693                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  4694 00002DC8 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4695 00002DCC E932010000          <1>         JMP     COMMANDO
  4696                              <1> 
  4697                              <1> ;----------------------------------------
  4698                              <1> ;	SEEK		     (AH = 0CH) :
  4699                              <1> ;----------------------------------------
  4700                              <1> 
  4701                              <1> DISK_SEEK:
  4702 00002DD1 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4703 00002DD5 E8A0010000          <1> 	CALL	COMMAND
  4704 00002DDA 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4705 00002DDC E812020000          <1> 	CALL	_WAIT
  4706 00002DE1 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4707 00002DE3 E89F020000          <1> 	CALL	CHECK_STATUS
  4708 00002DE8 803D[53D30000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4709 00002DEF 7507                <1> 	JNE	short DS_EXIT
  4710 00002DF1 C605[53D30000]00    <1>         MOV     byte [DISK_STATUS1],0
  4711                              <1> DS_EXIT:
  4712 00002DF8 C3                  <1> 	RETn
  4713                              <1> 
  4714                              <1> ;----------------------------------------
  4715                              <1> ;	TEST DISK READY      (AH = 10H) :
  4716                              <1> ;----------------------------------------
  4717                              <1> 
  4718                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  4719 00002DF9 E831020000          <1> 	CALL	NOT_BUSY
  4720 00002DFE 751C                <1> 	JNZ	short TR_EX
  4721 00002E00 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4722 00002E03 668B15[B6CD0000]    <1> 	MOV	DX,[HF_PORT]
  4723 00002E0A 80C206              <1> 	add	dl,6
  4724 00002E0D EE                  <1> 	OUT	DX,AL
  4725 00002E0E E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4726 00002E13 7507                <1> 	JNZ	short TR_EX
  4727 00002E15 C605[53D30000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4728                              <1> TR_EX:	
  4729 00002E1C C3                  <1> 	RETn
  4730                              <1> 
  4731                              <1> ;----------------------------------------
  4732                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4733                              <1> ;----------------------------------------
  4734                              <1> 
  4735                              <1> HDISK_RECAL:
  4736 00002E1D C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4737 00002E21 E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4738 00002E26 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4739 00002E28 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4740 00002E2D 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4741 00002E2F E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4742 00002E34 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4743                              <1> RECAL_X:
  4744 00002E36 E84C020000          <1> 	CALL	CHECK_STATUS
  4745 00002E3B 803D[53D30000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4746 00002E42 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4747 00002E44 C605[53D30000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4748                              <1> RECAL_EXIT:
  4749 00002E4B 803D[53D30000]00    <1>         CMP     byte [DISK_STATUS1],0
  4750 00002E52 C3                  <1> 	RETn
  4751                              <1> 
  4752                              <1> ;----------------------------------------
  4753                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4754                              <1> ;----------------------------------------
  4755                              <1> 
  4756                              <1> CTLR_DIAGNOSTIC:
  4757 00002E53 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4758 00002E54 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4759                              <1> 	;AND	AL,0BFH
  4760 00002E56 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4761                              <1> 	;JMP	$+2
  4762                              <1> 	IODELAY
  4762 00002E58 EB00                <2>  jmp short $+2
  4762 00002E5A EB00                <2>  jmp short $+2
  4763 00002E5C E6A1                <1> 	OUT	INTB01,AL
  4764                              <1> 	IODELAY
  4764 00002E5E EB00                <2>  jmp short $+2
  4764 00002E60 EB00                <2>  jmp short $+2
  4765 00002E62 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4766 00002E64 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4767                              <1> 	;JMP	$+2
  4768                              <1> 	IODELAY
  4768 00002E66 EB00                <2>  jmp short $+2
  4768 00002E68 EB00                <2>  jmp short $+2
  4769 00002E6A E621                <1> 	OUT	INTA01,AL
  4770 00002E6C FB                  <1> 	STI
  4771 00002E6D E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4772 00002E72 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4773                              <1> 	;MOV	DX, HF_PORT+7
  4774 00002E74 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4775 00002E7B 80C207              <1> 	add	dl, 7
  4776 00002E7E B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4777 00002E80 EE                  <1> 	OUT	DX,AL
  4778 00002E81 E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4779 00002E86 B480                <1> 	MOV	AH,TIME_OUT
  4780 00002E88 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4781                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4782 00002E8A 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4783 00002E91 FEC2                <1> 	inc	dl
  4784 00002E93 EC                  <1> 	IN	AL,DX
  4785 00002E94 A2[4AD30000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4786 00002E99 B400                <1> 	MOV	AH,0
  4787 00002E9B 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4788 00002E9D 7402                <1> 	JE	SHORT CD_EXIT
  4789 00002E9F B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4790                              <1> CD_EXIT:
  4791 00002EA1 8825[53D30000]      <1> 	MOV	[DISK_STATUS1],AH
  4792 00002EA7 C3                  <1> 	RETn
  4793                              <1> 
  4794                              <1> ;----------------------------------------
  4795                              <1> ; COMMANDI				:
  4796                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  4797                              <1> ;	NSECTOR RETURNS ZERO		:
  4798                              <1> ;----------------------------------------
  4799                              <1> COMMANDI:
  4800 00002EA8 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4801 00002EAD 7253                <1> 	JC	short CMD_ABORT
  4802                              <1> 	;MOV	DI,BX
  4803 00002EAF 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4804 00002EB1 E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4805 00002EB6 754A                <1> 	JNZ	short CMD_ABORT
  4806                              <1> CMD_I1:
  4807 00002EB8 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4808 00002EBD 7543                <1> 	JNZ	short TM_OUT		; TIME OUT
  4809                              <1> cmd_i1x: ; 18/02/2016
  4810                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  4811 00002EBF B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4812                              <1> 	;MOV	DX,HF_PORT
  4813 00002EC4 668B15[B6CD0000]    <1> 	mov	dx,[HF_PORT]
  4814 00002ECB FA                  <1> 	CLI
  4815 00002ECC FC                  <1> 	CLD
  4816 00002ECD F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4817 00002ED0 FB                  <1> 	STI
  4818 00002ED1 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4819 00002ED5 7419                <1> 	JZ	short CMD_I3
  4820 00002ED7 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4821 00002EDC 7224                <1> 	JC	short TM_OUT
  4822                              <1> 	;MOV	DX,HF_PORT
  4823 00002EDE 668B15[B6CD0000]    <1> 	mov	dx,[HF_PORT]
  4824                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4825 00002EE5 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4826 00002EEA EC                  <1> CMD_I2: IN	AL,DX
  4827                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4828 00002EEB 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4829 00002EED 47                  <1> 	INC	eDI
  4830 00002EEE E2FA                <1> 	LOOP	CMD_I2
  4831                              <1> CMD_I3: 
  4832                              <1> 	; wait for 400 ns
  4833 00002EF0 80C207              <1> 	add 	dl, 7
  4834 00002EF3 EC                  <1> 	in	al, dx
  4835 00002EF4 EC                  <1> 	in	al, dx
  4836 00002EF5 EC                  <1> 	in	al, dx
  4837                              <1> 	;
  4838 00002EF6 E88C010000          <1> 	CALL	CHECK_STATUS
  4839 00002EFB 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4840 00002EFD FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4841                              <1> 	;JNZ	SHORT CMD_I1
  4842 00002F00 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4843                              <1> CMD_ABORT:
  4844 00002F02 C3                  <1> TM_OUT: RETn
  4845                              <1> 
  4846                              <1> ;----------------------------------------
  4847                              <1> ; COMMANDO				:
  4848                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  4849                              <1> ;	NSECTOR RETURNS ZERO		:
  4850                              <1> ;----------------------------------------
  4851                              <1> COMMANDO:
  4852 00002F03 E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4853 00002F08 72F8                <1> 	JC	short CMD_ABORT
  4854 00002F0A 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4855 00002F0C E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4856 00002F11 75EF                <1> 	JNZ	short CMD_ABORT
  4857 00002F13 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4858 00002F18 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  4859                              <1> CMD_O1: ;PUSH	DS
  4860                              <1> 	;PUSH	ES			; MOVE ES TO DS
  4861                              <1> 	;POP	DS
  4862                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  4863                              <1> 	;MOV	DX,HF_PORT
  4864                              <1> 	; 01/02/2015
  4865 00002F1A 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4866                              <1> 	;push	es
  4867                              <1> 	;pop	ds
  4868                              <1> 	;mov	cx, 256
  4869 00002F21 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4870 00002F26 FA                  <1> 	CLI
  4871 00002F27 FC                  <1> 	CLD
  4872 00002F28 F3666F              <1> 	REP	OUTSW
  4873 00002F2B FB                  <1> 	STI
  4874                              <1> 	;POP	DS			; RESTORE DS
  4875 00002F2C F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4876 00002F30 7419                <1> 	JZ	short CMD_O3
  4877 00002F32 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4878 00002F37 72C9                <1> 	JC	short TM_OUT
  4879                              <1> 	;MOV	DX,HF_PORT
  4880 00002F39 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4881                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4882 00002F40 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4883                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  4884 00002F45 8A06                <1> 	mov	al, [esi]
  4885 00002F47 EE                  <1> 	OUT	DX,AL
  4886 00002F48 46                  <1> 	INC	eSI
  4887 00002F49 E2FA                <1> 	LOOP	CMD_O2
  4888                              <1> CMD_O3:
  4889 00002F4B E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  4890 00002F50 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  4891 00002F52 E830010000          <1> 	CALL	CHECK_STATUS
  4892 00002F57 75A9                <1> 	JNZ	short CMD_ABORT
  4893 00002F59 F605[49D30000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  4894 00002F60 75B8                <1> 	JNZ	SHORT CMD_O1
  4895                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  4896 00002F62 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4897                              <1> 	;add	dl, 2
  4898 00002F69 FEC2                <1> 	inc	dl
  4899 00002F6B FEC2                <1> 	inc	dl
  4900 00002F6D EC                  <1> 	IN	AL,DX			;
  4901 00002F6E A8FF                <1> 	TEST	AL,0FFH 		;
  4902 00002F70 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  4903 00002F72 C605[53D30000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  4904                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  4905                              <1> CMD_O4:
  4906 00002F79 C3                  <1> 	RETn
  4907                              <1> 
  4908                              <1> ;--------------------------------------------------------
  4909                              <1> ; COMMAND						:
  4910                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  4911                              <1> ; OUTPUT						:
  4912                              <1> ;	BL = STATUS					:
  4913                              <1> ;	BH = ERROR REGISTER				:
  4914                              <1> ;--------------------------------------------------------
  4915                              <1> 
  4916                              <1> COMMAND:
  4917 00002F7A 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  4918                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  4919                              <1> COMMAND1:
  4920                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  4921 00002F7B E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  4922                              <1> 	;;POP	CX
  4923 00002F80 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  4924 00002F82 803D[53D30000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  4925                              <1> 	;JZ	short CMD_TIMEOUT
  4926                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  4927                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  4928 00002F89 7507                <1> 	jne	short COMMAND4
  4929                              <1> CMD_TIMEOUT:
  4930 00002F8B C605[53D30000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4931                              <1> COMMAND4:
  4932 00002F92 5B                  <1> 	POP	eBX
  4933 00002F93 803D[53D30000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  4934 00002F9A C3                  <1> 	RETn
  4935                              <1> COMMAND2:
  4936 00002F9B 5B                  <1> 	POP	eBX
  4937 00002F9C 57                  <1> 	PUSH	eDI
  4938 00002F9D C605[4BD30000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  4939 00002FA4 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  4940 00002FA5 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4941                              <1> 	;AND	AL,0BFH
  4942 00002FA7 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  4943                              <1> 	;JMP	$+2
  4944                              <1> 	IODELAY
  4944 00002FA9 EB00                <2>  jmp short $+2
  4944 00002FAB EB00                <2>  jmp short $+2
  4945 00002FAD E6A1                <1> 	OUT	INTB01,AL
  4946 00002FAF E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4947 00002FB1 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4948                              <1> 	;JMP	$+2
  4949                              <1> 	IODELAY
  4949 00002FB3 EB00                <2>  jmp short $+2
  4949 00002FB5 EB00                <2>  jmp short $+2
  4950 00002FB7 E621                <1> 	OUT	INTA01,AL
  4951 00002FB9 FB                  <1> 	STI
  4952 00002FBA 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  4953                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  4954 00002FBC 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  4955 00002FC3 FEC2                <1> 	inc	dl
  4956 00002FC5 F605[55D30000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  4957 00002FCC 7411                <1> 	JZ	short COMMAND3
  4958 00002FCE 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  4959 00002FD1 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  4960 00002FD3 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  4961 00002FD5 7208                <1> 	JB	short COMMAND3
  4962 00002FD7 3C40                <1> 	CMP	AL,40H
  4963 00002FD9 7704                <1> 	JA	short COMMAND3
  4964 00002FDB 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  4965                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  4966                              <1> COMMAND3:
  4967 00002FDF 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  4968 00002FE3 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  4969                              <1> 	IODELAY
  4969 00002FE4 EB00                <2>  jmp short $+2
  4969 00002FE6 EB00                <2>  jmp short $+2
  4970 00002FE8 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  4971 00002FE9 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  4972 00002FEB 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  4973 00002FEF 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  4974 00002FF1 5F                  <1> 	POP	eDI
  4975 00002FF2 C3                  <1> 	RETn				; ZERO FLAG IS SET
  4976                              <1> 
  4977                              <1> ;CMD_TIMEOUT:
  4978                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4979                              <1> ;COMMAND4:
  4980                              <1> ;	POP	BX
  4981                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4982                              <1> ;	RETn
  4983                              <1> 
  4984                              <1> ;----------------------------------------
  4985                              <1> ;	WAIT FOR INTERRUPT		:
  4986                              <1> ;----------------------------------------
  4987                              <1> ;WAIT:
  4988                              <1> _WAIT:
  4989 00002FF3 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4990                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4991                              <1> 	;CLC
  4992                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  4993                              <1> 	;INT	15H
  4994                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  4995                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  4996                              <1> 
  4997                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  4998                              <1> 	;; 21/02/2015
  4999                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  5000                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  5001 00002FF4 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  5002                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  5003                              <1> ;-----	WAIT LOOP
  5004                              <1> 
  5005                              <1> WT1:	
  5006                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  5007 00002FF9 F605[4BD30000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  5008                              <1> 	;LOOPZ	WT1
  5009 00003000 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  5010                              <1> 	;DEC	BL
  5011                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  5012                              <1> 
  5013                              <1> WT1_hi:
  5014 00003002 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  5015 00003004 A810                <1> 	test	al, 10h			; transition on memory
  5016 00003006 75FA                <1> 	jnz	short WT1_hi		; refresh.
  5017                              <1> WT1_lo:
  5018 00003008 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  5019 0000300A A810                <1> 	test	al, 10h			
  5020 0000300C 74FA                <1> 	jz	short WT1_lo
  5021 0000300E E2E9                <1> 	loop	WT1
  5022                              <1> 	;;or	bl, bl
  5023                              <1> 	;;jz	short WT2	
  5024                              <1> 	;;dec	bl
  5025                              <1> 	;;jmp	short WT1
  5026                              <1> 	;dec	bl
  5027                              <1> 	;jnz	short WT1	
  5028                              <1> 
  5029 00003010 C605[53D30000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  5030 00003017 EB0E                <1> 	JMP	SHORT WT4
  5031 00003019 C605[53D30000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  5032 00003020 C605[4BD30000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  5033 00003027 803D[53D30000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5034 0000302E C3                  <1> 	RETn
  5035                              <1> 
  5036                              <1> ;----------------------------------------
  5037                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  5038                              <1> ;----------------------------------------
  5039                              <1> NOT_BUSY:
  5040 0000302F FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  5041                              <1> 	;PUSH	eBX
  5042                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  5043 00003030 668B15[B6CD0000]    <1> 	mov	DX, [HF_PORT]
  5044 00003037 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  5045                              <1> 	;MOV	BL,DELAY_1
  5046                              <1> 					; wait for 10 seconds
  5047                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  5048                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  5049                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  5050 0000303A B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  5051                              <1> 	;
  5052                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  5053                              <1> NB1:	
  5054 0000303F EC                  <1> 	IN	AL,DX			; CHECK STATUS
  5055                              <1> 	;TEST	AL,ST_BUSY
  5056 00003040 2480                <1> 	and	al, ST_BUSY
  5057                              <1> 	;LOOPNZ	NB1
  5058 00003042 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  5059                              <1> 	;DEC	BL			
  5060                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  5061                              <1> 
  5062 00003044 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  5063 00003046 A810                <1> 	TEST	AL,010H			; transition on memory
  5064 00003048 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  5065 0000304A E461                <1> NB1_lo: IN	AL,SYS1
  5066 0000304C A810                <1> 	TEST	AL,010H
  5067 0000304E 74FA                <1> 	JZ	short NB1_lo
  5068 00003050 E2ED                <1> 	LOOP	NB1
  5069                              <1> 	;dec	bl
  5070                              <1> 	;jnz	short NB1
  5071                              <1> 	;
  5072                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  5073                              <1> ;;	jb	short NB1
  5074                              <1> 	;
  5075                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  5076                              <1> 	;JMP	SHORT NB3
  5077 00003052 B080                <1> 	mov	al, TIME_OUT
  5078                              <1> NB2:	
  5079                              <1> 	;MOV	byte [DISK_STATUS1],0
  5080                              <1> ;NB3:	
  5081                              <1> 	;POP	eBX
  5082 00003054 A2[53D30000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  5083                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5084 00003059 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  5085 0000305B C3                  <1> 	RETn
  5086                              <1> 
  5087                              <1> ;----------------------------------------
  5088                              <1> ;	WAIT FOR DATA REQUEST		:
  5089                              <1> ;----------------------------------------
  5090                              <1> WAIT_DRQ:
  5091                              <1> 	;MOV	CX,DELAY_3
  5092                              <1> 	;MOV	DX,HF_PORT+7
  5093 0000305C 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  5094 00003063 80C207              <1> 	add	dl, 7
  5095                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  5096                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  5097                              <1> 					; (but it is written as 2000
  5098                              <1> 					; micro seconds in ATORGS.ASM file
  5099                              <1> 					; of Award Bios - 1999, D1A0622)
  5100 00003066 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  5101 0000306B EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  5102 0000306C A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  5103 0000306E 7516                <1> 	JNZ	short WQ_OK
  5104                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  5105                              <1> WQ_hi:	
  5106 00003070 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  5107 00003072 A810                <1> 	TEST	AL,010H			; transition on memory
  5108 00003074 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  5109 00003076 E461                <1> WQ_lo:  IN      AL,SYS1
  5110 00003078 A810                <1> 	TEST	AL,010H
  5111 0000307A 74FA                <1> 	JZ	SHORT WQ_lo
  5112 0000307C E2ED                <1> 	LOOP	WQ_1
  5113                              <1> 
  5114 0000307E C605[53D30000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  5115 00003085 F9                  <1> 	STC
  5116                              <1> WQ_OK:
  5117 00003086 C3                  <1> 	RETn
  5118                              <1> ;WQ_OK:	;CLC
  5119                              <1> ;	RETn
  5120                              <1> 
  5121                              <1> ;----------------------------------------
  5122                              <1> ;	CHECK FIXED DISK STATUS 	:
  5123                              <1> ;----------------------------------------
  5124                              <1> CHECK_STATUS:
  5125 00003087 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  5126 0000308C 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  5127 0000308E A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  5128 00003090 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  5129 00003092 E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  5130                              <1> CHECK_S1:
  5131 00003097 803D[53D30000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  5132 0000309E C3                  <1> 	RETn
  5133                              <1> 
  5134                              <1> ;----------------------------------------
  5135                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  5136                              <1> ;----------------------------------------
  5137                              <1> CHECK_ST:
  5138                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  5139 0000309F 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]
  5140 000030A6 80C207              <1> 	add	dl, 7
  5141                              <1> 	
  5142                              <1> 	; 17/02/2016
  5143                              <1> 	;(http://wiki.osdev.org/ATA_PIO_Mode)
  5144                              <1> 	;"delay 400ns to allow drive to set new values of BSY and DRQ"
  5145 000030A9 EC                  <1> 	IN	AL,DX
  5146                              <1> 	;in	al, dx ; 100ns
  5147                              <1> 	;in	al, dx ; 100ns
  5148                              <1>  	;in	al, dx ; 100ns
  5149                              <1> 	NEWIODELAY ; 18/02/2016 (AWARD BIOS - 1999, 'CKST' in AHSDK.ASM)
  5149 000030AA E6EB                <2>  out 0ebh,al
  5150                              <1> 	;
  5151 000030AC A2[49D30000]        <1> 	MOV	[HF_STATUS],AL
  5152 000030B1 B400                <1> 	MOV	AH,0
  5153 000030B3 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  5154 000030B5 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  5155 000030B7 B4CC                <1> 	MOV	AH,WRITE_FAULT
  5156 000030B9 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  5157 000030BB 7514                <1> 	JNZ	short CKST_EXIT
  5158 000030BD B4AA                <1> 	MOV	AH,NOT_RDY
  5159 000030BF A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  5160 000030C1 740E                <1> 	JZ	short CKST_EXIT
  5161 000030C3 B440                <1> 	MOV	AH,BAD_SEEK
  5162 000030C5 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  5163 000030C7 7408                <1> 	JZ	short CKST_EXIT
  5164 000030C9 B411                <1> 	MOV	AH,DATA_CORRECTED
  5165 000030CB A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  5166 000030CD 7502                <1> 	JNZ	short CKST_EXIT
  5167 000030CF B400                <1> 	MOV	AH,0
  5168                              <1> CKST_EXIT:
  5169 000030D1 8825[53D30000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  5170 000030D7 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  5171 000030DA 7403                <1> 	JZ	short CKST_EX1
  5172 000030DC 80FC00              <1> 	CMP	AH,0
  5173                              <1> CKST_EX1:
  5174 000030DF C3                  <1> 	RETn
  5175                              <1> 
  5176                              <1> ;----------------------------------------
  5177                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  5178                              <1> ;----------------------------------------
  5179                              <1> CHECK_ER:
  5180                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  5181 000030E0 668B15[B6CD0000]    <1> 	mov	dx, [HF_PORT]		;
  5182 000030E7 FEC2                <1> 	inc	dl
  5183 000030E9 EC                  <1> 	IN	AL,DX
  5184 000030EA A2[4AD30000]        <1> 	MOV	[HF_ERROR],AL
  5185 000030EF 53                  <1> 	PUSH	eBX ; 21/02/2015
  5186 000030F0 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  5187 000030F5 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  5188 000030F7 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  5189 000030F9 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  5190 000030FB BB[AACD0000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  5191 00003100 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  5192                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  5193                              <1> 	;mov	ah, [bx]
  5194 00003102 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  5195 00003104 8825[53D30000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  5196 0000310A 5B                  <1> 	POP	eBX
  5197 0000310B 80FC00              <1> 	CMP	AH,0
  5198 0000310E C3                  <1> 	RETn
  5199                              <1> 
  5200                              <1> ;--------------------------------------------------------
  5201                              <1> ; CHECK_DMA						:
  5202                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  5203                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  5204                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  5205                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  5206                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  5207                              <1> ;  -ERROR OTHERWISE					:
  5208                              <1> ;--------------------------------------------------------
  5209                              <1> CHECK_DMA:
  5210 0000310F 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  5211 00003111 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  5212 00003115 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  5213 00003119 7404                <1> 	JZ	short CKD1
  5214 0000311B 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  5215 0000311F 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  5216 00003122 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  5217 00003124 7208                <1> 	JB	short CKDERR		; TOO MANY
  5218 00003126 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  5219 00003128 7204                <1> 	JB	short CKDERR		; ERROR
  5220 0000312A F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  5221 0000312B 6658                <1> 	POP	AX
  5222 0000312D C3                  <1> 	RETn				; NORMAL RETURN
  5223 0000312E F9                  <1> CKDERR: STC				; INDICATE ERROR
  5224 0000312F C605[53D30000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  5225 00003136 6658                <1> 	POP	AX
  5226 00003138 C3                  <1> 	RETn
  5227                              <1> 
  5228                              <1> ;----------------------------------------
  5229                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  5230                              <1> ;----------------------------------------
  5231                              <1> 					
  5232                              <1> ; INPUT -> DL = 0 based drive number
  5233                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  5234                              <1> 
  5235                              <1> GET_VEC:
  5236                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  5237                              <1> 	;MOV	ES,AX
  5238                              <1> 	;TEST	DL,1
  5239                              <1> 	;JZ	short GV_0
  5240                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  5241                              <1> ;	JMP	SHORT GV_EXIT
  5242                              <1> ;GV_0:
  5243                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  5244                              <1> ;
  5245                              <1> 	;xor	bh, bh
  5246 00003139 31DB                <1> 	xor	ebx, ebx
  5247 0000313B 88D3                <1> 	mov	bl, dl
  5248                              <1> 	;;02/01/2015
  5249                              <1> 	;;shl	bl, 1			; port address offset
  5250                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  5251                              <1> 	;;shl	bl, 1			; dpt pointer offset
  5252 0000313D C0E302              <1> 	shl	bl, 2	;;
  5253                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  5254 00003140 81C3[58D30000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  5255                              <1> 	;push	word [bx+2]		; dpt segment
  5256                              <1> 	;pop	es
  5257                              <1> 	;mov	bx, [bx]		; dpt offset
  5258 00003146 8B1B                <1> 	mov	ebx, [ebx]		
  5259                              <1> ;GV_EXIT:
  5260 00003148 C3                  <1> 	RETn
  5261                              <1> 
  5262                              <1> hdc1_int: ; 21/02/2015
  5263                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  5264                              <1> ;								:
  5265                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5266                              <1> ;								:
  5267                              <1> ;----------------------------------------------------------------
  5268                              <1> 
  5269                              <1> ; 22/12/2014
  5270                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  5271                              <1> ;	 '11/15/85'
  5272                              <1> ; AWARD BIOS 1999 (D1A0622) 
  5273                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  5274                              <1> 
  5275                              <1> ;int_76h:
  5276                              <1> HD_INT:
  5277 00003149 6650                <1> 	PUSH	AX
  5278 0000314B 1E                  <1> 	PUSH	DS
  5279                              <1> 	;CALL	DDS
  5280                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5281 0000314C 66B81000            <1> 	mov	ax, KDATA
  5282 00003150 8ED8                <1> 	mov 	ds, ax
  5283                              <1> 	;
  5284                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5285                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  5286 00003152 C605[4BD30000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5287                              <1> 	;
  5288 00003159 6652                <1> 	push	dx
  5289 0000315B 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5290                              <1> 					; Clear Controller
  5291                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5292 0000315F EC                  <1> 	in	al, dx			;
  5293 00003160 665A                <1> 	pop	dx
  5294                              <1> 	NEWIODELAY
  5294 00003162 E6EB                <2>  out 0ebh,al
  5295                              <1> 	;
  5296 00003164 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5297 00003166 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5298                              <1> 	;JMP	$+2			; WAIT
  5299                              <1> 	NEWIODELAY
  5299 00003168 E6EB                <2>  out 0ebh,al
  5300 0000316A E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5301 0000316C 1F                  <1> 	POP	DS
  5302                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  5303                              <1> 	;MOV	AX,9100H		; DEVICE POST
  5304                              <1> 	;INT	15H			;  INTERRUPT
  5305                              <1> irq15_iret: ; 25/02/2015
  5306 0000316D 6658                <1> 	POP	AX
  5307 0000316F CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  5308                              <1> 
  5309                              <1> hdc2_int: ; 21/02/2015
  5310                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  5311                              <1> ;								:
  5312                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5313                              <1> ;								:
  5314                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5315                              <1> 
  5316                              <1> ;int_77h:
  5317                              <1> HD1_INT:
  5318 00003170 6650                <1> 	PUSH	AX
  5319                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  5320                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  5321 00003172 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5322 00003174 E6A0                <1> 	out	0A0h, al
  5323 00003176 EB00                <1>         jmp short $+2
  5324 00003178 EB00                <1> 	jmp short $+2
  5325 0000317A E4A0                <1> 	in	al, 0A0h
  5326 0000317C 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5327 0000317E 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5328                              <1> 	;
  5329 00003180 1E                  <1> 	PUSH	DS
  5330                              <1> 	;CALL	DDS
  5331                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5332 00003181 66B81000            <1> 	mov	ax, KDATA
  5333 00003185 8ED8                <1> 	mov 	ds, ax
  5334                              <1> 	;
  5335                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5336                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  5337 00003187 800D[4BD30000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5338                              <1> 	;
  5339 0000318E 6652                <1> 	push	dx
  5340 00003190 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5341                              <1> 					; Clear Controller (Award BIOS 1999)
  5342 00003194 EBC9                <1> 	jmp	short Clear_IRQ1415
  5343                              <1> 
  5344                              <1> 
  5345                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  5346                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  5347                              <1> 
  5348                              <1> 
  5349                              <1> ;////////////////////////////////////////////////////////////////////
  5350                              <1> ;; END OF DISK I/O SYTEM ///
  1899                                  %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: 10/06/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 00003196 A1[C0D20000]        <1> 	mov	eax, [free_pages]
   328 0000319B 21C0                <1> 	and	eax, eax
   329 0000319D 7438                <1> 	jz	short out_of_memory
   330                              <1> 	;
   331 0000319F 53                  <1> 	push	ebx
   332 000031A0 51                  <1> 	push	ecx
   333                              <1> 	;
   334 000031A1 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   335 000031A6 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 000031A8 031D[C4D20000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   343                              <1> 				 ; next_free_page >> 5
   344 000031AE 030D[C8D20000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   345                              <1> 				 ; (total_pages - 1) >> 5
   346                              <1> al_p_scan:
   347 000031B4 39CB                <1> 	cmp	ebx, ecx
   348 000031B6 770A                <1> 	ja	short al_p_notfound
   349                              <1> 	;
   350                              <1> 	; 01/07/2015
   351                              <1> 	; AMD64 Architecture Programmers Manual
   352                              <1> 	; Volume 3:
   353                              <1> 	; General-Purpose and System Instructions
   354                              <1> 	;
   355                              <1> 	; BSF - Bit Scan Forward
   356                              <1> 	;
   357                              <1> 	;   Searches the value in a register or a memory location
   358                              <1> 	;   (second operand) for the least-significant set bit. 
   359                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
   360                              <1> 	;   and stores the index of the least-significant set bit in a destination
   361                              <1> 	;   register (first operand). If the second operand contains 0, 
   362                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
   363                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
   364                              <1> 	;   of the searched value
   365                              <1> 	;
   366 000031B8 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 000031BB 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 000031BD 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 000031C0 EBF2                <1>         jmp     short al_p_scan
   382                              <1> 	;
   383                              <1> al_p_notfound:
   384 000031C2 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   385 000031C8 890D[C4D20000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   386                              <1> 				 ; (deallocate_page procedure will change it)
   387 000031CE 31C0                <1> 	xor	eax, eax
   388 000031D0 A3[C0D20000]        <1> 	mov	[free_pages], eax ; 0
   389 000031D5 59                  <1> 	pop	ecx
   390 000031D6 5B                  <1> 	pop	ebx
   391                              <1> 	;
   392                              <1> out_of_memory:
   393 000031D7 E855040000          <1> 	call	swap_out
   394 000031DC 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   395                              <1> 	;
   396 000031DE 29C0                <1> 	sub 	eax, eax ; 0
   397 000031E0 F9                  <1> 	stc
   398 000031E1 C3                  <1> 	retn
   399                              <1> 
   400                              <1> al_p_found:
   401 000031E2 89D9                <1> 	mov	ecx, ebx
   402 000031E4 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   403 000031EA 890D[C4D20000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   404                              <1> 				 ; address/offset (to the next)
   405 000031F0 FF0D[C0D20000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   406                              <1> 	;
   407 000031F6 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 000031F9 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   415 000031FC 01C8                <1> 	add	eax, ecx	 ; = page number
   416 000031FE 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 00003201 59                  <1> 	pop	ecx
   422 00003202 5B                  <1> 	pop	ebx
   423                              <1> al_p_ok:
   424 00003203 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 00003204 E88DFFFFFF          <1> 	call	allocate_page
   446 00003209 7216                <1> 	jc	short mkpd_error
   447                              <1> 	;
   448 0000320B A3[D9E30000]        <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 00003210 57                  <1> 	push	edi
   462 00003211 51                  <1> 	push	ecx
   463 00003212 50                  <1> 	push	eax
   464 00003213 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   465 00003218 89C7                <1> 	mov	edi, eax
   466 0000321A 31C0                <1> 	xor	eax, eax
   467 0000321C F3AB                <1> 	rep	stosd
   468 0000321E 58                  <1> 	pop	eax
   469 0000321F 59                  <1> 	pop	ecx
   470 00003220 5F                  <1> 	pop	edi
   471                              <1> mkpd_error:
   472                              <1> mkpt_error:
   473 00003221 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 00003222 E86FFFFFFF          <1> 	call	allocate_page
   497 00003227 72F8                <1> 	jc	short mkpt_error
   498 00003229 E811000000          <1> 	call	set_pde	
   499 0000322E 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 00003230 E861FFFFFF          <1> 	call	allocate_page
   520 00003235 7207                <1> 	jc	short mkp_err
   521 00003237 E821000000          <1> 	call	set_pte	
   522 0000323C 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   523                              <1> mkp_err:
   524 0000323E 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 0000323F 89DA                <1> 	mov	edx, ebx
   550 00003241 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   551 00003244 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   552 00003247 0315[D9E30000]      <1> 	add	edx, [u.pgdir]
   553                              <1> 	;
   554 0000324D 21C0                <1> 	and	eax, eax
   555 0000324F 7506                <1> 	jnz	short spde_1
   556                              <1> 	;
   557 00003251 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   558                              <1> 	;test	al, 1
   559                              <1> 	;jz	short spde_2
   560 00003253 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   561                              <1> spde_1:
   562                              <1> 	;and	cx, 0FFFh
   563 00003257 8902                <1> 	mov	[edx], eax
   564 00003259 66090A              <1> 	or	[edx], cx
   565 0000325C 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 0000325D 50                  <1> 	push	eax
   596 0000325E A1[D9E30000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   597 00003263 E837000000          <1> 	call 	get_pde
   598                              <1> 		; EDX = PDE address
   599                              <1> 		; EAX = PDE value
   600 00003268 5A                  <1> 	pop	edx ; physical page address
   601 00003269 722A                <1> 	jc	short spte_err ; PDE not present
   602                              <1> 	;
   603 0000326B 53                  <1> 	push	ebx ; 24/07/2015
   604 0000326C 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   605                              <1> 			    ; EDX = PT address (physical)	
   606 00003270 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   607 00003273 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   608                              <1> 			 ; clear higher 10 bits (PD bits)
   609 00003279 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   610 0000327C 01C3                <1> 	add	ebx, eax
   611                              <1> 	;
   612 0000327E 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   613 00003280 A801                <1> 	test	al, 1
   614 00003282 740C                <1> 	jz	short spte_0
   615 00003284 09D2                <1> 	or	edx, edx
   616 00003286 750F                <1> 	jnz	short spte_1
   617 00003288 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   618 0000328C 89C2                <1> 	mov	edx, eax
   619 0000328E 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 00003290 21C0                <1> 	and	eax, eax
   625 00003292 7403                <1> 	jz	short spte_1
   626                              <1> 	; 24/07/2015
   627                              <1> 	; swapped page ! (on disk)
   628 00003294 5B                  <1> 	pop	ebx
   629                              <1> spte_err:
   630 00003295 F9                  <1> 	stc
   631 00003296 C3                  <1> 	retn
   632                              <1> spte_1: 
   633 00003297 89D0                <1> 	mov	eax, edx
   634                              <1> spte_2:
   635 00003299 09CA                <1> 	or	edx, ecx
   636                              <1> 	; 23/06/2015
   637 0000329B 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   638                              <1> 	; 24/07/2015
   639 0000329D 5B                  <1> 	pop	ebx
   640 0000329E 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 0000329F 89DA                <1> 	mov	edx, ebx
   658 000032A1 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   659 000032A4 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   660 000032A7 01C2                <1> 	add	edx, eax ; page directory address (physical)
   661 000032A9 8B02                <1> 	mov	eax, [edx]
   662 000032AB A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   663 000032AD 751F                <1> 	jnz	short gpte_retn
   664 000032AF F9                  <1> 	stc
   665                              <1> gpde_retn:	
   666 000032B0 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 000032B1 E8E9FFFFFF          <1> 	call 	get_pde
   688 000032B6 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 000032B8 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   693 000032BC 89DA                <1> 	mov	edx, ebx
   694 000032BE C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   695 000032C1 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   696                              <1> 			 ; clear higher 10 bits (PD bits)
   697 000032C7 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   698 000032CA 01C2                <1> 	add	edx, eax
   699 000032CC 8B02                <1> 	mov	eax, [edx]
   700                              <1> gpte_retn:
   701 000032CE 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 000032CF 56                  <1> 	push	esi
   724 000032D0 51                  <1> 	push	ecx
   725 000032D1 50                  <1> 	push	eax
   726 000032D2 89C6                <1> 	mov	esi, eax 
   727 000032D4 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 000032D6 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   731                              <1> dapd_0:
   732 000032D8 AD                  <1> 	lodsd
   733 000032D9 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   734 000032DB 7409                <1> 	jz	short dapd_1	
   735 000032DD 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   736 000032E1 E812000000          <1> 	call	deallocate_page_table			
   737                              <1> dapd_1:
   738 000032E6 41                  <1> 	inc	ecx ; page directory entry index
   739 000032E7 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   740 000032ED 72E9                <1> 	jb	short dapd_0
   741                              <1> dapd_2:
   742 000032EF 58                  <1> 	pop	eax
   743 000032F0 E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   744 000032F5 59                  <1> 	pop	ecx
   745 000032F6 5E                  <1> 	pop	esi
   746 000032F7 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 000032F8 56                  <1> 	push	esi
   770 000032F9 57                  <1> 	push	edi
   771 000032FA 52                  <1> 	push	edx
   772 000032FB 50                  <1> 	push	eax ; *
   773 000032FC 89C6                <1> 	mov	esi, eax 
   774 000032FE 31FF                <1> 	xor	edi, edi ; 0
   775                              <1> dapt_0:
   776 00003300 AD                  <1> 	lodsd
   777 00003301 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   778 00003303 7441                <1> 	jz	short dapt_1
   779                              <1> 	;
   780 00003305 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   781                              <1> 				  ; (must be 1)
   782 00003307 754C                <1> 	jnz	short dapt_3
   783                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   784 00003309 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   785                              <1> 				   ; as child's page ?
   786 0000330D 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 0000330F 53                  <1> 	push	ebx
   790 00003310 51                  <1> 	push	ecx
   791 00003311 66C1E102            <1> 	shl	cx, 2 ; *4 
   792 00003315 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   793 00003317 8B0B                <1> 	mov	ecx, [ebx]
   794 00003319 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   795 0000331C 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   796 0000331E 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   797                              <1> 	; EDI = page table entry index (0-1023)
   798 00003323 89FA                <1> 	mov	edx, edi 
   799 00003325 66C1E202            <1> 	shl	dx, 2 ; *4 
   800 00003329 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   801 0000332B 8B1A                <1> 	mov	ebx, [edx]
   802 0000332D F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   803 00003330 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   804 00003332 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   805 00003336 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   806 0000333B 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   807 0000333D 7514                <1> 	jne	short dapt_2	; not same page
   808                              <1> 				; deallocate the child's page
   809 0000333F 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   810 00003342 59                  <1> 	pop	ecx
   811 00003343 5B                  <1> 	pop	ebx
   812 00003344 EB14                <1> 	jmp	short dapt_4
   813                              <1> dapt_1:
   814 00003346 09C0                <1> 	or	eax, eax	; swapped page ?
   815 00003348 7417                <1> 	jz	short dapt_5	; no
   816                              <1> 				; yes
   817 0000334A D1E8                <1> 	shr	eax, 1
   818 0000334C E8C7040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   819                              <1> 				  ; on the swap disk (or in file)
   820 00003351 EB0E                <1> 	jmp	short dapt_5
   821                              <1> dapt_2:
   822 00003353 59                  <1> 	pop	ecx
   823 00003354 5B                  <1> 	pop	ebx
   824                              <1> dapt_3:	
   825                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   826 00003355 E814000000          <1> 	call	deallocate_page
   827                              <1> dapt_4:
   828 0000335A C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   829                              <1> dapt_5:
   830 00003361 47                  <1> 	inc	edi ; page table entry index
   831 00003362 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   832 00003368 7296                <1> 	jb	short dapt_0
   833                              <1> 	;
   834 0000336A 58                  <1> 	pop	eax ; *
   835 0000336B 5A                  <1> 	pop	edx
   836 0000336C 5F                  <1> 	pop	edi	
   837 0000336D 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 0000336E 53                  <1> 	push	ebx
   860 0000336F 52                  <1> 	push	edx
   861                              <1> 	;
   862 00003370 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   863                              <1> 				     ; 12 bits right
   864                              <1> 				     ; to get page number
   865 00003373 89C2                <1> 	mov	edx, eax
   866                              <1> 	; 15/09/2015
   867 00003375 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 00003378 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   871                              <1> 				     ; (to get 32 bit position)			
   872                              <1> 	;
   873 0000337B BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   874 00003380 01D3                <1> 	add	ebx, edx
   875 00003382 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   876                              <1> 				     ; (allocation bit position)	 
   877 00003385 3B15[C4D20000]      <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 0000338B 7306                <1> 	jnb	short dap_1	     ; no	
   881 0000338D 8915[C4D20000]      <1> 	mov	[next_page], edx     ; yes
   882                              <1> dap_1:
   883 00003393 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 00003396 FF05[C0D20000]      <1>         inc     dword [free_pages]
   891                              <1> dap_2:
   892 0000339C 5A                  <1> 	pop	edx
   893 0000339D 5B                  <1> 	pop	ebx
   894 0000339E 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 0000339F E8F2FDFFFF          <1> 	call	allocate_page
   978 000033A4 723E                <1> 	jc	short dpd_err
   979                              <1> 	;
   980 000033A6 55                  <1> 	push	ebp ; 20/07/2015
   981 000033A7 56                  <1> 	push	esi
   982 000033A8 57                  <1> 	push	edi
   983 000033A9 53                  <1> 	push	ebx
   984 000033AA 51                  <1> 	push	ecx
   985 000033AB 8B35[D9E30000]      <1> 	mov	esi, [u.pgdir]
   986 000033B1 89C7                <1> 	mov	edi, eax
   987 000033B3 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 000033B4 A5                  <1> 	movsd
   992 000033B5 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
   993 000033BA B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
   994                              <1> dpd_0:	
   995 000033BF AD                  <1> 	lodsd
   996                              <1> 	;or	eax, eax
   997                              <1>         ;jnz     short dpd_1
   998 000033C0 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
   999 000033C2 7508                <1> 	jnz	short dpd_1
  1000                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1001 000033C4 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1002 000033CA EB0F                <1> 	jmp	short dpd_2
  1003                              <1> dpd_1:	
  1004 000033CC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1005 000033D0 89C3                <1> 	mov	ebx, eax
  1006                              <1> 	; EBX = Parent's page table address
  1007 000033D2 E81F000000          <1> 	call	duplicate_page_table
  1008 000033D7 720C                <1> 	jc	short dpd_p_err
  1009                              <1> 	; EAX = Child's page table address
  1010 000033D9 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 000033DB AB                  <1> 	stosd
  1015 000033DC E2E1                <1> 	loop	dpd_0
  1016                              <1> 	;
  1017 000033DE 58                  <1> 	pop	eax  ; restore child's page directory address
  1018                              <1> dpd_3:
  1019 000033DF 59                  <1> 	pop	ecx
  1020 000033E0 5B                  <1> 	pop	ebx
  1021 000033E1 5F                  <1> 	pop	edi
  1022 000033E2 5E                  <1> 	pop	esi
  1023 000033E3 5D                  <1> 	pop	ebp ; 20/07/2015
  1024                              <1> dpd_err:
  1025 000033E4 C3                  <1> 	retn
  1026                              <1> dpd_p_err:
  1027                              <1> 	; release the allocated pages missing (recover free space)
  1028 000033E5 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1029 000033E6 8B1D[D9E30000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1030 000033EC E8DEFEFFFF          <1> 	call 	deallocate_page_dir
  1031 000033F1 29C0                <1> 	sub	eax, eax ; 0
  1032 000033F3 F9                  <1> 	stc
  1033 000033F4 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 000033F6 E89BFDFFFF          <1> 	call	allocate_page
  1057 000033FB 726A                <1> 	jc	short dpt_err
  1058                              <1> 	;
  1059 000033FD 50                  <1> 	push	eax ; *
  1060 000033FE 56                  <1> 	push	esi
  1061 000033FF 57                  <1> 	push	edi
  1062 00003400 52                  <1> 	push	edx
  1063 00003401 51                  <1> 	push	ecx
  1064                              <1> 	;
  1065 00003402 89DE                <1> 	mov	esi, ebx
  1066 00003404 89C7                <1> 	mov	edi, eax
  1067 00003406 89C2                <1> 	mov	edx, eax
  1068 00003408 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1069                              <1> dpt_0:
  1070 0000340E AD                  <1> 	lodsd
  1071 0000340F 21C0                <1> 	and	eax, eax
  1072 00003411 7444                <1> 	jz	short dpt_3
  1073 00003413 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1074 00003415 7507                <1> 	jnz	short dpt_1
  1075                              <1> 	; 20/07/2015
  1076                              <1> 	; ebp = virtual (linear) address of the memory page
  1077 00003417 E806050000          <1> 	call	reload_page ; 28/04/2015
  1078 0000341C 7244                <1> 	jc	short dpt_p_err
  1079                              <1> dpt_1:
  1080                              <1> 	; 21/09/2015
  1081 0000341E 89C1                <1> 	mov	ecx, eax
  1082 00003420 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1083 00003424 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1084 00003427 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 00003429 E868FDFFFF          <1> 	call	allocate_page
  1089 0000342E 7232                <1> 	jc	short dpt_p_err
  1090 00003430 57                  <1> 	push	edi
  1091 00003431 56                  <1> 	push	esi
  1092 00003432 89CE                <1> 	mov	esi, ecx
  1093 00003434 89C7                <1> 	mov	edi, eax
  1094 00003436 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1095 0000343B F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1096 0000343D 5E                  <1> 	pop	esi
  1097 0000343E 5F                  <1> 	pop	edi
  1098                              <1> 	; 
  1099 0000343F 53                  <1> 	push	ebx
  1100 00003440 50                  <1> 	push	eax
  1101                              <1> 	; 20/07/2015
  1102 00003441 89EB                <1> 	mov	ebx, ebp
  1103                              <1> 	; ebx = virtual address of the memory page
  1104 00003443 E88A030000          <1> 	call	add_to_swap_queue
  1105 00003448 58                  <1> 	pop	eax
  1106 00003449 5B                  <1> 	pop	ebx
  1107                              <1> 	; 21/09/2015
  1108 0000344A 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1109                              <1> 		; user + writable + present page
  1110 0000344C EB09                <1> 	jmp	short dpt_3
  1111                              <1> dpt_2:
  1112                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1113 0000344E 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1114                              <1> 		    ; (read only page!)
  1115 00003450 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1116 00003453 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1117                              <1> dpt_3:
  1118 00003457 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1119                              <1> 	;
  1120 00003458 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1121                              <1> 	;
  1122 0000345E 39D7                <1> 	cmp	edi, edx
  1123 00003460 72AC                <1> 	jb	short dpt_0
  1124                              <1> dpt_p_err:
  1125 00003462 59                  <1> 	pop	ecx
  1126 00003463 5A                  <1> 	pop	edx
  1127 00003464 5F                  <1> 	pop	edi
  1128 00003465 5E                  <1> 	pop	esi
  1129 00003466 58                  <1> 	pop	eax ; *
  1130                              <1> dpt_err:
  1131 00003467 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 00003468 53                  <1> 	push	ebx
  1274 00003469 52                  <1> 	push	edx
  1275 0000346A 51                  <1> 	push	ecx
  1276                              <1> 	;
  1277                              <1> 	; 21/09/2015 (debugging)
  1278 0000346B FF05[E9E30000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1279 00003471 FF05[64F10000]      <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 00003477 8A15[5CF10000]      <1> 	mov	dl, [error_code]
  1283                              <1> 	;
  1284 0000347D F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1285                              <1> 			; sign
  1286 00003480 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 00003482 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1309                              <1> 			; sign
  1310 00003485 0F84AB000000        <1>         jz      pfh_p_err
  1311                              <1> 	; 31/08/2015
  1312 0000348B 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 0000348E 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 00003494 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1320                              <1> 			 ; which has caused to page fault
  1321 00003497 E8A2000000          <1> 	call 	copy_page
  1322 0000349C 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1323                              <1> 	;
  1324 000034A2 EB7D                <1>         jmp     pfh_cpp_ok
  1325                              <1> 	;
  1326                              <1> pfh_alloc_np:
  1327 000034A4 E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1328 000034A9 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 000034AF 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1334 000034B2 7505                <1> 	jnz	short pfh_um
  1335                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1336 000034B4 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 000034B7 EB06                <1> 	jmp	short pfh_get_pde
  1341                              <1> 	;
  1342                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1343 000034B9 8B1D[D9E30000]      <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 000034BF 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1348 000034C2 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1349                              <1> 			 ; which has been caused to page fault
  1350                              <1> 			 ;
  1351 000034C5 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1352 000034C8 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1353                              <1> 	;
  1354 000034CB 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1355 000034CD 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1356 000034CF F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1357 000034D2 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1358                              <1> 			  	  ; set/validate page directory entry
  1359 000034D4 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1360 000034D9 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1361 000034DB 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1362 000034DD 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 000034DF 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1368 000034E1 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1369 000034E3 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1370 000034E5 89C3                <1> 	mov	ebx, eax
  1371 000034E7 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1372 000034EC 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 000034EE 89C1                <1> 	mov	ecx, eax
  1376 000034F0 E81BFDFFFF          <1> 	call	clear_page ; Clear page content
  1377                              <1> pfh_get_pte:
  1378 000034F5 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1379                              <1> 			 ; which has been caused to page fault
  1380 000034F8 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1381 000034FA C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1382                              <1> 			 ; higher 20 bits of the page fault address 
  1383 000034FD 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1384 00003502 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1385 00003505 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1386 00003507 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 00003509 21C0                <1> 	and	eax, eax
  1389 0000350B 7410                <1> 	jz	short pfh_gpte_1
  1390                              <1> 	; 20/07/2015
  1391 0000350D 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1392 0000350F 55                  <1> 	push	ebp ; 20/07/2015
  1393 00003510 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 00003513 E8B7000000          <1> 	call	swap_in
  1399 00003518 5D                  <1> 	pop	ebp
  1400 00003519 7210                <1> 	jc      short pfh_err_retn
  1401 0000351B 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 0000351D 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1406 0000351F 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 00003521 0F20D3              <1> 	mov	ebx, cr2
  1410 00003524 E8A9020000          <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 00003529 31C0                <1> 	xor	eax, eax  ; 0
  1419                              <1> 	;
  1420                              <1> pfh_err_retn:
  1421 0000352B 59                  <1> 	pop	ecx
  1422 0000352C 5A                  <1> 	pop	edx
  1423 0000352D 5B                  <1> 	pop	ebx
  1424 0000352E C3                  <1> 	retn 
  1425                              <1> 	
  1426                              <1> pfh_im_err:
  1427 0000352F 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 00003534 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 00003536 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 0000353B F9                  <1> 	stc
  1440 0000353C 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 0000353E 56                  <1> 	push	esi
  1470 0000353F 57                  <1> 	push	edi
  1471                              <1> 	;push	ebx
  1472                              <1> 	;push	ecx
  1473 00003540 31F6                <1> 	xor 	esi, esi
  1474 00003542 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1475 00003545 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1476 00003547 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1477 0000354A 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1478 0000354D 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1479 0000354F 031D[D9E30000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1480 00003555 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1481 00003557 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1482 0000355B 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1483 0000355D 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1484 00003563 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1485 00003567 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1486                              <1> 	; 07/09/2015
  1487 00003569 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1488                              <1> 				     ; read only page as a child process?)	
  1489 0000356E 7509                <1> 	jnz	short cpp_0 ; yes
  1490 00003570 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1491 00003572 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1492 00003577 EB32                <1> 	jmp	short cpp_1
  1493                              <1> cpp_0:
  1494 00003579 89FE                <1> 	mov	esi, edi
  1495 0000357B 0335[DDE30000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1496 00003581 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1497 00003583 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1498 00003587 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1499 00003589 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1500 0000358F 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1501 00003593 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1502 00003595 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1503                              <1> 	; 21/09/2015
  1504 00003597 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1505 00003599 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1506                              <1> 	;
  1507 0000359D F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1508 000035A0 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1509                              <1> 	;
  1510 000035A2 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1511 000035A7 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1512 000035A9 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 000035AB E8E6FBFFFF          <1> 	call	allocate_page
  1516 000035B0 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1517 000035B2 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1518 000035B4 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 000035B6 890E                <1> 	mov	[esi], ecx
  1524 000035B8 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 000035BB 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1528                              <1> 	; 07/09/2015
  1529 000035BD 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1530 000035BF B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1531 000035C4 F3A5                <1> 	rep	movsd ; 31/08/2015
  1532                              <1> cpp_3:		
  1533 000035C6 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1534 000035C8 8903                <1> 	mov	[ebx], eax ; Update PTE
  1535 000035CA 28C0                <1> 	sub	al, al ; clear attributes
  1536                              <1> cpp_4:
  1537                              <1> 	;pop	ecx
  1538                              <1> 	;pop	ebx
  1539 000035CC 5F                  <1> 	pop	edi
  1540 000035CD 5E                  <1> 	pop	esi
  1541 000035CE 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 000035CF 833D[46F10000]00    <1>         cmp     dword [swp_drv], 0
  1731 000035D6 7646                <1> 	jna	short swpin_dnp_err
  1732                              <1> 
  1733 000035D8 3B05[4AF10000]      <1> 	cmp	eax, [swpd_size]
  1734 000035DE 734A                <1> 	jnb	short swpin_snp_err
  1735                              <1> 
  1736 000035E0 56                  <1> 	push	esi
  1737 000035E1 53                  <1> 	push	ebx
  1738 000035E2 51                  <1> 	push	ecx
  1739 000035E3 8B35[46F10000]      <1> 	mov	esi, [swp_drv]	
  1740 000035E9 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 000035EE 50                  <1> 	push	eax
  1751 000035EF E8B2020000          <1> 	call	logical_disk_read
  1752 000035F4 58                  <1> 	pop	eax
  1753 000035F5 730C                <1> 	jnc	short swpin_read_ok
  1754                              <1> 	;
  1755 000035F7 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1756 000035FC A3[D5E30000]        <1> 	mov	[u.error], eax
  1757 00003601 EB17                <1> 	jmp	short swpin_retn
  1758                              <1> 	;
  1759                              <1> swpin_read_ok:
  1760                              <1> 	; EAX = Offset address (logical sector number)
  1761 00003603 E810020000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
  1762                              <1> 	;
  1763                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1764                              <1> 	; 20/07/2015
  1765 00003608 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1766 0000360A 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1767 0000360F 8A1D[CFE30000]      <1> 	mov	bl, [u.uno] ; current process number
  1768                              <1> 	; EBX = Virtual address & process number combination
  1769 00003615 E8DB000000          <1> 	call	swap_queue_shift
  1770                              <1> 	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
  1771                              <1> 	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  1772                              <1> 	; zf = 1
  1773                              <1> swpin_retn:
  1774 0000361A 59                  <1> 	pop	ecx
  1775 0000361B 5B                  <1> 	pop	ebx
  1776 0000361C 5E                  <1> 	pop	esi
  1777 0000361D C3                  <1> 	retn
  1778                              <1> 
  1779                              <1> swpin_dnp_err:
  1780 0000361E B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1781                              <1> swpin_err_retn:
  1782 00003623 A3[D5E30000]        <1> 	mov	[u.error], eax
  1783 00003628 F9                  <1> 	stc
  1784 00003629 C3                  <1> 	retn
  1785                              <1> 
  1786                              <1> swpin_snp_err:
  1787 0000362A B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1788 0000362F EBF2                <1> 	jmp	short swpin_err_retn
  1789                              <1> 
  1790                              <1> swap_out:
  1791                              <1> 	; 10/06/2016
  1792                              <1> 	; 07/06/2016
  1793                              <1>         ; 23/05/2016
  1794                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1795                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
  1796                              <1> 	;
  1797                              <1> 	; INPUT -> 
  1798                              <1> 	;	none
  1799                              <1> 	;
  1800                              <1> 	; OUTPUT ->
  1801                              <1> 	;	EAX = Physical page address (which is swapped out
  1802                              <1> 	;	      for allocating a new page)
  1803                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  1804                              <1> 	;		  or sector not present or drive not ready
  1805                              <1> 	;	     EAX = Error code
  1806                              <1> 	;	     [u.error] = EAX 
  1807                              <1> 	;		       = The last error code for the process
  1808                              <1> 	;		         (will be reset after returning to user)	  
  1809                              <1> 	;
  1810                              <1> 	; Modified Registers -> none (except EAX)
  1811                              <1> 	;
  1812 00003631 66833D[44F10000]01  <1> 	cmp 	word [swpq_count], 1
  1813 00003639 0F82AF000000        <1>         jc      swpout_im_err ; 'insufficient memory'
  1814                              <1> 
  1815                              <1>         ;cmp    dword [swp_drv], 1
  1816                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  1817                              <1> 
  1818 0000363F 833D[4EF10000]01    <1>         cmp     dword [swpd_free], 1
  1819 00003646 0F828F000000        <1>         jc      swpout_nfspc_err ; 'no free space on swap disk'
  1820                              <1> 
  1821 0000364C 53                  <1> 	push	ebx ; *
  1822                              <1> swpout_1:
  1823                              <1> 	; 10/06/2016
  1824 0000364D 31DB                <1> 	xor	ebx, ebx ; shift the queue and return a PTE value
  1825 0000364F E8A1000000          <1> 	call	swap_queue_shift
  1826 00003654 21C0                <1> 	and	eax, eax	; 0 = empty queue (improper entries)
  1827 00003656 0F848A000000        <1>         jz      swpout_npts_err        ; There is not any proper PTE
  1828                              <1> 				       ; pointer in the swap queue
  1829                              <1> 	; EAX = PTE value of the page
  1830                              <1> 	; EBX = PTE address of the page
  1831 0000365C 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1832                              <1> 	;
  1833                              <1> 	; 07/06/2016
  1834                              <1> 	; 19/05/2016
  1835                              <1> 	; check this page is in timer events or not
  1836                              <1> 	
  1837                              <1> swpout_timer_page_0:
  1838 00003660 52                  <1> 	push	edx ; **
  1839                              <1> 
  1840                              <1> 	; 07/06/2016
  1841 00003661 803D[40E00000]00    <1> 	cmp	byte [timer_events], 0 
  1842 00003668 762F                <1> 	jna	short swpout_2
  1843                              <1> 	;
  1844 0000366A 8A15[40E00000]      <1> 	mov	dl, [timer_events]
  1845                              <1> 
  1846 00003670 51                  <1> 	push	ecx ; ***
  1847 00003671 53                  <1> 	push	ebx ; ****
  1848 00003672 BB[44F00000]        <1> 	mov	ebx, timer_set ; beginning address of timer event
  1849                              <1> 			       ; structures 
  1850                              <1> swpout_timer_page_1:
  1851 00003677 8A0B                <1> 	mov	cl, [ebx]
  1852 00003679 08C9                <1> 	or	cl, cl ; 0 = free, >0 = process number
  1853 0000367B 7415                <1> 	jz	short swpout_timer_page_3
  1854 0000367D 8B4B0C              <1> 	mov	ecx, [ebx+12] ; response (signal return) address
  1855 00003680 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 00003685 39C8                <1> 	cmp	eax, ecx
  1859 00003687 7505                <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 00003689 5B                  <1> 	pop	ebx ; ****
  1871 0000368A 59                  <1> 	pop	ecx ; ***
  1872 0000368B 5A                  <1> 	pop	edx ; **
  1873 0000368C EBBF                <1> 	jmp	short swpout_1	; do not swap out this page !
  1874                              <1>  
  1875                              <1> swpout_timer_page_2:
  1876                              <1> 	; 07/06/2016
  1877 0000368E FECA                <1> 	dec	dl
  1878 00003690 7405                <1> 	jz	short swpout_timer_page_4
  1879                              <1> swpout_timer_page_3:
  1880                              <1> 	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
  1881                              <1> 	;jnb	short swpout_timer_page_4
  1882 00003692 83C310              <1> 	add	ebx, 16
  1883 00003695 EBE0                <1> 	jmp	short swpout_timer_page_1	
  1884                              <1> 
  1885                              <1> swpout_timer_page_4:
  1886 00003697 5B                  <1> 	pop	ebx ; ****
  1887 00003698 59                  <1> 	pop	ecx ; ***
  1888                              <1> swpout_2:
  1889 00003699 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1890 0000369B 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1891                              <1> 	;
  1892 0000369D E8A9010000          <1> 	call	link_swap_block
  1893 000036A2 7304                <1> 	jnc	short swpout_3	       ; It may not be needed here	
  1894                              <1> 				       ; because [swpd_free] value
  1895                              <1> 				       ; was checked at the beginging. 	
  1896 000036A4 5A                  <1> 	pop	edx ; **
  1897 000036A5 5B                  <1> 	pop	ebx ; *
  1898 000036A6 EB33                <1> 	jmp	short swpout_nfspc_err 
  1899                              <1> swpout_3:
  1900 000036A8 A900000080          <1> 	test	eax, 80000000h ; test bit 31 (this may not be needed!)
  1901 000036AD 752C                <1> 	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
  1902                              <1> 	;	
  1903 000036AF 56                  <1> 	push	esi ; **
  1904 000036B0 51                  <1> 	push	ecx ; ***
  1905 000036B1 50                  <1> 	push	eax ; sector address ; (31 bit !, bit 31 = 0)
  1906 000036B2 8B35[46F10000]      <1> 	mov	esi, [swp_drv]	
  1907 000036B8 B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1908                              <1> 		; Note: Even if corresponding physical disk's sector 
  1909                              <1> 		; size different than 512 bytes, logical disk sector
  1910                              <1> 		; size is 512 bytes and disk writing procedure
  1911                              <1> 		; will be performed for writing 4096 bytes
  1912                              <1> 		; (2*2048, 8*512). 
  1913                              <1> 	; ESI = Logical disk description table address
  1914                              <1> 	; EBX = Buffer (Page) address
  1915                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1916                              <1> 	; ECX = Sector count ; 8 sectors
  1917                              <1> 	; edx = PTE address
  1918 000036BD E8E5010000          <1> 	call	logical_disk_write
  1919                              <1> 	; edx = PTE address
  1920 000036C2 59                  <1> 	pop	ecx ; sector address	
  1921 000036C3 730C                <1> 	jnc	short swpout_write_ok
  1922                              <1> 	;
  1923                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
  1924                              <1> swpout_dw_err:
  1925 000036C5 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1926 000036CA A3[D5E30000]        <1> 	mov	[u.error], eax
  1927 000036CF EB06                <1> 	jmp	short swpout_retn
  1928                              <1> 	;
  1929                              <1> swpout_write_ok:
  1930                              <1> 	; EBX = Buffer (page) address
  1931                              <1> 	; EDX = Page Table Entry address
  1932                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
  1933 000036D1 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1934 000036D3 890A                <1> 	mov 	[edx], ecx 
  1935                              <1> 		; bit 0 = 0 (swapped page)
  1936 000036D5 89D8                <1> 	mov	eax, ebx
  1937                              <1> swpout_retn:
  1938 000036D7 59                  <1> 	pop	ecx ; ***
  1939 000036D8 5E                  <1> 	pop	esi ; **
  1940 000036D9 5B                  <1> 	pop	ebx ; *
  1941 000036DA C3                  <1> 	retn
  1942                              <1> 
  1943                              <1> ;swpout_dnp_err:
  1944                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  1945                              <1> ;	jmp	short swpout_err_retn
  1946                              <1> swpout_nfspc_err:
  1947 000036DB B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1948                              <1> swpout_err_retn:
  1949 000036E0 A3[D5E30000]        <1> 	mov	[u.error], eax
  1950                              <1> 	;stc
  1951 000036E5 C3                  <1> 	retn
  1952                              <1> swpout_npts_err:
  1953 000036E6 B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1954 000036EB 5B                  <1> 	pop	ebx
  1955 000036EC EBF2                <1> 	jmp	short swpout_err_retn
  1956                              <1> swpout_im_err:
  1957 000036EE B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1958 000036F3 EBEB                <1> 	jmp	short swpout_err_retn
  1959                              <1> 
  1960                              <1> swap_queue_shift:
  1961                              <1> 	; 10/06/2016
  1962                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
  1963                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
  1964                              <1> 	;
  1965                              <1> 	; INPUT ->
  1966                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  1967                              <1> 	;	      and process number combination (bit 0 to 11)
  1968                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  1969                              <1> 	;	
  1970                              <1> 	; OUTPUT ->
  1971                              <1> 	;	If EBX input > 0 
  1972                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  1973                              <1> 	; 	   from the tail to the head, up to entry offset
  1974                              <1> 	; 	   which points to EBX input value or nothing
  1975                              <1> 	;	   to do if EBX value is not found in the queue.
  1976                              <1> 	;	   (The entry -with EBX value- will be removed
  1977                              <1> 	;	   from the queue if it is found.)
  1978                              <1> 	;
  1979                              <1> 	;	   EAX = 0		
  1980                              <1> 	;
  1981                              <1> 	;	If EBX input = 0
  1982                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  1983                              <1> 	; 	   from the tail to the head, if the PTE address
  1984                              <1> 	;	   which is pointed in head of the queue is marked
  1985                              <1> 	;	   as "accessed" or it is marked as "non present".
  1986                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
  1987                              <1> 	;	   in the head- is set -to 1-, it will be reset
  1988                              <1> 	;	   -to 0- and then, the queue will be rotated 
  1989                              <1> 	;	   -without dropping pointer of the PTE from 
  1990                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
  1991                              <1> 	;	   Pointer in the head will be moved into the tail,
  1992                              <1> 	;	   other PTEs will be shifted on head direction.)
  1993                              <1> 	;
  1994                              <1> 	;	   Swap queue will be shifted up to the first
  1995                              <1> 	;	   'present' or 'non accessed' page will be found
  1996                              <1> 	;	   (as pointed) in the queue head (then it will be
  1997                              <1>         ;          removed/dropped from the queue).
  1998                              <1> 	;
  1999                              <1> 	;	   EAX (> 0) = PTE value of the page which is
  2000                              <1> 	;		 (it's pointer -virtual address-) dropped
  2001                              <1> 	;		 (removed) from swap queue.
  2002                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
  2003                              <1> 	;	         which is (it's pointer -virtual address-)
  2004                              <1> 	;		 dropped (removed) from swap queue.
  2005                              <1> 	;
  2006                              <1> 	;	   EAX = 0 -> empty swap queue ! 
  2007                              <1> 	;
  2008                              <1> 	; Modified Registers -> EAX, EBX (if EAX > 0)
  2009                              <1> 	;
  2010 000036F5 0FB705[44F10000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  2011 000036FC 6621C0              <1> 	and	ax, ax
  2012 000036FF 7433                <1> 	jz	short swpqs_retn
  2013 00003701 57                  <1> 	push	edi
  2014 00003702 56                  <1> 	push	esi
  2015 00003703 51                  <1> 	push	ecx
  2016 00003704 53                  <1> 	push	ebx
  2017 00003705 BE00E00800          <1> 	mov	esi, swap_queue
  2018 0000370A 89C1                <1> 	mov	ecx, eax
  2019 0000370C 09DB                <1> 	or	ebx, ebx
  2020 0000370E 7425                <1> 	jz	short swpqs_7
  2021                              <1> swpqs_1:
  2022 00003710 AD                  <1> 	lodsd
  2023 00003711 39D8                <1> 	cmp	eax, ebx
  2024 00003713 7406                <1> 	je	short swpqs_2
  2025 00003715 E2F9                <1> 	loop	swpqs_1
  2026                              <1> 	; 10/06/2016
  2027 00003717 29C0                <1> 	sub	eax, eax 
  2028 00003719 EB15                <1> 	jmp	short swpqs_6
  2029                              <1> swpqs_2:
  2030 0000371B 89F7                <1> 	mov	edi, esi
  2031 0000371D 83EF04              <1> 	sub 	edi, 4
  2032                              <1> swpqs_3:
  2033 00003720 66FF0D[44F10000]    <1> 	dec	word [swpq_count]
  2034 00003727 7403                <1> 	jz	short swpqs_5
  2035                              <1> swpqs_4:
  2036 00003729 49                  <1> 	dec 	ecx
  2037 0000372A F3A5                <1> 	rep	movsd	; shift up (to the head)
  2038                              <1> swpqs_5:
  2039 0000372C 31C0                <1> 	xor	eax, eax
  2040 0000372E 8907                <1> 	mov	[edi], eax
  2041                              <1> swpqs_6:
  2042 00003730 5B                  <1> 	pop	ebx
  2043                              <1> swpqs_14:
  2044 00003731 59                  <1> 	pop	ecx
  2045 00003732 5E                  <1> 	pop	esi
  2046 00003733 5F                  <1> 	pop	edi
  2047                              <1> swpqs_retn:
  2048 00003734 C3                  <1> 	retn		
  2049                              <1> swpqs_7:
  2050 00003735 89F7                <1> 	mov	edi, esi ; head
  2051 00003737 AD                  <1> 	lodsd
  2052                              <1> 	; 20/07/2015
  2053 00003738 89C3                <1> 	mov	ebx, eax
  2054 0000373A 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  2055                              <1> 		      ; ebx = virtual address (at page boundary)	
  2056 00003740 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2057                              <1> 		      ; ax = process number (1 to 4095)
  2058 00003745 3A05[CFE30000]      <1> 	cmp	al, [u.uno]
  2059                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2060 0000374B 7507                <1> 	jne	short swpqs_8
  2061 0000374D A1[D9E30000]        <1> 	mov	eax, [u.pgdir]
  2062 00003752 EB28                <1> 	jmp	short swpqs_9
  2063                              <1> swpqs_8:
  2064                              <1> 	; 09/06/2016
  2065 00003754 80B8[F1E00000]00    <1> 	cmp	byte [eax+p.stat-1], 0
  2066 0000375B 76C3                <1> 	jna	short swpqs_3     ; free (or terminated) process
  2067 0000375D 80B8[F1E00000]02    <1> 	cmp	byte [eax+p.stat-1], 2 ; waiting
  2068 00003764 77BA                <1> 	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
  2069                              <1> 
  2070                              <1> 	;shl	ax, 2
  2071 00003766 C0E002              <1> 	shl	al, 2
  2072 00003769 8B80[FEE00000]      <1> 	mov 	eax, [eax+p.upage-4]
  2073 0000376F 09C0                <1> 	or	eax, eax
  2074 00003771 74AD                <1> 	jz	short swpqs_3 ; invalid upage
  2075 00003773 83C061              <1> 	add	eax, u.pgdir - user
  2076                              <1> 			 ; u.pgdir value for the process
  2077                              <1> 			 ; is in [eax]
  2078 00003776 8B00                <1> 	mov	eax, [eax]
  2079 00003778 21C0                <1> 	and	eax, eax
  2080 0000377A 74A4                <1> 	jz	short swpqs_3 ; invalid page directory
  2081                              <1> swpqs_9:
  2082 0000377C 52                  <1> 	push	edx
  2083                              <1> 	; eax = page directory
  2084                              <1> 	; ebx = virtual address
  2085 0000377D E82FFBFFFF          <1> 	call	get_pte
  2086 00003782 89D3                <1> 	mov	ebx, edx	; PTE address
  2087 00003784 5A                  <1> 	pop	edx
  2088                              <1> 	; 10/06/2016
  2089 00003785 723B                <1> 	jc	short swpqs_13 ; empty PDE
  2090                              <1> 	; EAX = PTE value
  2091 00003787 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2092 00003789 7437                <1> 	jz	short swpqs_13  ; Drop non-present page
  2093                              <1> 			        ; from the queue (head)
  2094 0000378B A802                <1> 	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
  2095 0000378D 7433                <1> 	jz	short swpqs_13  ; Drop read only page
  2096                              <1> 			        ; from the queue (head) 	
  2097                              <1> 	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
  2098                              <1> 	;jnz	short swpqs_11  ; present
  2099                              <1> 			        ; accessed page
  2100 0000378F 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2101 00003793 7211                <1> 	jc	short swpqs_11  ; accessed page
  2102                              <1> 
  2103 00003795 49                  <1> 	dec	ecx
  2104 00003796 66890D[44F10000]    <1> 	mov	[swpq_count], cx
  2105 0000379D 7402                <1>         jz      short swpqs_10
  2106                              <1> 		; esi = head + 4
  2107                              <1> 		; edi = head
  2108 0000379F F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2109                              <1> swpqs_10:
  2110 000037A1 890F                <1> 	mov	[edi], ecx ; 0
  2111 000037A3 59                  <1> 	pop	ecx       	;  EBX (input) in stack
  2112                              <1> 				;  EBX = PTE address	
  2113 000037A4 EB8B                <1> 	jmp	short swpqs_14 
  2114                              <1> 
  2115                              <1> swpqs_11:
  2116 000037A6 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2117                              <1> 	; Rotation (head -> tail)
  2118 000037A8 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2119 000037A9 74F6                <1> 	jz	short swpqs_10
  2120                              <1> 		; esi = head + 4
  2121                              <1> 		; edi = head
  2122 000037AB 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2123 000037AD F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2124 000037AF 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1]
  2125                              <1> 
  2126 000037B1 668B0D[44F10000]    <1> 	mov	cx, [swpq_count]
  2127                              <1> 
  2128                              <1> swpqs_12:
  2129 000037B8 BE00E00800          <1> 	mov	esi, swap_queue ; head
  2130 000037BD E973FFFFFF          <1>         jmp     swpqs_7
  2131                              <1> 
  2132                              <1> swpqs_13:
  2133 000037C2 49                  <1> 	dec	ecx
  2134 000037C3 66890D[44F10000]    <1> 	mov	[swpq_count], cx
  2135 000037CA 0F845CFFFFFF        <1>         jz      swpqs_5
  2136 000037D0 EBE6                <1> 	jmp	short swpqs_12
  2137                              <1> 
  2138                              <1> add_to_swap_queue:
  2139                              <1> ; temporary - 16/09/2015
  2140 000037D2 C3                  <1> retn
  2141                              <1> 	; 20/07/2015
  2142                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2143                              <1> 	;
  2144                              <1> 	; Adds new page to swap queue
  2145                              <1> 	; (page directories and page tables must not be added
  2146                              <1> 	; to swap queue)	
  2147                              <1> 	;
  2148                              <1> 	; INPUT ->
  2149                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
  2150                              <1> 	;
  2151                              <1> 	; OUTPUT ->
  2152                              <1> 	;	EAX = [swpq_count]
  2153                              <1> 	;	      (after the PTE has been added)
  2154                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  2155                              <1> 	;	      the PTE could not be added.
  2156                              <1> 	;
  2157                              <1> 	; Modified Registers -> EAX
  2158                              <1> 	;
  2159 000037D3 53                  <1> 	push	ebx
  2160 000037D4 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2161 000037D9 8A1D[CFE30000]      <1> 	mov	bl, [u.uno] ; current process number
  2162 000037DF E811FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2163                              <1> 				 ; it is already in the queue
  2164                              <1> 		; then add it to the tail of the queue
  2165 000037E4 0FB705[44F10000]    <1> 	movzx	eax, word [swpq_count]
  2166 000037EB 663D0004            <1> 	cmp	ax, 1024
  2167 000037EF 7205                <1> 	jb	short atsq_1
  2168 000037F1 6629C0              <1> 	sub	ax, ax
  2169 000037F4 5B                  <1> 	pop	ebx
  2170 000037F5 C3                  <1> 	retn
  2171                              <1> atsq_1:
  2172 000037F6 56                  <1> 	push	esi
  2173 000037F7 BE00E00800          <1> 	mov	esi, swap_queue
  2174 000037FC 6621C0              <1> 	and	ax, ax
  2175 000037FF 740A                <1> 	jz	short atsq_2
  2176 00003801 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2177 00003805 01C6                <1> 	add	esi, eax
  2178 00003807 66C1E802            <1> 	shr	ax, 2
  2179                              <1> atsq_2:
  2180 0000380B 6640                <1> 	inc	ax
  2181 0000380D 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2182 0000380F 66A3[44F10000]      <1> 	mov	[swpq_count], ax
  2183 00003815 5E                  <1> 	pop	esi
  2184 00003816 5B                  <1> 	pop	ebx
  2185 00003817 C3                  <1> 	retn
  2186                              <1> 
  2187                              <1> unlink_swap_block:
  2188                              <1> 	; 15/09/2015
  2189                              <1> 	; 30/04/2015
  2190                              <1> 	; 18/04/2015
  2191                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2192                              <1> 	;
  2193                              <1> 	; INPUT -> 
  2194                              <1> 	;	EAX = swap disk/file offset address
  2195                              <1> 	;	      (bit 1 to bit 31)
  2196                              <1> 	; OUTPUT ->
  2197                              <1> 	;	[swpd_free] is increased
  2198                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  2199                              <1> 	;
  2200                              <1> 	; Modified Registers -> EAX
  2201                              <1> 	;
  2202 00003818 53                  <1> 	push	ebx
  2203 00003819 52                  <1> 	push	edx
  2204                              <1> 	;
  2205 0000381A C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  2206                              <1> 				     ; 3 bits right
  2207                              <1> 				     ; to get swap block/page number
  2208 0000381D 89C2                <1> 	mov	edx, eax
  2209                              <1> 	; 15/09/2015
  2210 0000381F C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
  2211                              <1> 				     ; (1 allocation bit = 1 page)
  2212                              <1> 				     ; (1 allocation bytes = 8 pages)
  2213 00003822 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2214                              <1> 				     ; (to get 32 bit position)			
  2215                              <1> 	;
  2216 00003825 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2217 0000382A 01D3                <1> 	add	ebx, edx
  2218 0000382C 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2219                              <1> 				     ; (allocation bit position)	 
  2220 0000382F 3B05[52F10000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  2221                              <1> 				     ; than the address in 'swpd_next' ?
  2222                              <1> 				     ; (next/first free block value)		
  2223 00003835 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2224 00003837 A3[52F10000]        <1> 	mov	[swpd_next], eax     ; yes	
  2225                              <1> uswpbl_1:
  2226 0000383C 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
  2227                              <1> 				     ; set relevant bit to 1.
  2228                              <1> 				     ; set CF to the previous bit value	
  2229 0000383F F5                  <1> 	cmc			     ; complement carry flag	
  2230 00003840 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2231                              <1> 				     ; if the block is already deallocated
  2232                              <1> 				     ; before.	
  2233 00003842 FF05[4EF10000]      <1>         inc     dword [swpd_free]
  2234                              <1> uswpbl_2:
  2235 00003848 5A                  <1> 	pop	edx
  2236 00003849 5B                  <1> 	pop	ebx
  2237 0000384A C3                  <1> 	retn
  2238                              <1> 
  2239                              <1> link_swap_block:
  2240                              <1> 	; 01/07/2015
  2241                              <1> 	; 18/04/2015
  2242                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2243                              <1> 	;
  2244                              <1> 	; INPUT -> none
  2245                              <1> 	;
  2246                              <1> 	; OUTPUT ->
  2247                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  2248                              <1> 	;	      in sectors (corresponding 
  2249                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  2250                              <1> 	;
  2251                              <1> 	;	CF = 1 and EAX = 0 
  2252                              <1> 	; 		   if there is not a free block to be allocated	
  2253                              <1> 	;
  2254                              <1> 	; Modified Registers -> none (except EAX)
  2255                              <1> 	;
  2256                              <1> 
  2257                              <1> 	;mov	eax, [swpd_free]
  2258                              <1> 	;and	eax, eax
  2259                              <1> 	;jz	short out_of_swpspc
  2260                              <1> 	;
  2261 0000384B 53                  <1> 	push	ebx
  2262 0000384C 51                  <1> 	push	ecx
  2263                              <1> 	;
  2264 0000384D BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2265 00003852 89D9                <1> 	mov	ecx, ebx
  2266 00003854 031D[52F10000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2267                              <1> 				 ; next_free_swap_block >> 5
  2268 0000385A 030D[56F10000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2269                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2270                              <1> lswbl_scan:
  2271 00003860 39CB                <1> 	cmp	ebx, ecx
  2272 00003862 770A                <1> 	ja	short lswbl_notfound
  2273                              <1> 	;
  2274 00003864 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2275                              <1> 			   ; Clears ZF if a bit is found set (1) and 
  2276                              <1> 			   ; loads the destination with an index to
  2277                              <1> 			   ; first set bit. (0 -> 31) 
  2278                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2279                              <1> 	; 01/07/2015
  2280 00003867 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  2281                              <1> 			 ;
  2282                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
  2283                              <1> 			 ;	  with value of 1 means 
  2284                              <1> 			 ;	  the corresponding page is free 
  2285                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
  2286 00003869 83C304              <1> 	add	ebx, 4
  2287                              <1> 			 ; We return back for searching next page block
  2288                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
  2289                              <1> 			 ;	 we always will find at least 1 free block here.
  2290 0000386C EBF2                <1> 	jmp    	short lswbl_scan
  2291                              <1> 	;
  2292                              <1> lswbl_notfound:	
  2293 0000386E 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2294 00003874 890D[52F10000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2295                              <1> 				 ; (unlink_swap_block procedure will change it)
  2296 0000387A 31C0                <1> 	xor	eax, eax
  2297 0000387C A3[4EF10000]        <1> 	mov	[swpd_free], eax
  2298 00003881 F9                  <1> 	stc
  2299                              <1> lswbl_ok:
  2300 00003882 59                  <1> 	pop	ecx
  2301 00003883 5B                  <1> 	pop	ebx
  2302 00003884 C3                  <1> 	retn
  2303                              <1> 	;
  2304                              <1> ;out_of_swpspc:
  2305                              <1> ;	stc
  2306                              <1> ;	retn
  2307                              <1> 
  2308                              <1> lswbl_found:
  2309 00003885 89D9                <1> 	mov	ecx, ebx
  2310 00003887 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2311 0000388D 890D[52F10000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2312                              <1> 				 ; address/offset (to the next)
  2313 00003893 FF0D[4EF10000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2314                              <1> 	;
  2315 00003899 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2316                              <1> 				 ; is copied into the Carry Flag and then cleared
  2317                              <1> 				 ; in the destination.
  2318                              <1> 				 ;
  2319                              <1> 				 ; Reset the bit which is corresponding to the 
  2320                              <1> 				 ; (just) allocated block.
  2321 0000389C C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2322 0000389F 01C8                <1> 	add	eax, ecx	 ; = block number
  2323 000038A1 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  2324                              <1> 				 ; 1 block =  8 sectors
  2325                              <1> 	;
  2326                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
  2327                              <1> 	;
  2328                              <1> 	; NOTE: The relevant page table entry will be updated
  2329                              <1> 	;       according to this EAX value...
  2330                              <1> 	;
  2331 000038A4 EBDC                <1> 	jmp	short lswbl_ok
  2332                              <1> 
  2333                              <1> logical_disk_read:
  2334                              <1> 	; 20/07/2015
  2335                              <1> 	; 09/03/2015 (temporary code here)
  2336                              <1> 	;
  2337                              <1> 	; INPUT ->
  2338                              <1> 	; 	ESI = Logical disk description table address
  2339                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2340                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2341                              <1> 	; 	ECX = Sector count
  2342                              <1> 	;
  2343                              <1> 	;
  2344 000038A6 C3                  <1> 	retn
  2345                              <1> 
  2346                              <1> logical_disk_write:
  2347                              <1> 	; 20/07/2015
  2348                              <1> 	; 09/03/2015 (temporary code here)
  2349                              <1> 	;
  2350                              <1> 	; INPUT ->
  2351                              <1> 	; 	ESI = Logical disk description table address
  2352                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2353                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2354                              <1> 	; 	ECX = Sector count
  2355                              <1> 	;
  2356 000038A7 C3                  <1> 	retn
  2357                              <1> 
  2358                              <1> get_physical_addr:
  2359                              <1> 	; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  2360                              <1> 	; 18/10/2015
  2361                              <1> 	; 29/07/2015
  2362                              <1> 	; 20/07/2015
  2363                              <1> 	; 04/06/2015
  2364                              <1> 	; 20/05/2015
  2365                              <1> 	; 28/04/2015
  2366                              <1> 	; 18/04/2015
  2367                              <1> 	; Get physical address
  2368                              <1> 	;     (allocates a new page for user if it is not present)
  2369                              <1> 	;	
  2370                              <1> 	; (This subroutine is needed for mapping user's virtual 
  2371                              <1> 	; (buffer) address to physical address (of the buffer).)
  2372                              <1> 	; ('sys write', 'sys read' system calls...)
  2373                              <1> 	;
  2374                              <1> 	; INPUT ->
  2375                              <1> 	;	EBX = virtual address
  2376                              <1> 	;	u.pgdir = page directory (physical) address
  2377                              <1> 	;
  2378                              <1> 	; OUTPUT ->
  2379                              <1> 	;	EAX = physical address 
  2380                              <1> 	;	EBX = linear address	
  2381                              <1> 	;	EDX = physical address of the page frame
  2382                              <1> 	;	      (with attribute bits)
  2383                              <1> 	;	ECX = byte count within the page frame
  2384                              <1> 	;
  2385                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  2386                              <1> 	;
  2387 000038A8 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2388                              <1> get_physical_addr_x: ; 27/05/2016
  2389 000038AE A1[D9E30000]        <1> 	mov	eax, [u.pgdir]
  2390 000038B3 E8F9F9FFFF          <1> 	call	get_pte
  2391                              <1> 		; EDX = Page table entry address (if CF=0)
  2392                              <1> 	        ;       Page directory entry address (if CF=1)
  2393                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  2394                              <1> 		; EAX = Page table entry value (page address)
  2395                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  2396 000038B8 731C                <1> 	jnc	short gpa_1
  2397                              <1> 	;
  2398 000038BA E8D7F8FFFF          <1> 	call	allocate_page
  2399 000038BF 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2400                              <1> gpa_0:
  2401 000038C1 E84AF9FFFF          <1> 	call 	clear_page
  2402                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2403 000038C6 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  2404                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  2405                              <1> 			   ; (user, writable, present page)	
  2406 000038C8 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2407 000038CA A1[D9E30000]        <1> 	mov	eax, [u.pgdir]	
  2408 000038CF E8DDF9FFFF          <1> 	call	get_pte
  2409 000038D4 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2410                              <1> gpa_1:
  2411                              <1> 	; EAX = PTE value, EDX = PTE address
  2412 000038D6 A801                <1> 	test 	al, PTE_A_PRESENT
  2413 000038D8 751A                <1> 	jnz	short gpa_3
  2414 000038DA 09C0                <1> 	or	eax, eax
  2415 000038DC 7430                <1> 	jz	short gpa_4  ; Allocate a new page
  2416                              <1> 	; 20/07/2015
  2417 000038DE 55                  <1> 	push	ebp
  2418 000038DF 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2419                              <1> 	; reload swapped page
  2420 000038E1 E83C000000          <1> 	call	reload_page ; 28/04/2015
  2421 000038E6 5D                  <1> 	pop	ebp
  2422 000038E7 7224                <1> 	jc	short gpa_retn
  2423                              <1> gpa_2:
  2424                              <1> 	; 20/07/2015
  2425                              <1> 	; 20/05/2015
  2426                              <1> 	; add this page to swap queue
  2427 000038E9 50                  <1> 	push	eax 
  2428                              <1> 	; EBX = virtual address
  2429 000038EA E8E3FEFFFF          <1> 	call 	add_to_swap_queue
  2430 000038EF 58                  <1> 	pop	eax
  2431                              <1> 		; PTE address in EDX
  2432                              <1> 		; virtual address in EBX
  2433                              <1> 	; EAX = memory page address
  2434 000038F0 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  2435                              <1> 				  ; present flag, bit 0 = 1
  2436                              <1> 				  ; user flag, bit 2 = 1	
  2437                              <1> 				  ; writable flag, bit 1 = 1
  2438 000038F2 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2439                              <1> gpa_3:
  2440                              <1> 	; 18/10/2015
  2441 000038F4 89D9                <1> 	mov	ecx, ebx
  2442 000038F6 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2443 000038FC 89C2                <1> 	mov 	edx, eax
  2444 000038FE 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2445 00003902 01C8                <1> 	add	eax, ecx
  2446 00003904 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2447 00003906 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2448 0000390C F8                  <1> 	clc
  2449                              <1> gpa_retn:
  2450 0000390D C3                  <1> 	retn	
  2451                              <1> gpa_4:	
  2452 0000390E E883F8FFFF          <1> 	call	allocate_page
  2453 00003913 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2454 00003915 E8F6F8FFFF          <1> 	call	clear_page
  2455 0000391A EBCD                <1> 	jmp	short gpa_2
  2456                              <1> 
  2457                              <1> gpa_im_err:	
  2458 0000391C B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2459                              <1> 				  ; Major error = 0 (No protection fault)	
  2460 00003921 C3                  <1> 	retn
  2461                              <1> 
  2462                              <1> reload_page:
  2463                              <1> 	; 20/07/2015
  2464                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  2465                              <1> 	;
  2466                              <1> 	; Reload (Restore) swapped page at memory
  2467                              <1> 	;
  2468                              <1> 	; INPUT -> 
  2469                              <1> 	;	EBP = Virtual (linear) memory address
  2470                              <1> 	;	EAX = PTE value (swap disk sector address)
  2471                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  2472                              <1> 	; OUTPUT ->
  2473                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  2474                              <1> 	;
  2475                              <1> 	;	CF = 1 and EAX = error code
  2476                              <1> 	;
  2477                              <1> 	; Modified Registers -> none (except EAX)
  2478                              <1> 	;
  2479 00003922 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2480 00003924 53                  <1> 	push	ebx      ;
  2481 00003925 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2482 00003927 E86AF8FFFF          <1> 	call	allocate_page
  2483 0000392C 720C                <1> 	jc	short rlp_im_err
  2484 0000392E 93                  <1> 	xchg 	eax, ebx	
  2485                              <1> 	; EBX = Physical memory (page) address
  2486                              <1> 	; EAX = Swap disk (offset) address
  2487                              <1> 	; EBP = Virtual (linear) memory address
  2488 0000392F E89BFCFFFF          <1> 	call	swap_in
  2489 00003934 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2490 00003936 89D8                <1> 	mov	eax, ebx	
  2491                              <1> rlp_retn:
  2492 00003938 5B                  <1> 	pop	ebx
  2493 00003939 C3                  <1> 	retn
  2494                              <1> 	
  2495                              <1> rlp_im_err:	
  2496 0000393A B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2497                              <1> 				  ; Major error = 0 (No protection fault)	
  2498 0000393F EBF7                <1> 	jmp	short rlp_retn
  2499                              <1> 
  2500                              <1> rlp_swp_err:
  2501 00003941 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2502 00003946 EBF0                <1> 	jmp	short rlp_retn
  2503                              <1> 
  2504                              <1> 
  2505                              <1> copy_page_dir:
  2506                              <1> 	; 19/09/2015
  2507                              <1> 	; temporary - 07/09/2015
  2508                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2509                              <1> 	;
  2510                              <1> 	; INPUT -> 
  2511                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  2512                              <1> 	;		    page directory.
  2513                              <1> 	; OUTPUT ->
  2514                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  2515                              <1> 	;	       page directory.
  2516                              <1> 	;	(New page directory with new page table entries.)
  2517                              <1> 	;	(New page tables with read only copies of the parent's
  2518                              <1> 	;	pages.)
  2519                              <1> 	;	EAX = 0 -> Error (CF = 1)
  2520                              <1> 	;
  2521                              <1> 	; Modified Registers -> none (except EAX)
  2522                              <1> 	;
  2523 00003948 E849F8FFFF          <1> 	call	allocate_page
  2524 0000394D 723E                <1> 	jc	short cpd_err
  2525                              <1> 	;
  2526 0000394F 55                  <1> 	push	ebp ; 20/07/2015
  2527 00003950 56                  <1> 	push	esi
  2528 00003951 57                  <1> 	push	edi
  2529 00003952 53                  <1> 	push	ebx
  2530 00003953 51                  <1> 	push	ecx
  2531 00003954 8B35[D9E30000]      <1> 	mov	esi, [u.pgdir]
  2532 0000395A 89C7                <1> 	mov	edi, eax
  2533 0000395C 50                  <1> 	push	eax ; save child's page directory address
  2534                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  2535                              <1> 	; (use same system space for all user page tables) 
  2536 0000395D A5                  <1> 	movsd
  2537 0000395E BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2538 00003963 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2539                              <1> cpd_0:	
  2540 00003968 AD                  <1> 	lodsd
  2541                              <1> 	;or	eax, eax
  2542                              <1>         ;jnz     short cpd_1
  2543 00003969 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2544 0000396B 7508                <1> 	jnz	short cpd_1
  2545                              <1>  	; (virtual address at the end of the page table)	
  2546 0000396D 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2547 00003973 EB0F                <1> 	jmp	short cpd_2
  2548                              <1> cpd_1:	
  2549 00003975 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2550 00003979 89C3                <1> 	mov	ebx, eax
  2551                              <1> 	; EBX = Parent's page table address
  2552 0000397B E81F000000          <1> 	call	copy_page_table
  2553 00003980 720C                <1> 	jc	short cpd_p_err
  2554                              <1> 	; EAX = Child's page table address
  2555 00003982 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  2556                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  2557                              <1> 			 ; (present, writable, user)
  2558                              <1> cpd_2:
  2559 00003984 AB                  <1> 	stosd
  2560 00003985 E2E1                <1> 	loop	cpd_0
  2561                              <1> 	;
  2562 00003987 58                  <1> 	pop	eax  ; restore child's page directory address
  2563                              <1> cpd_3:
  2564 00003988 59                  <1> 	pop	ecx
  2565 00003989 5B                  <1> 	pop	ebx
  2566 0000398A 5F                  <1> 	pop	edi
  2567 0000398B 5E                  <1> 	pop	esi
  2568 0000398C 5D                  <1> 	pop	ebp
  2569                              <1> cpd_err:
  2570 0000398D C3                  <1> 	retn
  2571                              <1> cpd_p_err:
  2572                              <1> 	; release the allocated pages missing (recover free space)
  2573 0000398E 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2574 0000398F 8B1D[D9E30000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2575 00003995 E835F9FFFF          <1> 	call 	deallocate_page_dir
  2576 0000399A 29C0                <1> 	sub	eax, eax ; 0
  2577 0000399C F9                  <1> 	stc
  2578 0000399D EBE9                <1> 	jmp	short cpd_3	
  2579                              <1> 
  2580                              <1> copy_page_table:
  2581                              <1> 	; 19/09/2015
  2582                              <1> 	; temporary - 07/09/2015
  2583                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2584                              <1> 	;
  2585                              <1> 	; INPUT -> 
  2586                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  2587                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  2588                              <1> 	; OUTPUT ->
  2589                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  2590                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  2591                              <1> 	;	CF = 1 -> error 
  2592                              <1> 	;
  2593                              <1> 	; Modified Registers -> EBP (except EAX)
  2594                              <1> 	;
  2595 0000399F E8F2F7FFFF          <1> 	call	allocate_page
  2596 000039A4 725A                <1> 	jc	short cpt_err
  2597                              <1> 	;
  2598 000039A6 50                  <1> 	push	eax ; *
  2599                              <1> 	;push 	ebx
  2600 000039A7 56                  <1> 	push	esi
  2601 000039A8 57                  <1> 	push	edi
  2602 000039A9 52                  <1> 	push	edx
  2603 000039AA 51                  <1> 	push	ecx
  2604                              <1> 	;
  2605 000039AB 89DE                <1> 	mov	esi, ebx
  2606 000039AD 89C7                <1> 	mov	edi, eax
  2607 000039AF 89C2                <1> 	mov	edx, eax
  2608 000039B1 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2609                              <1> cpt_0:
  2610 000039B7 AD                  <1> 	lodsd
  2611 000039B8 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2612 000039BA 750B                <1> 	jnz	short cpt_1
  2613 000039BC 21C0                <1> 	and	eax, eax
  2614 000039BE 7430                <1> 	jz	short cpt_2
  2615                              <1> 	; ebp = virtual (linear) address of the memory page
  2616 000039C0 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2617 000039C5 7234                <1> 	jc	short cpt_p_err
  2618                              <1> cpt_1:
  2619 000039C7 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2620 000039CB 89C1                <1> 	mov	ecx, eax
  2621                              <1> 	; Allocate a new page for the child process
  2622 000039CD E8C4F7FFFF          <1> 	call	allocate_page
  2623 000039D2 7227                <1> 	jc	short cpt_p_err
  2624 000039D4 57                  <1> 	push	edi
  2625 000039D5 56                  <1> 	push	esi
  2626 000039D6 89CE                <1> 	mov	esi, ecx
  2627 000039D8 89C7                <1> 	mov	edi, eax
  2628 000039DA B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2629 000039DF F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2630 000039E1 5E                  <1> 	pop	esi
  2631 000039E2 5F                  <1> 	pop	edi
  2632                              <1> 	; 
  2633 000039E3 53                  <1> 	push	ebx
  2634 000039E4 50                  <1> 	push	eax
  2635 000039E5 89EB                <1> 	mov	ebx, ebp
  2636                              <1> 	; ebx = virtual address of the memory page
  2637 000039E7 E8E6FDFFFF          <1> 	call	add_to_swap_queue
  2638 000039EC 58                  <1> 	pop	eax
  2639 000039ED 5B                  <1> 	pop	ebx
  2640                              <1> 	;
  2641                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2642 000039EE 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2643                              <1> cpt_2:
  2644 000039F0 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2645                              <1> 	;
  2646 000039F1 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2647                              <1> 	;
  2648 000039F7 39D7                <1> 	cmp	edi, edx
  2649 000039F9 72BC                <1> 	jb	short cpt_0
  2650                              <1> cpt_p_err:
  2651 000039FB 59                  <1> 	pop	ecx
  2652 000039FC 5A                  <1> 	pop	edx
  2653 000039FD 5F                  <1> 	pop	edi
  2654 000039FE 5E                  <1> 	pop	esi
  2655                              <1> 	;pop	ebx
  2656 000039FF 58                  <1> 	pop	eax ; *
  2657                              <1> cpt_err:
  2658 00003A00 C3                  <1> 	retn
  2659                              <1> 
  2660                              <1> 
  2661                              <1> allocate_memory_block:
  2662                              <1> 	; 03/04/2016
  2663                              <1> 	; 02/04/2016
  2664                              <1> 	; 01/04/2016
  2665                              <1> 	; 14/03/2016
  2666                              <1> 	; 13/03/2016
  2667                              <1> 	; 12/03/2016 (TRDOS 386 = TRDOS v2.0)
  2668                              <1> 	; Allocating contiguous memory pages (in the kernel's memory space)
  2669                              <1> 	;
  2670                              <1> 	; INPUT -> 
  2671                              <1> 	;	EAX = Beginning address (physical)
  2672                              <1> 	;	EAX = 0 -> Allocate memory block from the first proper aperture	
  2673                              <1> 	;	ECX = Number of bytes to be allocated
  2674                              <1> 	;
  2675                              <1> 	; OUTPUT ->
  2676                              <1> 	; 	1) cf = 0 -> successful
  2677                              <1> 	;	EAX = Beginning (physical) address of the allocated memory block
  2678                              <1> 	;	ECX = Number of allocated bytes (rounded up to page borders) 
  2679                              <1> 	;	2) cf = 1 -> unsuccessful
  2680                              <1> 	;	 2.1) If EAX > 0 -> 
  2681                              <1> 	;	      (Number of requested pages is more than # of free pages
  2682                              <1> 	;	       but contiguous free pages -the aperture- is not enough!)	   	
  2683                              <1> 	;	      EAX = Beginning address of available aperture
  2684                              <1> 	;		    (one of all aperture with max. aperture size/length)		
  2685                              <1> 	;	      ECX = Size of available aperture (memory block) in bytes
  2686                              <1> 	;	 2.2) If EAX = 0 -> Out of memory error 
  2687                              <1> 	;	            (number of free pages is less than requested number)
  2688                              <1> 	;	      ECX = Total number of free bytes (free pages * 4096) 
  2689                              <1> 	;		    (It is not number of contiguous free bytes)	
  2690                              <1> 	;
  2691                              <1> 	; (Modified Registers -> EAX, ECX)
  2692                              <1> 	;
  2693                              <1> 	; PURPOSE: Loading a file at memory for copying or running etc.
  2694                              <1> 	; If this procedure returns with cf is set, ECX contains maximum
  2695                              <1> 	; available space and EAX contains the beginning address of it.
  2696                              <1> 	; If EAX has zero, ECX contains total number of free bytes.
  2697                              <1> 	; If requested block has been successfully allocated (by rounding up to
  2698                              <1> 	; the last page border), it must be deallocated later by using
  2699                              <1> 	; 'dealloacate_memory_block' procedure.    
  2700                              <1> 
  2701 00003A01 52                  <1> 	push	edx ; *
  2702 00003A02 BAFF0F0000          <1> 	mov	edx, PAGE_SIZE - 1   ; 4095
  2703 00003A07 01D1                <1> 	add	ecx, edx
  2704 00003A09 01D0                <1> 	add	eax, edx
  2705 00003A0B C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2706                              <1> 
  2707                              <1> 	; ECX = number of contiguous pages to be allocated
  2708 00003A0E 8B15[C0D20000]      <1> 	mov	edx, [free_pages]
  2709 00003A14 39D1                <1> 	cmp	ecx, edx
  2710 00003A16 7775                <1> 	ja	short amb_6
  2711                              <1> 
  2712 00003A18 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; 12
  2713                              <1> 
  2714 00003A1B 89C2                <1> 	mov	edx, eax 	     ; page number
  2715 00003A1D C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2716                              <1> 				     ; (1 allocation bit = 1 page)
  2717                              <1> 				     ; (1 allocation bytes = 8 pages)
  2718 00003A20 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2719                              <1> 				     ; (to get 32 bit position)	
  2720 00003A23 53                  <1> 	push	ebx ; **
  2721                              <1> amb_0:
  2722 00003A24 890D[74DF0000]      <1> 	mov	[mem_ipg_count], ecx ; initial (reset) value of page count
  2723 00003A2A 890D[78DF0000]      <1> 	mov	[mem_pg_count], ecx
  2724 00003A30 31C9                <1> 	xor	ecx, ecx ; 0
  2725 00003A32 890D[7CDF0000]      <1> 	mov	[mem_aperture], ecx ; 0
  2726 00003A38 890D[80DF0000]      <1> 	mov	[mem_max_aperture], ecx ; 0
  2727                              <1> 	
  2728 00003A3E BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address.
  2729 00003A43 3B15[C4D20000]      <1> 	cmp	edx, [next_page]     ; Is the beginning page address lower
  2730                              <1> 				     ; than the address in 'next_page' ?
  2731                              <1> 				     ; (the first/next free page of user space)		
  2732 00003A49 7208                <1> 	jb	short amb_1
  2733 00003A4B 3B15[C8D20000]      <1> 	cmp 	edx, [last_page]     ; is the beginning page address higher
  2734                              <1> 				     ; than the address in 'last_page' ?
  2735                              <1> 				     ; (end of the memory)		
  2736 00003A51 7606                <1> 	jna	short amb_2	     ; no	
  2737                              <1> amb_1:
  2738 00003A53 8B15[C4D20000]      <1> 	mov	edx, [next_page]     ; yes (reset to the first page of user space)
  2739                              <1> amb_2:
  2740 00003A59 01D3                <1> 	add	ebx, edx
  2741                              <1> 
  2742 00003A5B A3[84DF0000]        <1> 	mov	[mem_pg_pos], eax    ; beginning page no (for curr. mem. aperture)
  2743 00003A60 A3[88DF0000]        <1>  	mov	[mem_max_pg_pos], eax ; beginning page no for max. mem. aperture
  2744                              <1> 
  2745 00003A65 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only (0 to 31)
  2746                              <1> 				     ; (allocation bit position)	 
  2747 00003A68 744B                <1> 	jz	short amb_10	     ; 0	
  2748                              <1> amb_3:
  2749 00003A6A 8B13                <1> 	mov	edx, [ebx]
  2750 00003A6C 88C1                <1> 	mov	cl, al ; 1 to 31
  2751 00003A6E D3EA                <1> 	shr	edx, cl
  2752 00003A70 89D0                <1> 	mov	eax, edx
  2753                              <1> amb_4:
  2754 00003A72 D1E8                <1> 	shr	eax, 1 ; (***)
  2755 00003A74 7321                <1> 	jnc	short amb_7
  2756 00003A76 FF05[7CDF0000]      <1> 	inc	dword [mem_aperture]
  2757 00003A7C FF0D[78DF0000]      <1> 	dec	dword [mem_pg_count]
  2758 00003A82 747B                <1> 	jz	short amb_15
  2759                              <1> amb_5:
  2760 00003A84 80F91F              <1> 	cmp	cl, 31
  2761 00003A87 7317                <1> 	jnb	short amb_8
  2762 00003A89 FEC1                <1> 	inc	cl
  2763 00003A8B EBE5                <1> 	jmp	short amb_4
  2764                              <1> 
  2765                              <1> amb_6:	; out_of_memory
  2766 00003A8D 31C0                <1> 	xor	eax, eax ; 0
  2767 00003A8F 89D1                <1> 	mov	ecx, edx ; free pages
  2768 00003A91 C1E10C              <1> 	shl	ecx, PAGE_SHIFT
  2769 00003A94 5A                  <1> 	pop	edx ; *
  2770 00003A95 F9                  <1> 	stc
  2771 00003A96 C3                  <1> 	retn
  2772                              <1> amb_7:
  2773 00003A97 50                  <1> 	push	eax ; (***) allocation bits (in shifted status)
  2774 00003A98 E819010000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2775 00003A9D 58                  <1> 	pop	eax ; (***)
  2776 00003A9E EBE4                <1> 	jmp	short amb_5
  2777                              <1> amb_8:
  2778 00003AA0 28C9                <1> 	sub	cl, cl ; 0
  2779                              <1> amb_9:
  2780 00003AA2 89DA                <1> 	mov	edx, ebx
  2781 00003AA4 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL
  2782 00003AAA 3B15[C8D20000]      <1> 	cmp	edx, [last_page]
  2783 00003AB0 7336                <1> 	jnb	short amb_14 ; contiguous pages not enough
  2784 00003AB2 83C304              <1> 	add	ebx, 4
  2785                              <1> amb_10:
  2786 00003AB5 8B03                <1> 	mov	eax, [ebx]
  2787 00003AB7 21C0                <1> 	and 	eax, eax
  2788 00003AB9 7406                <1>         jz      short amb_11 ; there is not a free page bit in this alloc dword
  2789 00003ABB 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0
  2790 00003ABC 740A                <1> 	jz	short amb_12 ; all of bits are set (32 free pages)
  2791 00003ABE 48                  <1> 	dec	eax
  2792 00003ABF EBB1                <1> 	jmp	short amb_4
  2793                              <1> amb_11:
  2794 00003AC1 E8F0000000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2795 00003AC6 EBDA                <1> 	jmp	short amb_9	
  2796                              <1> amb_12:
  2797 00003AC8 B120                <1> 	mov	cl, 32
  2798 00003ACA 390D[78DF0000]      <1> 	cmp	[mem_pg_count], ecx ; 32
  2799 00003AD0 7306                <1> 	jnb	short amb_13
  2800 00003AD2 8B0D[78DF0000]      <1> 	mov	ecx, [mem_pg_count]
  2801                              <1> amb_13:
  2802 00003AD8 010D[7CDF0000]      <1> 	add	[mem_aperture], ecx
  2803 00003ADE 290D[78DF0000]      <1> 	sub	[mem_pg_count], ecx
  2804 00003AE4 7619                <1> 	jna	short amb_15
  2805 00003AE6 EBB8                <1> 	jmp	short amb_8
  2806                              <1> amb_14:
  2807 00003AE8 A1[88DF0000]        <1> 	mov	eax, [mem_max_pg_pos] ; begin address of max. mem aperture	
  2808 00003AED 8B0D[80DF0000]      <1> 	mov	ecx, [mem_max_aperture] ; max. (largest) memory aperture
  2809 00003AF3 C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2810 00003AF6 C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2811 00003AF9 F9                  <1> 	stc
  2812 00003AFA E9AC000000          <1>         jmp     amb_25
  2813                              <1> 
  2814                              <1> amb_15: ; OK !
  2815 00003AFF A1[84DF0000]        <1> 	mov	eax, [mem_pg_pos]    ; Beginning address as page number
  2816 00003B04 8B0D[7CDF0000]      <1> 	mov	ecx, [mem_aperture]  ; Free contiguous page count
  2817                              <1> amb_16:
  2818                              <1> 	; allocate contiguous memory pages (via memory allocation table bits)
  2819 00003B0A 89C2                <1> 	mov	edx, eax
  2820 00003B0C C1EA05              <1> 	shr	edx, 5 ; 32 pages in one allocation dword (32 bits)
  2821 00003B0F BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2822 00003B14 01D3                <1> 	add	ebx, edx
  2823 00003B16 83E01F              <1> 	and	eax, 1Fh ; 31
  2824                              <1> 	; 03/04/2016
  2825 00003B19 BA20000000          <1> 	mov	edx, 32
  2826 00003B1E 28C2                <1> 	sub	dl, al
  2827 00003B20 39CA                <1> 	cmp	edx, ecx
  2828 00003B22 7602                <1> 	jna	short amb_17
  2829 00003B24 89CA                <1> 	mov	edx, ecx
  2830                              <1> amb_17:
  2831 00003B26 29D1                <1> 	sub	ecx, edx
  2832 00003B28 51                  <1> 	push	ecx ; ***
  2833 00003B29 89D1                <1> 	mov	ecx, edx
  2834                              <1> amb_18:		
  2835 00003B2B 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2836                              <1> 				 ; is copied into the Carry Flag and then cleared
  2837                              <1> 				 ; in the destination.
  2838 00003B2E FF0D[C0D20000]      <1> 	dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2839 00003B34 49                  <1> 	dec	ecx
  2840 00003B35 7404                <1> 	jz	short amb_19
  2841 00003B37 FEC0                <1> 	inc	al
  2842 00003B39 EBF0                <1> 	jmp	short amb_18
  2843                              <1> amb_19:	
  2844 00003B3B 59                  <1> 	pop	ecx ; ***
  2845 00003B3C 21C9                <1> 	and	ecx, ecx ; 0 ?
  2846 00003B3E 741E                <1> 	jz	short amb_22	
  2847                              <1> 	; 01/04/2016
  2848 00003B40 B020                <1> 	mov	al, 32
  2849                              <1> amb_20:
  2850 00003B42 83C304              <1> 	add	ebx, 4
  2851 00003B45 39C1                <1> 	cmp	ecx, eax ; 32
  2852 00003B47 7305                <1> 	jnb	short amb_21
  2853                              <1> 	; ECX < 32
  2854 00003B49 28C0                <1> 	sub	al, al ; 0
  2855 00003B4B 50                  <1> 	push	eax ; 0 ***
  2856 00003B4C EBDD                <1> 	jmp	short amb_18
  2857                              <1> amb_21:
  2858 00003B4E 2905[C0D20000]      <1> 	sub	[free_pages], eax ; [free_pages] = [free_pages] - 32
  2859 00003B54 C70300000000        <1> 	mov	dword [ebx], 0 ; reset 32 bits
  2860 00003B5A 29C1                <1> 	sub	ecx, eax ; 32
  2861 00003B5C 75E4                <1> 	jnz	short amb_20
  2862                              <1> amb_22:
  2863 00003B5E A1[84DF0000]        <1> 	mov	eax, [mem_pg_pos]   ; Beginning address as page number
  2864 00003B63 8B0D[7CDF0000]      <1> 	mov	ecx, [mem_aperture] ; Free contiguous page count
  2865                              <1> 	; [next_page] update
  2866 00003B69 89C2                <1> 	mov	edx, eax
  2867                              <1> 	; 03/04/2016
  2868 00003B6B C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2869                              <1> 				     ; (1 allocation bit = 1 page)
  2870                              <1> 				     ; (1 allocation bytes = 8 pages)
  2871 00003B6E 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2872                              <1> 				     ; (to get 32 bit position)	
  2873 00003B71 3B15[C4D20000]      <1> 	cmp	edx, [next_page] ; first free page pointer offset
  2874 00003B77 7732                <1> 	ja	short amb_25
  2875 00003B79 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2876 00003B7E 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2877 00003B82 7721                <1> 	ja	short amb_24
  2878 00003B84 89C2                <1> 	mov	edx, eax
  2879 00003B86 01CA                <1> 	add	edx, ecx
  2880 00003B88 C1EA03              <1> 	shr	edx, 3
  2881 00003B8B 80E2FC              <1> 	and	dl, 0FCh
  2882                              <1> amb_23:
  2883 00003B8E 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2884 00003B92 7711                <1> 	ja	short amb_24
  2885 00003B94 83C204              <1> 	add	edx, 4
  2886 00003B97 3B15[C8D20000]      <1> 	cmp	edx, [last_page]    ; last page pointer offset
  2887 00003B9D 76EF                <1> 	jna	short amb_23
  2888 00003B9F 8B15[CCD20000]      <1> 	mov	edx, [first_page]   ; (for) beginning of user's space
  2889                              <1> amb_24:
  2890 00003BA5 8915[C4D20000]      <1> 	mov	[next_page], edx
  2891                              <1> amb_25:
  2892 00003BAB 9C                  <1> 	pushf
  2893 00003BAC C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2894 00003BAF C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2895 00003BB2 9D                  <1> 	popf
  2896 00003BB3 5B                  <1> 	pop	ebx ; **
  2897 00003BB4 5A                  <1> 	pop	edx ; *
  2898 00003BB5 C3                  <1> 	retn
  2899                              <1> 
  2900                              <1> amb_26:	; set maximum free memory aperture (free memory block size) 
  2901 00003BB6 89DA                <1> 	mov	edx, ebx ; current address
  2902 00003BB8 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL ; MAT beginning address
  2903                              <1> 	; 02/04/2016 
  2904 00003BBE C1E203              <1> 	shl	edx, 3 ; MAT byte offset * 8 = page number base
  2905 00003BC1 01CA                <1> 	add	edx, ecx ; current page number (ecx =  0 to 31)
  2906                              <1> 	;
  2907 00003BC3 A1[7CDF0000]        <1> 	mov	eax, [mem_aperture]
  2908 00003BC8 21C0                <1> 	and	eax, eax
  2909 00003BCA 7424                <1>         jz      short amb_27
  2910 00003BCC C705[7CDF0000]0000- <1>         mov     dword [mem_aperture], 0
  2910 00003BD4 0000                <1>
  2911 00003BD6 3B05[80DF0000]      <1> 	cmp	eax, [mem_max_aperture]
  2912 00003BDC 7612                <1> 	jna	short amb_27
  2913 00003BDE A3[80DF0000]        <1> 	mov	[mem_max_aperture], eax
  2914                              <1> 	;
  2915 00003BE3 89D0                <1> 	mov	eax, edx
  2916 00003BE5 2B05[80DF0000]      <1> 	sub	eax, [mem_max_aperture] ; the last aperture size in pages
  2917                              <1> 	; EAX = Beginning page number of the max. aperture 
  2918 00003BEB A3[88DF0000]        <1> 	mov	[mem_max_pg_pos], eax
  2919                              <1> amb_27: 
  2920 00003BF0 42                  <1> 	inc	edx	
  2921 00003BF1 8915[84DF0000]      <1> 	mov	[mem_pg_pos], edx ; next page
  2922                              <1> 
  2923 00003BF7 A1[74DF0000]        <1> 	mov	eax, [mem_ipg_count] ; initial (reset) value of page count
  2924 00003BFC A3[78DF0000]        <1> 	mov	[mem_pg_count], eax
  2925                              <1> 
  2926 00003C01 C3                  <1> 	retn
  2927                              <1> 
  2928                              <1> deallocate_memory_block:
  2929                              <1> 	; 03/04/2016
  2930                              <1> 	; 14/03/2016 (TRDOS 386 = TRDOS v2.0)
  2931                              <1> 	; Deallocating contiguous memory pages (in the kernel's memory space)
  2932                              <1> 	;
  2933                              <1> 	; INPUT -> 
  2934                              <1> 	;	EAX = Beginning address (physical)
  2935                              <1> 	;	ECX = Number of bytes to be deallocated
  2936                              <1> 	;
  2937                              <1> 	; OUTPUT ->
  2938                              <1> 	;	Mememory Allocation Table bits will be updated
  2939                              <1> 	;	[free_pages] will be changed (increased)
  2940                              <1> 	;
  2941                              <1> 	; (Modified Registers -> EAX, ECX)
  2942                              <1> 	;
  2943                              <1> 	; PURPOSE: Unloading/Freeing a file -or an allocated memory block- 
  2944                              <1> 	; at memory after copying, running, saving, reading, writing etc.
  2945                              <1> 	;
  2946                              <1> 
  2947 00003C02 52                  <1> 	push	edx ; *
  2948 00003C03 53                  <1> 	push	ebx ; **
  2949                              <1> 
  2950 00003C04 C1E80C              <1> 	shr	eax, PAGE_SHIFT	     ; 12
  2951 00003C07 C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2952                              <1> 
  2953                              <1> 	; EAX = Beginning page number
  2954                              <1> 	; ECX = Number of contiguous pages to be deallocated
  2955                              <1> damb_0:
  2956                              <1> 	; deallocate contiguous memory pages (via memory allocation table bits)
  2957 00003C0A 89C2                <1> 	mov	edx, eax
  2958 00003C0C C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2959                              <1> 				     ; (1 allocation bit = 1 page)
  2960                              <1> 				     ; (1 allocation bytes = 8 pages)
  2961 00003C0F 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2962                              <1> 				     ; (to get 32 bit position)	
  2963 00003C12 3B15[C4D20000]      <1> 	cmp	edx, [next_page] ; next free page
  2964 00003C18 7306                <1> 	jnb	short damb_1
  2965 00003C1A 8915[C4D20000]      <1> 	mov	[next_page], edx
  2966                              <1> damb_1:
  2967 00003C20 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2968 00003C25 01D3                <1> 	add	ebx, edx
  2969 00003C27 83E01F              <1> 	and	eax, 1Fh ; 31
  2970                              <1> 
  2971                              <1> 	; 03/04/2016
  2972 00003C2A BA20000000          <1> 	mov	edx, 32
  2973 00003C2F 28C2                <1> 	sub	dl, al
  2974 00003C31 39CA                <1> 	cmp	edx, ecx
  2975 00003C33 7602                <1> 	jna	short damb_2
  2976 00003C35 89CA                <1> 	mov	edx, ecx
  2977                              <1> damb_2:
  2978 00003C37 29D1                <1> 	sub	ecx, edx
  2979 00003C39 51                  <1> 	push	ecx ; ***
  2980 00003C3A 89D1                <1> 	mov	ecx, edx
  2981                              <1> damb_3:		
  2982 00003C3C 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
  2983                              <1> 				     ; set relevant bit to 1.
  2984                              <1> 				     ; set CF to the previous bit value	
  2985 00003C3F FF05[C0D20000]      <1> 	inc     dword [free_pages]   ; 1 page has been deallocated (X = X+1) 
  2986 00003C45 49                  <1> 	dec	ecx
  2987 00003C46 7404                <1> 	jz	short damb_4
  2988 00003C48 FEC0                <1> 	inc	al
  2989 00003C4A EBF0                <1> 	jmp	short damb_3
  2990                              <1> damb_4:	
  2991 00003C4C 59                  <1> 	pop	ecx ; ***
  2992 00003C4D 21C9                <1> 	and	ecx, ecx ; 0 ?
  2993 00003C4F 741E                <1> 	jz	short damb_7
  2994                              <1> 	; 03/04/2016
  2995 00003C51 B020                <1> 	mov	al, 32
  2996                              <1> damb_5:
  2997 00003C53 83C304              <1> 	add	ebx, 4
  2998 00003C56 39C1                <1> 	cmp	ecx, eax ; 32
  2999 00003C58 7305                <1> 	jnb	short damb_6
  3000                              <1> 	; ECX < 32
  3001 00003C5A 28C0                <1> 	sub	al, al ; 0
  3002 00003C5C 50                  <1> 	push	eax ; 0 ***
  3003 00003C5D EBDD                <1> 	jmp	short damb_3
  3004                              <1> damb_6:
  3005 00003C5F 0105[C0D20000]      <1> 	add	[free_pages], eax ; [free_pages] = [free_pages] + 32
  3006 00003C65 C703FFFFFFFF        <1> 	mov	dword [ebx], 0FFFFFFFFh ; set 32 bits
  3007 00003C6B 29C1                <1> 	sub	ecx, eax ; 32
  3008 00003C6D 75E4                <1> 	jnz	short damb_5
  3009                              <1> damb_7:
  3010 00003C6F 5B                  <1> 	pop	ebx ; **
  3011 00003C70 5A                  <1> 	pop	edx ; *
  3012 00003C71 C3                  <1> 	retn
  3013                              <1> 
  3014                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  3015                              <1> 
  3016                              <1> ;; Data:
  3017                              <1> 
  3018                              <1> ; 09/03/2015
  3019                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  3020                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  3021                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  3022                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  3023                              <1> ;swpd_next:  dd 0 ; next free page block
  3024                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
  1900                                  %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 00003C72 9C                  <1> 	pushfd
    30 00003C73 0E                  <1> 	push 	cs
    31 00003C74 E801000000          <1> 	call 	TIME_OF_DAY_1
    32 00003C79 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 00003C7A FB                  <1> 	sti				; INTERRUPTS BACK ON
   107                              <1> 	; 29/05/2016
   108 00003C7B 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   109                              <1> 	;
   110 00003C80 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   111 00003C83 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   112                              <1> 	; (*) jc short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   113 00003C84 721C                <1> 	jc	short _TIME_9 ; 29/05/2016
   114                              <1> 
   115 00003C86 1E                  <1> 	push	ds
   116 00003C87 56                  <1> 	push	esi
   117 00003C88 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   118 00003C8C 8EDE                <1> 	mov	ds, si
   119 00003C8E C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   120 00003C91 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   121 00003C94 FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   122 00003C95 FF96[A83C0000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   123                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   124 00003C9B FB                  <1> 	sti				; INTERRUPTS BACK ON
   125 00003C9C B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   126 00003C9E 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   127 00003C9F 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 00003CA0 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 00003CA2 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 00003CA7 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 00003CA8 [C83C0000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   165 00003CAC [DB3C0000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   166 00003CB0 [E93C0000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   167 00003CB4 [183D0000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   168 00003CB8 [5A3D0000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   169 00003CBC [873D0000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   170 00003CC0 [D43D0000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   171 00003CC4 [273E0000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   172                              <1> 
   173                              <1> RTC_TBE	equ	$
   174                              <1> 
   175                              <1> RTC_00:				; READ TIME COUNT
   176 00003CC8 A0[3CD30000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   177 00003CCD C605[3CD30000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   178 00003CD4 8B0D[38D30000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   179 00003CDA C3                  <1> 	retn
   180                              <1> 
   181                              <1> RTC_10:				; SET TIME COUNT
   182 00003CDB 890D[38D30000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   183 00003CE1 C605[3CD30000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   184 00003CE8 C3                  <1> 	retn				; RETURN WITH NO CARRY
   185                              <1> 
   186                              <1> RTC_20:				; GET RTC TIME
   187 00003CE9 E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   188 00003CEE 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   189                              <1> 
   190 00003CF0 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   191 00003CF2 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   192 00003CF7 88C6                <1> 	mov	dh, al			; SAVE
   193 00003CF9 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   194 00003CFB E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   195 00003D00 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   196 00003D02 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   197 00003D04 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   198 00003D06 E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   199 00003D0B 88C1                <1> 	mov	cl, al			; SAVE
   200 00003D0D B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   201 00003D0F E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   202 00003D14 88C5                <1> 	mov	ch, al			; SAVE
   203 00003D16 F8                  <1> 	clc				; SET CY= 0
   204                              <1> RTC_29:
   205 00003D17 C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   206                              <1> 
   207                              <1> RTC_30:				; SET RTC TIME
   208 00003D18 E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   209 00003D1D 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   210 00003D1F E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   211                              <1> RTC_35:
   212 00003D24 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   213 00003D26 B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   214 00003D28 E8E0010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   215 00003D2D 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   216 00003D2F B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   217 00003D31 E8D7010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   218 00003D36 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   219 00003D38 B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   220 00003D3A E8CE010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   221                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   222                              <1> 	;mov	ah, al
   223 00003D3F 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   224 00003D43 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   225 00003D48 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   226 00003D4A 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   227 00003D4C 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   228 00003D4F 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   229 00003D51 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   230 00003D53 E8B5010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   231 00003D58 F8                  <1> 	clc				; SET CY= 0
   232 00003D59 C3                  <1> 	retn				; RETURN WITH CY= 0
   233                              <1> 
   234                              <1> RTC_40:				; GET RTC DATE
   235 00003D5A E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   236 00003D5F 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   237                              <1> 
   238 00003D61 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   239 00003D63 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   240 00003D68 88C2                <1> 	mov	dl, al			; SAVE
   241 00003D6A B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   242 00003D6C E883010000          <1> 	call	CMOS_READ		; READ MONTH
   243 00003D71 88C6                <1> 	mov	dh, al			; SAVE
   244 00003D73 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   245 00003D75 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   246 00003D7A 88C1                <1> 	mov	cl, al			; SAVE
   247 00003D7C B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   248 00003D7E E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   249 00003D83 88C5                <1> 	mov	ch, al			; SAVE
   250 00003D85 F8                  <1> 	clc				; SET CY=0
   251                              <1> RTC_49:
   252 00003D86 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   253                              <1> 
   254                              <1> RTC_50:				; SET RTC DATE
   255 00003D87 E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   256 00003D8C 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   257 00003D8E E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   258                              <1> RTC_55:
   259 00003D93 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   260 00003D97 E871010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   261 00003D9C 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   262 00003D9E B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   263 00003DA0 E868010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   264 00003DA5 88F4                <1> 	mov	ah, dh			; GET MONTH
   265 00003DA7 B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   266 00003DA9 E85F010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   267 00003DAE 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   268 00003DB0 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   269 00003DB2 E856010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   270 00003DB7 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   271 00003DB9 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   272 00003DBB E84D010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   273                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   274                              <1> 	;mov	ah, al
   275 00003DC0 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   276 00003DC4 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   277 00003DC9 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   278 00003DCB 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   279 00003DCD E83B010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   280 00003DD2 F8                  <1> 	clc				; SET CY= 0
   281 00003DD3 C3                  <1> 	retn				; RETURN CY=0
   282                              <1> 
   283                              <1> RTC_60:				; SET RTC ALARM
   284 00003DD4 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   285 00003DD6 E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   286 00003DDB A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   287 00003DDD F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   288 00003DDE 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   289 00003DE0 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   290 00003DE5 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   291 00003DE7 E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   292                              <1> RTC_65:	
   293 00003DEC 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   294 00003DEE B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   295 00003DF0 E818010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   296 00003DF5 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   297 00003DF7 B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   298 00003DF9 E80F010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   299 00003DFE 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   300 00003E00 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   301 00003E02 E806010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   302 00003E07 E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   303 00003E09 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   304 00003E0B E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   305                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   306                              <1> 	;mov	ah, al
   307 00003E0D 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   308 00003E11 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   309 00003E16 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   310 00003E18 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   311 00003E1A 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   312 00003E1C E8EC000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   313 00003E21 F8                  <1> 	clc				; SET CY= 0
   314                              <1> RTC_69:
   315 00003E22 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   316 00003E26 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 00003E27 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   322 00003E2B E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   323 00003E30 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   324 00003E32 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   325 00003E34 E8D4000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   326 00003E39 F8                  <1> 	clc				; SET CY= 0
   327 00003E3A 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 00003E3B 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   333 00003E3F 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 00003E44 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   337 00003E48 E8C0000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   338 00003E4D B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   339 00003E4F E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   340 00003E54 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   341 00003E56 E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   342 00003E5B 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 00003E5C 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   363 00003E5D 50                  <1> 	push	eax			; SAVE REGISTERS
   364 00003E5E 57                  <1> 	push	edi
   365                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   366 00003E5F 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   367 00003E63 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   368 00003E65 90                  <1> 	nop				; I/O DELAY
   369 00003E66 EB00                <1> 	jmp	short $+2
   370 00003E68 E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   371 00003E6A A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   372 00003E6C 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   373                              <1> 
   374 00003E6E 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   375 00003E70 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   376 00003E72 90                  <1> 	nop				; I/O DELAY
   377 00003E73 EB00                <1> 	jmp	short $+2	
   378 00003E75 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   379 00003E77 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   380 00003E79 A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   381 00003E7B 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 00003E7D 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   386 00003E81 8EDF                <1> 	mov	ds, di
   387                              <1> 	
   388 00003E83 812D[30D30000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   388 00003E8B 0000                <1>
   389 00003E8D 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 00003E8F 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   394 00003E91 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   395 00003E95 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   396 00003E97 90                  <1> 	nop				; I/O DELAY
   397 00003E98 EB00                <1> 	jmp	short $+2
   398 00003E9A E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   399 00003E9C 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   400 00003E9E 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   401 00003EA0 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   402 00003EA2 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   403 00003EA4 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   404 00003EA6 C605[34D30000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   405 00003EAD 8B3D[35D30000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   406 00003EB3 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   407 00003EB6 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   408                              <1> RTC_I_5:
   409 00003EB8 A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   410 00003EBA 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   411                              <1> 
   412 00003EBC B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   413 00003EBE E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   414 00003EC0 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   415 00003EC1 52                  <1> 	push	edx
   416 00003EC2 E82B810000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   417 00003EC7 5A                  <1> 	pop	edx
   418 00003EC8 FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   419                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   420 00003EC9 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 00003ECB B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   424 00003ECD E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   425 00003ECF B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   426 00003ED1 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   427 00003ED3 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   428 00003ED5 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   429 00003ED6 58                  <1> 	pop	eax
   430 00003ED7 1F                  <1> 	pop	ds
   431 00003ED8 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 00003ED9 51                  <1> 	push	ecx
   439                              <1> 
   440                              <1> 	; 29/05/2016
   441 00003EDA 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 00003EDF B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   450 00003EE1 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   451 00003EE2 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   452 00003EE7 A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   453 00003EE9 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   454 00003EEB FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   455 00003EEC E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   456 00003EEE 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   457                              <1> 		; xor ax, ax
   458 00003EF0 F9                  <1> 	stc				; SET CARRY FOR ERROR
   459                              <1> UPD_90:
   460 00003EF1 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   461 00003EF2 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   462 00003EF3 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 00003EF4 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   486 00003EF5 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   487 00003EF7 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   488 00003EF8 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   489 00003EFA FA                  <1> 	cli				; DISABLE INTERRUPTS
   490 00003EFB E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   491                              <1> 	; 29/05/2016
   492                              <1> 	;nop				; I/O DELAY
   493 00003EFD E6EB                <1> 	out	0ebh,al	; NEWIODELAY ; AWARD BIOS 1999, ATIME.ASM
   494                              <1> 	;
   495 00003EFF E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   496 00003F01 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 00003F03 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 00003F05 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   502 00003F07 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   503 00003F09 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   504 00003F0B 9D                  <1> 	popf	
   505 00003F0C 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 00003F0D 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   527 00003F0E 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   528 00003F10 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   529 00003F12 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   530 00003F13 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   531 00003F15 FA                  <1> 	cli				; DISABLE INTERRUPTS
   532 00003F16 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   533 00003F18 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   534 00003F1A E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   535 00003F1C 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 00003F1E D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   538 00003F20 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   539 00003F22 90                  <1> 	nop				; I/O DELAY
   540 00003F23 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   541 00003F25 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   542 00003F27 9D                  <1> 	popf
   543 00003F28 C3                  <1> 	retn
   544                              <1> 
   545                              <1> ; /// End Of TIMER FUNCTIONS ///
  1901                                  %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> ;	 					 		
  1902                                  %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
  1903                                  %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 00003F29 31C0                <1> 	xor	eax, eax
    30 00003F2B BF00010900          <1> 	mov	edi, Logical_DOSDisks
    31 00003F30 B980060000          <1> 	mov	ecx, 6656/4 ; 26*256 = 6656 bytes
    32 00003F35 F3AB                <1> 	rep	stosd ; 1664 times 4 bytes
    33                              <1> 
    34 00003F37 B83F3A2F00          <1> 	mov	eax, '?:/'
    35 00003F3C A3[7FD30000]        <1> 	mov	[Current_Dir_Drv], eax
    36                              <1> 
    37                              <1> 	; Logical DRV INIT (only for hard disks)
    38 00003F41 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 00003F46 BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    45 00003F4B B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    46 00003F4D 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    47 00003F50 8806                <1> 	mov 	[esi], al ; A:
    48 00003F52 81C600010000        <1> 	add 	esi, 100h 
    49 00003F58 8806                <1> 	mov 	[esi], al ; B: 
    50                              <1>            
    51                              <1> _current_drive_bootdisk:
    52 00003F5A 8A15[BCCD0000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    53 00003F60 80FAFF              <1> 	cmp 	dl, 0FFh
    54 00003F63 740A                <1> 	je 	short _last_dos_diskno_check
    55                              <1> _boot_drive_check:
    56 00003F65 80FA80              <1> 	cmp 	dl, 80h
    57 00003F68 7218                <1> 	jb 	short _current_drive_a
    58 00003F6A 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    59 00003F6D EB13                <1> 	jmp 	short _current_drive_a 
    60                              <1> 
    61                              <1> _last_dos_diskno_check:
    62 00003F6F 8A15[18C20000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    63 00003F75 80FA02              <1> 	cmp 	dl, 2
    64 00003F78 7706                <1> 	ja 	short _current_drive_c
    65 00003F7A 7406                <1> 	je 	short _current_drive_a
    66 00003F7C 30D2                <1> 	xor 	dl, dl ; A:
    67 00003F7E EB02                <1> 	jmp 	short _current_drive_a
    68                              <1> 
    69                              <1> _current_drive_c:
    70 00003F80 B202                <1> 	mov 	dl, 2 ; C:
    71                              <1> 
    72                              <1> _current_drive_a:
    73 00003F82 8815[BDCD0000]      <1> 	mov	[drv], dl
    74 00003F88 BE[1AC20000]        <1>         mov     esi, msg_CRLF_temp
    75 00003F8D E89E000000          <1> 	call 	print_msg
    76                              <1> 
    77 00003F92 8A15[BDCD0000]      <1> 	mov	dl, [drv]
    78 00003F98 E898090000          <1> 	call 	change_current_drive
    79 00003F9D 730C                <1> 	jnc 	short _start_mainprog
    80                              <1> 
    81                              <1> _drv_not_ready_error: 
    82 00003F9F BE[DEC40000]        <1> 	mov 	esi, msgl_drv_not_ready
    83 00003FA4 E887000000          <1> 	call 	print_msg
    84 00003FA9 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 00003FAB 66B80100            <1> 	mov	ax, 1
    96 00003FAF A2[CFE30000]        <1> 	mov	[u.uno], al
    97 00003FB4 66A3[68E30000]      <1> 	mov	[mpid], ax
    98 00003FBA 66A3[62E00000]      <1> 	mov	[p.pid], ax
    99 00003FC0 A2[F2E00000]        <1> 	mov	[p.stat], al
   100 00003FC5 B004                <1> 	mov	al, time_count
   101 00003FC7 A2[C2E30000]        <1> 	mov	[u.quant], al
   102                              <1> 	;
   103 00003FCC A1[B8D20000]        <1> 	mov	eax, [k_page_dir]
   104 00003FD1 A3[D9E30000]        <1> 	mov	[u.pgdir], eax ; reset
   105                              <1> 	;
   106 00003FD6 E8BBF1FFFF          <1> 	call	allocate_page
   107 00003FDB 0F82A3000000        <1> 	jc	panic
   108 00003FE1 A3[D0E30000]        <1> 	mov	[u.upage], eax ; user structure page	
   109 00003FE6 A3[02E10000]        <1> 	mov	[p.upage], eax
   110 00003FEB E820F2FFFF          <1> 	call	clear_page
   111                              <1> 	;
   112                              <1> 	; 24/08/2015
   113 00003FF0 FE0D[75E30000]      <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 00003FF6 BF00300900          <1> 	mov	edi, Env_Page ; 93000h
   118 00003FFB B980000000          <1> 	mov	ecx, Env_Page_Size / 4 	; 512/4  (4096/4)				 	  		 	  
   119 00004000 31C0                <1> 	xor	eax, eax
   120 00004002 F3AB                <1> 	rep	stosd
   121                              <1> 
   122                              <1> 	; 14/04/2016
   123 00004004 E8BF320000          <1>  	call	mainprog_startup_configuration
   124                              <1> 
   125 00004009 E8630A0000          <1>         call    dos_prompt
   126                              <1>               
   127                              <1> _end_of_mainprog:
   128 0000400E BE[1AC20000]        <1>         mov     esi, msg_CRLF_temp
   129 00004013 E818000000          <1> 	call 	print_msg
   130 00004018 BE[20C20000]        <1> 	mov 	esi, mainprog_Version
   131 0000401D E80E000000          <1> 	call 	print_msg
   132                              <1> 	; 24/01/2016
   133 00004022 28E4                <1> 	sub	ah, ah
   134 00004024 E88DCAFFFF          <1> 	call	int16h ; call getch
   135 00004029 E964CFFFFF          <1> 	jmp	cpu_reset
   136                              <1> 
   137 0000402E 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 00004030 8A3D[E6D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   148                              <1> 	;mov	bl, 07h ; Black background, light gray forecolor
   149                              <1> 
   150 00004036 AC                  <1> 	lodsb
   151                              <1> pmsg1:
   152 00004037 56                  <1> 	push 	esi
   153                              <1> 	;mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   154 00004038 B307                <1> 	mov	bl, 07h ; Black background, light gray forecolor
   155 0000403A E8C3D6FFFF          <1> 	call 	_write_tty
   156 0000403F 5E                  <1> 	pop	esi
   157 00004040 AC                  <1> 	lodsb
   158 00004041 20C0                <1> 	and 	al, al
   159 00004043 75F2                <1> 	jnz 	short pmsg1
   160 00004045 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 00004046 0FB61D[E6D20000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   168 0000404D 8AA3[30CD0000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   169 00004053 80FC04              <1> 	cmp	ah, 4
   170 00004056 7205                <1> 	jb	short cls1
   171 00004058 80FC07              <1> 	cmp	ah, 7
   172 0000405B 7526                <1> 	jne	short vga_clear
   173                              <1> cls1:
   174                              <1> 	;mov	bh, bl
   175                              <1> 	;mov	bl, 7
   176 0000405D 3A25[16CD0000]      <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 00004063 0F854ED3FFFF        <1> 	jne	set_mode_3
   182                              <1> cls2:
   183 00004069 88DF                <1> 	mov	bh, bl ; video page (0 to 7)
   184 0000406B B307                <1> 	mov	bl, 07h ; attribute to be used on blanked line
   185 0000406D 28C0                <1> 	sub 	al, al ; 0 =  entire window
   186 0000406F 6631C9              <1> 	xor 	cx, cx
   187 00004072 66BA4F18            <1> 	mov 	dx, 184Fh
   188 00004076 E8C3D4FFFF          <1> 	call	_scroll_up ; 24/01/2016
   189                              <1> 	;
   190                              <1> 	;mov	bh, [ACTIVE_PAGE] ; video page number (0 to 7)
   191 0000407B 6631D2              <1> 	xor 	dx, dx
   192 0000407E E80AD7FFFF          <1> 	call	_set_cpos ; 24/01/2016 
   193                              <1> 	;retn
   194                              <1> vga_clear:
   195 00004083 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 00004084 BE[55CF0000]        <1> 	mov 	esi, panic_msg
   202 00004089 E8A2FFFFFF          <1> 	call 	print_msg
   203                              <1> key_to_reboot:
   204                              <1>         ; 24/01/2016
   205 0000408E 28E4                <1>         sub     ah, ah
   206 00004090 E821CAFFFF          <1>         call    int16h ; call   getch
   207                              <1>         ; wait for a character from the current tty
   208                              <1> 	;
   209 00004095 B00A                <1> 	mov	al, 0Ah
   210 00004097 8A3D[E6D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
   211 0000409D B307                <1> 	mov	bl, 07h ; Black background, 
   212                              <1> 			; light gray forecolor
   213 0000409F E85ED6FFFF          <1> 	call 	_write_tty
   214 000040A4 E9E9CEFFFF          <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 000040A9 66833D[C4E30000]00  <1> 	cmp 	word [u.intr], 0
   226 000040B1 7645                <1> 	jna 	short cbrk4
   227                              <1> cbrk0:
   228                              <1> 	; 12/11/2015
   229                              <1> 	; 06/12/2013
   230 000040B3 66833D[C6E30000]00  <1> 	cmp 	word [u.quit], 0
   231 000040BB 743B                <1> 	jz	short cbrk4
   232                              <1> 	;
   233                              <1> 	; 20/09/2013	
   234 000040BD 6650                <1> 	push 	ax
   235 000040BF A0[E6D20000]        <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 000040C4 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   244 000040C6 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 000040C8 52                  <1> 	push	edx
   256 000040C9 0FB615[CFE30000]    <1> 	movzx	edx, byte [u.uno]
   257 000040D0 3A82[C1E00000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   258 000040D6 5A                  <1> 	pop	edx
   259 000040D7 7412                <1> 	je	short cbrk2
   260                              <1> cbrk1:
   261 000040D9 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   262                              <1> 	; 06/12/2013
   263 000040DB 3A05[B0E30000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   264 000040E1 7408                <1> 	je	short cbrk2	
   265 000040E3 3A05[B1E30000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   266 000040E9 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 000040EB 6631C0              <1> 	xor	ax, ax ; 0
   274 000040EE 6648                <1> 	dec	ax
   275                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   276 000040F0 66A3[C6E30000]      <1> 	mov	[u.quit], ax
   277                              <1> cbrk3:
   278 000040F6 6658                <1> 	pop	ax
   279                              <1> cbrk4:
   280 000040F8 C3                  <1> 	retn
  1904                                  %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 000040F9 0FB60D[54D30000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
    25 00004100 80F901              <1> 	cmp	cl, 1
    26 00004103 7301                <1> 	jnb	short load_hd_partition_tables
    27                              <1> 	; No hard disks
    28 00004105 C3                  <1> 	retn
    29                              <1> load_hd_partition_tables:
    30 00004106 8B35[58D30000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    31 0000410C BF[7ED70000]        <1> 	mov 	edi, PTable_hd0
    32 00004111 B280                <1> 	mov 	dl, 80h
    33                              <1> load_next_hd_partition_table:
    34 00004113 51                  <1> 	push	ecx
    35 00004114 57                  <1> 	push	edi
    36 00004115 56                  <1> 	push	esi ; FDPT (+ DPTE) address
    37 00004116 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
    38 00004119 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
    39                              <1> 	;shr	al, 6
    40 0000411B A2[7FD90000]        <1> 	mov 	[HD_LBA_yes], al
    41 00004120 E81C040000          <1> 	call	load_masterboot
    42 00004125 7275                <1> 	jc	short pass_pt_this_hard_disk
    43                              <1> 
    44 00004127 BE[3CD70000]        <1> 	mov	esi, PartitionTable
    45 0000412C 89F3                <1> 	mov	ebx, esi
    46                              <1> 	;mov	ecx, 16
    47 0000412E B110                <1> 	mov	cl, 16
    48 00004130 F3A5                <1> 	rep 	movsd
    49 00004132 89DE                <1> 	mov 	esi, ebx 
    50 00004134 C605[BFCD0000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
    51                              <1> loc_validate_hdp_partition:
    52 0000413B 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
    53 0000413F 7641                <1> 	jna	short loc_validate_next_hdp_partition2
    54 00004141 56                  <1> 	push	esi ; Masterboot partition table offset
    55 00004142 52                  <1> 	push	edx ; dl = Physical drive number 
    56 00004143 FE05[80D90000]      <1> 	inc	byte [PP_Counter]
    57 00004149 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 0000414B E879010000          <1> 	call 	validate_hd_fat_partition
    63 00004150 730A                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
    64                              <1> 	;pop	edx
    65                              <1> 	;push	edx
    66 00004152 8B1424              <1> 	mov	edx, [esp] 
    67 00004155 E8C5020000          <1> 	call	validate_hd_fs_partition
    68 0000415A 7224                <1> 	jc	short loc_validate_next_hdp_partition1
    69                              <1> loc_set_valid_hdp_partition_entry:
    70 0000415C 8A0D[18C20000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
    71 00004162 80C141              <1> 	add 	cl, 'A'
    72                              <1> 	; ESI = Logical dos drive description table address
    73 00004165 880E                <1> 	mov	[esi+LD_Name], cl
    74 00004167 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
    75 0000416A 88E0                <1> 	mov	al, ah ; Physical drive number
    76 0000416C 2C80                <1> 	sub	al, 80h
    77 0000416E C0E002              <1> 	shl	al, 2
    78 00004171 0404                <1> 	add	al, 4 ; 0 Based
    79 00004173 2A05[BFCD0000]      <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 00004179 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 0000417C 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
    89                              <1> loc_validate_next_hdp_partition1:
    90 00004180 5A                  <1> 	pop 	edx ; dl = Physical drive number 
    91 00004181 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 00004182 FE0D[BFCD0000]      <1> 	dec	byte [hdc] ; 4 - partition index
    96 00004188 7412                <1> 	jz	short pass_pt_this_hard_disk
    97 0000418A 83C610              <1> 	add	esi, 16 ; 10h
    98 0000418D EBAC                <1> 	jmp	short loc_validate_hdp_partition
    99                              <1> loc_next_hd_partition_table:
   100 0000418F FEC2                <1> 	inc	dl
   101 00004191 83C620              <1> 	add	esi, 32 ; next FDPT address
   102 00004194 83C740              <1> 	add	edi, 64 ; next partition table destination
   103 00004197 E977FFFFFF          <1>         jmp     load_next_hd_partition_table
   104                              <1> pass_pt_this_hard_disk:
   105 0000419C 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
   106 0000419D 5F                  <1> 	pop	edi ; Ptable_hd?
   107 0000419E 59                  <1> 	pop	ecx
   108 0000419F E2EE                <1> 	loop	loc_next_hd_partition_table
   109 000041A1 803D[80D90000]01    <1> 	cmp	byte [PP_Counter], 1
   110 000041A8 7301                <1> 	jnb	short load_extended_dos_partitions
   111                              <1> 	; Empty partition table
   112 000041AA C3                  <1> 	retn 
   113                              <1> load_extended_dos_partitions:
   114 000041AB BE[7ED70000]        <1> 	mov	esi, PTable_hd0
   115 000041B0 BF[7ED80000]        <1> 	mov	edi, PTable_ep0
   116 000041B5 C605[BFCD0000]80    <1> 	mov	byte [hdc], 80h
   117                              <1> next_hd_extd_partition:
   118 000041BC 56                  <1> 	push	esi ; PTable_hd? offset
   119 000041BD 57                  <1> 	push	edi ; PTable_ep?
   120                              <1> 	;mov	ecx, 4
   121 000041BE B104                <1> 	mov	cl, 4
   122 000041C0 8A15[BFCD0000]      <1> 	mov	dl, byte [hdc]
   123                              <1> hd_check_fs_id_05h:
   124 000041C6 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   125 000041C9 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   126 000041CB 7404                <1> 	je	short loc_set_ep_start_sector
   127 000041CD 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   128 000041CF 7546                <1> 	jne	short continue_to_check_ep
   129                              <1> loc_set_ep_start_sector:
   130 000041D1 FE05[81D90000]      <1> 	inc	byte [EP_Counter]
   131 000041D7 88D4                <1> 	mov	ah, dl ; byte [hdc]
   132 000041D9 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
   133 000041DB 50                  <1> 	push	eax 
   134 000041DC 30E4                <1> 	xor	ah, ah  
   135 000041DE 2C80                <1> 	sub	al, 80h
   136 000041E0 50                  <1> 	push	eax
   137 000041E1 C0E002              <1> 	shl	al, 2 ; al = al * 4
   138 000041E4 0FB6D8              <1> 	movzx	ebx, al
   139 000041E7 81C3[82D90000]      <1> 	add	ebx, EP_StartSector
   140 000041ED 8B4608              <1> 	mov	eax, [esi+ptStartSector]
   141                              <1>         ; EAX = Extended partition's start sector
   142 000041F0 8903                <1>         mov	[ebx], eax
   143 000041F2 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
   144 000041F3 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
   145 000041F4 BB[7ED50000]        <1> 	mov	ebx, MasterBootBuff
   146 000041F9 803D[7FD90000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   147 00004200 7240                <1> 	jb	short loc_hd_load_ep_05h
   148 00004202 80FE05              <1> 	cmp	dh, 05h
   149 00004205 743B                <1> 	je	short loc_hd_load_ep_05h
   150                              <1> loc_hd_load_ep_0Fh:
   151                              <1> 	; 04/01/2016
   152 00004207 51                  <1> 	push	ecx
   153 00004208 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 0000420B B41B                <1> 	mov	ah, 1Bh ; LBA read
   159 0000420D B001                <1> 	mov	al, 1 ; sector count
   160 0000420F E811E6FFFF          <1> 	call	int13h
   161 00004214 59                  <1> 	pop	ecx
   162 00004215 733F                <1> 	jnc	short loc_hd_move_ep_table
   163                              <1> continue_to_check_ep:
   164 00004217 83C610              <1> 	add	esi, 16
   165 0000421A E2AA                <1> 	loop	hd_check_fs_id_05h
   166                              <1> continue_check_ep_next_disk:
   167 0000421C 5F                  <1> 	pop	edi ; PTable_ep?
   168 0000421D 5E                  <1> 	pop	esi ; PTable_hd?
   169 0000421E A0[54D30000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   170 00004223 047F                <1> 	add	al, 7Fh
   171 00004225 3805[BFCD0000]      <1> 	cmp	[hdc], al
   172 0000422B 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
   173 00004231 83C640              <1> 	add	esi, 64
   174 00004234 83C740              <1> 	add	edi, 64
   175 00004237 FE05[BFCD0000]      <1> 	inc	byte [hdc]
   176 0000423D E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
   177                              <1> loc_hd_load_ep_05h:
   178 00004242 51                  <1> 	push	ecx 
   179 00004243 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   180 00004246 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
   181 0000424A 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   182                              <1> 	;mov	ebx, MasterBootBuff
   183 0000424E E8D2E5FFFF          <1> 	call	int13h
   184 00004253 59                  <1> 	pop	ecx  
   185 00004254 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 00004256 8B3C24              <1> 	mov	edi, [esp]        
   190 00004259 BE[3CD70000]        <1>         mov	esi, PartitionTable ; Extended
   191 0000425E 89F3                <1> 	mov	ebx, esi
   192                              <1> 	;mov	ecx, 16
   193 00004260 B110                <1> 	mov	cl, 16
   194 00004262 F3A5                <1>        	rep	movsd
   195 00004264 89DE                <1> 	mov	esi, ebx 
   196                              <1> loc_set_hde_sub_partition_count:
   197 00004266 C605[80D90000]04    <1> 	mov	byte [PP_Counter], 4
   198                              <1> loc_validate_hde_partition:
   199 0000426D 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   200 00004271 763F                <1> 	jna	short loc_validate_next_hde_partition2
   201 00004273 56                  <1> 	push	esi ; Extended partition table offset
   202 00004274 8A15[BFCD0000]      <1> 	mov	dl, byte [hdc]
   203 0000427A 0FB6C2              <1> 	movzx	eax, dl
   204 0000427D 2C80                <1> 	sub	al, 80h
   205 0000427F 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 00004282 88C1                <1> 	mov	cl, al
   211 00004284 80C104              <1> 	add	cl, 4
   212 00004287 2A0D[80D90000]      <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 0000428D 88D5                <1>       	mov	ch, dl   
   217 0000428F 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 00004292 51                  <1> 	push	ecx ; *
   222 00004293 BF[82D90000]        <1> 	mov	edi, EP_StartSector
   223 00004298 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 0000429A E82A000000          <1> 	call	validate_hd_fat_partition
   228 0000429F 59                  <1> 	pop	ecx ; *
   229 000042A0 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 000042A2 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
   236                              <1> 	;
   237 000042A6 8A0D[18C20000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   238 000042AC 80C141              <1> 	add	cl, 'A'
   239 000042AF 880E                <1> 	mov	[esi+LD_Name], cl
   240                              <1> loc_validate_next_hde_partition1:
   241 000042B1 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 000042B2 FE0D[80D90000]      <1> 	dec	byte [PP_Counter]
   246 000042B8 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
   247 000042BE 83C610              <1> 	add 	esi, 16 ; 10h
   248 000042C1 EBAA                <1> 	jmp	short loc_validate_hde_partition
   249                              <1> loc_validating_hd_partitions_ok:
   250 000042C3 A0[18C20000]        <1> 	mov	al, [Last_DOS_DiskNo]
   251                              <1> loc_drv_init_retn:
   252 000042C8 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 000042C9 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   275 000042CC 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
   276                              <1> 	; 12/02/2016
   277                              <1> 	;jb	short loc_not_a_valid_fat_partition2
   278 000042CF 7305                <1>  	jnb	short vhdp_FAT16_32
   279                              <1> 	;
   280 000042D1 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)		
   281 000042D4 7519                <1> 	jne	short loc_not_a_valid_fat_partition1
   282                              <1> vhdp_FAT16_32:
   283 000042D6 B002                <1> 	mov	al, 2
   284 000042D8 7417                <1> 	je	short loc_set_valid_hd_partition_params
   285 000042DA 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   286 000042DD 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
   287 000042DF 7410                <1> 	je	short loc_set_valid_hd_partition_params
   288                              <1> 
   289 000042E1 FEC0                <1> 	inc	al ; 3
   290 000042E3 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   291 000042E6 7409                <1> 	je	short loc_set_valid_hd_partition_params
   292 000042E8 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
   293 000042EA 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   294 000042ED 7402                <1> 	je	short loc_set_valid_hd_partition_params
   295                              <1> loc_not_a_valid_fat_partition1:
   296 000042EF F9                  <1> 	stc
   297                              <1> loc_not_a_valid_fat_partition2:
   298 000042F0 C3                  <1> 	retn
   299                              <1> 
   300                              <1> loc_set_valid_hd_partition_params:
   301 000042F1 FE05[18C20000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   302                              <1> 	;
   303 000042F7 31DB                <1> 	xor	ebx, ebx
   304 000042F9 8A3D[18C20000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   305 000042FF 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   306                              <1> 	;
   307 00004305 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   308 00004309 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 0000430C 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   312                              <1> 	;
   313 00004310 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   314 00004313 09FF                <1> 	or	edi, edi 
   315 00004315 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   316                              <1> loc_add_hd_FAT_ep_start_sector:
   317 00004317 030F                <1> 	add	ecx, [edi]
   318                              <1> pass_hd_FAT_ep_start_sector_adding:
   319 00004319 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   320                              <1> loc_hd_FAT_logical_drv_init:
   321 0000431C 89DD                <1> 	mov	ebp, ebx
   322                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   323 0000431E A0[7FD90000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   324 00004323 884305              <1> 	mov	[ebx+LD_LBAYes], al
   325 00004326 BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   326 0000432B 08C0                <1> 	or	al, al
   327 0000432D 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 0000432F B41B                <1> 	mov	ah, 1Bh ; LBA read
   336 00004331 B001                <1> 	mov	al, 1 ; sector count
   337 00004333 E8EDE4FFFF          <1> 	call	int13h
   338 00004338 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   339                              <1> loc_not_a_valid_fat_partition3:
   340 0000433A C3                  <1> 	retn
   341                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   342 0000433B 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   343 0000433E 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   344 00004342 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   345                              <1> 	;mov	ebx, DOSBootSectorBuff
   346 00004346 E8DAE4FFFF          <1> 	call	int13h
   347 0000434B 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   348                              <1> loc_hd_drv_FAT_boot_validation:
   349                              <1> 	;mov	esi, DOSBootSectorBuff
   350 0000434D 89DE                <1> 	mov	esi, ebx
   351 0000434F 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   352 00004358 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
   353 0000435A 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   354 0000435E 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
   355 00004360 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   356 00004365 770F                <1> 	ja	short loc_hd_FAT16_BPB
   357 00004367 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   358 0000436B 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
   359                              <1> loc_hd_FAT32_BPB:
   360 0000436D B92D000000          <1> 	mov	ecx, 45
   361 00004372 EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
   362                              <1> 	;
   363                              <1> loc_not_a_valid_fat_partition4:
   364 00004374 F9                  <1> 	stc
   365 00004375 C3                  <1> 	retn
   366                              <1> 	;
   367                              <1> loc_hd_FAT16_BPB:
   368 00004376 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   369 0000437A 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   370 0000437C B920000000          <1> 	mov	ecx, 32
   371                              <1> loc_hd_move_FAT_BPB:
   372 00004381 89EF                <1> 	mov 	edi, ebp
   373                              <1> 	;mov	esi, ebx ; Boot sector
   374 00004383 57                  <1> 	push	edi
   375 00004384 83C706              <1> 	add	edi, LD_BPB
   376 00004387 F366A5              <1> 	rep	movsw 
   377 0000438A 5E                  <1> 	pop	esi
   378 0000438B 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   379 0000438F 03466C              <1> 	add	eax, [esi+LD_StartSector]
   380 00004392 894660              <1> 	mov	[esi+LD_FATBegin], eax
   381 00004395 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   382 00004399 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   383                              <1> loc_set_FAT32_RootDirLoc:
   384 0000439B 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   385 0000439E 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   386 000043A2 F7E3                <1> 	mul	ebx
   387 000043A4 034660              <1> 	add	eax, [esi+LD_FATBegin]
   388                              <1> loc_set_FAT32_data_begin:
   389 000043A7 894668              <1> 	mov	[esi+LD_DATABegin], eax
   390 000043AA 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 000043AD 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   395 000043B0 83E802              <1> 	sub	eax, 2
   396 000043B3 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   397                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   398 000043B5 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
   399 000043B8 F7E3                <1> 	mul	ebx
   400 000043BA 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   401 000043BD EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   402                              <1> 	;
   403                              <1> loc_set_FAT16_RootDirLoc:
   404 000043BF 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   405 000043C3 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   406 000043C7 F7E2                <1> 	mul	edx
   407 000043C9 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   408 000043CC 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   409                              <1> loc_set_FAT16_data_begin:
   410 000043CF 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   411 000043D2 B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
   412                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   413 000043D7 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   414 000043DB F7E2                <1>         mul	edx
   415                              <1> 	;mov	ecx, 511
   416 000043DD 66B9FF01            <1> 	mov	cx, 511
   417 000043E1 01C8                <1> 	add	eax, ecx
   418 000043E3 41                  <1> 	inc	ecx ; 512
   419 000043E4 F7F1                <1> 	div	ecx
   420 000043E6 014668              <1> 	add	[esi+LD_DATABegin], eax
   421 000043E9 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   422 000043ED 6685C0              <1> 	test	ax, ax
   423 000043F0 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
   424                              <1> loc_set_16bit_FAT_total_sectors:
   425 000043F2 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   426 000043F5 EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
   427                              <1> loc_set_32bit_FAT_total_sectors:
   428 000043F7 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   429 000043FA 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   430                              <1> loc_set_hd_FAT_cluster_count:
   431 000043FD 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   432 00004400 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   433 00004403 29D0                <1> 	sub	eax, edx
   434 00004405 31D2                <1> 	xor	edx, edx ; 0
   435 00004407 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   436 0000440B F7F1                <1>         div	ecx 
   437 0000440D 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 00004410 E859010000          <1> 	call	get_free_FAT_sectors
   443 00004415 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   444 00004417 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   445 0000441A 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 0000441E 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 0000441F 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   472 00004422 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   473 00004425 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   474                              <1> loc_set_valid_hd_fs_partition_params:
   475 00004427 FE05[18C20000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   476 0000442D 30C0                <1> 	xor	al, al ; mov al, 0
   477                              <1> 	;mov	[drv], dl
   478 0000442F 29DB                <1> 	sub	ebx, ebx ; 0
   479 00004431 8A3D[18C20000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   480 00004437 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   481 0000443D C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   482 00004441 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   483                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   484                              <1> 	;mov	[ebx+LD_FSType], ah
   485 00004444 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 00004448 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   490                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   491 0000444A A0[7FD90000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   492 0000444F 884305              <1> 	mov	[ebx+LD_LBAYes], al
   493 00004452 89DE                <1> 	mov	esi, ebx
   494 00004454 BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
   495 00004459 08C0                <1> 	or	al, al
   496 0000445B 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   497                              <1> loc_hd_fs_drv_init_load_bs_chs:
   498 0000445D 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   499 00004460 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   500 00004464 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   501                              <1> 	;mov	ebx, DOSBootSectorBuff
   502 00004468 E8B8E3FFFF          <1> 	call	int13h
   503 0000446D 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   504                              <1> loc_validate_hd_fs_partition_err_retn:
   505 0000446F C3                  <1> 	retn
   506                              <1> loc_validate_hd_fs_partition_stc_retn:
   507 00004470 F9                  <1> 	stc
   508 00004471 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 00004472 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 00004475 B41B                <1> 	mov	ah, 1Bh ; LBA read
   518 00004477 B001                <1> 	mov	al, 1 ; sector count
   519 00004479 E8A7E3FFFF          <1> 	call	int13h
   520 0000447E 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 00004480 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   524 00004482 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   525 0000448B 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 0000448D 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
   529 00004493 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 00004495 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   533 00004499 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   534                              <1> 	;
   535 0000449B 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   536                              <1> 	;
   537 0000449D 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   538 000044A0 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   539                              <1> 	;
   540                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   541 000044A3 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   542 000044A6 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   543                              <1> 	;
   544 000044A9 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   545 000044AC 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   546                              <1> 	;
   547 000044AF 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   548 000044B3 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   549 000044B7 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   550 000044BA 6698                <1> 	cbw
   551 000044BC 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   552 000044C0 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   553                              <1> 	;cbw
   554 000044C3 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   555                              <1> 	;
   556 000044C7 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   557 000044CA 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   558 000044CD 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   559 000044D0 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   560 000044D3 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   561 000044D6 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   562 000044D9 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   563 000044DC 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   564 000044DF 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   565 000044E2 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   566                              <1> 	;
   567 000044E5 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   568 000044E7 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   569 000044EA 89FE                <1> 	mov	esi, edi
   570                              <1> mread_hd_fs_MAT_sector:
   571                              <1>        ;mov	ebx, DOSBootSectorBuff
   572 000044EC B901000000          <1> 	mov	ecx, 1
   573 000044F1 E837790000          <1> 	call	disk_read
   574 000044F6 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   575                              <1> 	; EDI will not be changed
   576 000044F8 89DE                <1> 	mov	esi, ebx
   577                              <1> use_hdfs_mat_sector_params:
   578 000044FA 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   579 000044FD 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   580 00004500 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   581 00004503 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   582 00004506 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   583 00004509 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   584 0000450C 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   585 0000450F 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   586 00004512 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   587 00004515 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   588 00004518 89FE                <1> 	mov	esi, edi   
   589                              <1> read_hd_fs_RDT_sector:
   590 0000451A BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   591                              <1> 	;mov	ecx, 1
   592 0000451F B101                <1> 	mov	cl, 1
   593 00004521 E807790000          <1> 	call	disk_read
   594 00004526 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   595                              <1> 	; EDI will not be changed
   596 00004528 89DE                <1> 	mov	esi, ebx
   597                              <1> use_hdfs_RDT_sector_params:
   598 0000452A 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   599 0000452D 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   600 00004530 57                  <1> 	push	edi
   601                              <1> 	;mov	ecx, 16
   602 00004531 B110                <1> 	mov	cl, 16
   603 00004533 83C640              <1> 	add	esi, FS_RDT_VolumeName
   604 00004536 83C72C              <1> 	add	edi, LD_FS_VolumeName
   605 00004539 F3A5                <1> 	rep	movsd ; 64 bytes
   606 0000453B 5E                  <1> 	pop	esi
   607                              <1> 		; Volume Name Reset
   608 0000453C 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 00004540 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 00004541 B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
   622 00004543 E8DDE2FFFF          <1> 	call	int13h
   623 00004548 7301                <1> 	jnc	short pass_reset_error
   624                              <1> harddisk_error:
   625 0000454A C3                  <1>   	retn
   626                              <1> pass_reset_error:
   627 0000454B BB[7ED50000]        <1> 	mov	ebx, MasterBootBuff
   628 00004550 66B80102            <1> 	mov	ax, 0201h
   629 00004554 66B90100            <1> 	mov	cx, 1
   630 00004558 30F6                <1> 	xor	dh, dh
   631 0000455A E8C6E2FFFF          <1>  	call	int13h
   632 0000455F 72E9                <1> 	jc	short harddisk_error
   633                              <1> 	;
   634 00004561 66813D[7CD70000]55- <1> 	cmp	word [MBIDCode], 0AA55h
   634 00004569 AA                  <1>
   635 0000456A 7401                <1> 	je	short load_masterboot_ok
   636 0000456C F9                  <1> 	stc
   637                              <1> load_masterboot_ok:
   638 0000456D 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 0000456E 31C0                <1> 	xor	eax, eax
   653                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
   654                              <1> 	
   655 00004570 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
   656 00004574 7650                <1> 	jna	short loc_gfc_get_fat_free_clusters
   657                              <1> 
   658                              <1> 	; 29/02/2016
   659 00004576 48                  <1> 	dec	eax ; 0FFFFFFFFh
   660 00004577 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
   661 0000457A 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
   662 0000457D 40                  <1> 	inc	eax ; 0
   663                              <1> 	;
   664 0000457E 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
   665 00004582 03466C              <1> 	add	eax, [esi+LD_StartSector]
   666                              <1> 
   667 00004585 BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   668 0000458A B901000000          <1> 	mov	ecx, 1
   669 0000458F E899780000          <1>  	call	disk_read
   670 00004594 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
   671                              <1> retn_gfc_get_fsinfo_sec:
   672 00004596 C3                  <1> 	retn
   673                              <1> 
   674                              <1> loc_gfc_check_fsinfo_signs:
   675 00004597 BB[92D90000]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
   676 0000459C 813B52526141        <1>         cmp     dword [ebx], 41615252h
   677 000045A2 7520                <1> 	jne	short retn_gfc_get_fsinfo_stc
   678                              <1> 	;add	ebx, 484
   679                              <1> 	;cmp	dword [ebx], 61417272h
   680 000045A4 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   680 000045AD 61                  <1>
   681 000045AE 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
   682                              <1> 	;add	ebx, 4
   683                              <1> 	;mov	eax, [ebx]
   684 000045B0 8B83E8010000        <1> 	mov	eax, [ebx+488]
   685                              <1> 	; 29/02/2016
   686 000045B6 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
   687 000045B9 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
   688 000045BF 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
   689                              <1> 	;
   690 000045C2 EB12                <1> 	jmp	short retn_from_get_free_fat32_clusters
   691                              <1> 
   692                              <1> retn_gfc_get_fsinfo_stc:
   693 000045C4 F9                  <1> 	stc
   694 000045C5 C3                  <1> 	retn
   695                              <1> 
   696                              <1> loc_gfc_get_fat_free_clusters:
   697                              <1> 	;mov	eax, 2
   698 000045C6 B002                <1> 	mov	al, 2
   699                              <1> 	;mov	[FAT_CurrentCluster], eax
   700                              <1> loc_gfc_loop_get_next_cluster:
   701 000045C8 E805500000          <1> 	call	get_next_cluster
   702 000045CD 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
   703 000045CF 21C0                <1> 	and	eax, eax
   704 000045D1 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
   705                              <1>  
   706                              <1> retn_from_get_free_fat_clusters:
   707 000045D3 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
   708                              <1> retn_from_get_free_fat32_clusters:
   709 000045D6 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   710 000045DA F7E3                <1>       	mul	ebx
   711                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
   712                              <1> retn_get_free_sectors_calc:
   713 000045DC C3                  <1> 	retn
   714                              <1> 
   715                              <1> loc_gfc_free_fat_clusters_cont:
   716 000045DD 09C0                <1> 	or	eax, eax
   717 000045DF 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
   718 000045E1 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 000045E4 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
   723 000045E6 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
   724 000045E9 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
   725 000045EB 40                  <1> 	inc	eax
   726                              <1> 	;mov	[FAT_CurrentCluster], eax
   727 000045EC 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 000045EE BE[C0CD0000]        <1> 	mov	esi, fd0_type ; 10/01/2016
   742 000045F3 BF00010900          <1> 	mov	edi, Logical_DOSDisks
   743 000045F8 08D2                <1> 	or	dl, dl
   744 000045FA 7407                <1> 	jz	short loc_drv_init_fd0_fd1
   745 000045FC 81C700010000        <1> 	add	edi, 100h
   746 00004602 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
   747                              <1> loc_drv_init_fd0_fd1:
   748 00004603 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
   749 00004607 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
   750                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
   751 0000460A 7221                <1> 	jb	short read_fd_boot_sector_retn
   752 0000460C 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
   753                              <1> read_fd_boot_sector:
   754 0000460F 30F6                <1> 	xor	dh, dh
   755 00004611 B904000000          <1> 	mov	ecx, 4 ; Retry Count
   756                              <1> read_fd_boot_sector_again:
   757 00004616 51                  <1> 	push 	ecx
   758                              <1> 	;mov	cx, 1
   759 00004617 B101                <1> 	mov	cl, 1
   760 00004619 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   761 0000461D BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff
   762 00004622 E8FEE1FFFF          <1> 	call	int13h
   763 00004627 59                  <1> 	pop	ecx
   764 00004628 7304                <1> 	jnc	short use_fd_boot_sector_params
   765 0000462A E2EA                <1> 	loop	read_fd_boot_sector_again
   766                              <1> 
   767                              <1> read_fd_boot_sector_stc_retn:
   768 0000462C F9                  <1> 	stc
   769                              <1> read_fd_boot_sector_retn:
   770 0000462D C3                  <1> 	retn
   771                              <1> 
   772                              <1> use_fd_boot_sector_params:
   773                              <1> 	;mov	esi, DOSBootSectorBuff
   774 0000462E 89DE                <1> 	mov	esi, ebx
   775 00004630 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   776 00004639 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
   777 0000463B 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
   778 00004641 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
   779                              <1> 	;
   780 00004647 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
   781 0000464A 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   782                              <1> 	;
   783                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   784 0000464D 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   785 00004650 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
   786                              <1> 	;
   787 00004653 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
   788 00004656 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
   789 00004659 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   790 0000465D 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   791 00004661 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   792 00004664 6698                <1> 	cbw
   793 00004666 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   794 0000466A 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   795                              <1> 	;cbw
   796 0000466D 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   797                              <1> 	;
   798 00004671 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   799 00004674 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   800 00004677 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
   801 0000467A 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
   802 0000467D 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   803 00004680 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   804 00004683 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   805 00004686 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   806 00004689 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
   807 0000468C 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   808                              <1> 	;		
   809 0000468F 89FE                <1> 	mov	esi, edi
   810 00004691 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 00004694 B101                <1> 	mov	cl, 1
   816 00004696 E898770000          <1> 	call	chs_read
   817 0000469B 89DE                <1> 	mov	esi, ebx
   818 0000469D 7301                <1> 	jnc	short use_fdfs_mat_sector_params
   819                              <1> 	;jmp	short read_fd_boot_sector_retn
   820 0000469F C3                  <1> 	retn
   821                              <1> use_fdfs_mat_sector_params:
   822 000046A0 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   823 000046A3 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   824 000046A6 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   825 000046A9 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   826 000046AC 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
   827 000046AF 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
   828 000046B2 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   829 000046B5 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   830                              <1> 	;
   831 000046B8 89FE                <1> 	mov	esi, edi
   832 000046BA 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 000046BD B101                <1> 	mov	cl, 1
   837 000046BF E86F770000          <1> 	call	chs_read
   838 000046C4 89DE                <1> 	mov	esi, ebx
   839 000046C6 7220                <1> 	jc	short read_fd_RDT_sector_retn
   840                              <1> use_fdfs_RDT_sector_params:
   841 000046C8 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   842 000046CB 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   843 000046CE 57                  <1> 	push	edi
   844                              <1> 	;mov	ecx, 16
   845 000046CF B110                <1> 	mov	cl, 16	
   846 000046D1 83C640              <1> 	add	esi, FS_RDT_VolumeName
   847 000046D4 83C72C              <1> 	add	edi, LD_FS_VolumeName
   848 000046D7 F3A5                <1> 	rep	movsd ; 64 bytes
   849 000046D9 5E                  <1> 	pop	esi
   850 000046DA C6460300            <1> 	mov	byte [esi+LD_FATType], 0
   851 000046DE C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
   852 000046E2 E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
   853                              <1> 
   854                              <1> read_fd_RDT_sector_stc_retn:
   855 000046E7 F9                  <1> 	stc
   856                              <1> read_fd_RDT_sector_retn:
   857 000046E8 C3                  <1> 	retn
   858                              <1> 
   859                              <1> use_fd_fatfs_boot_sector_params:
   860 000046E9 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   861 000046ED 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
   862 000046EF 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
   863 000046F3 72F3                <1> 	jb	short read_fd_RDT_sector_retn
   864 000046F5 57                  <1> 	push	edi
   865 000046F6 83C706              <1> 	add	edi, LD_BPB
   866                              <1> 	;mov	ecx, 16
   867 000046F9 B110                <1> 	mov	cl, 16
   868 000046FB F3A5                <1> 	rep	movsd ; 64 bytes 
   869 000046FD 5E                  <1> 	pop	esi
   870 000046FE 31C0                <1> 	xor	eax, eax
   871 00004700 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
   872 00004703 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
   873 00004707 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
   874 0000470A F7E1                <1>   	mul	ecx
   875                              <1> 	; edx = 0 !
   876 0000470C 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
   877 00004710 66895660            <1> 	mov	[esi+LD_FATBegin], dx
   878                              <1> 	;add	eax, edx
   879 00004714 6601D0              <1> 	add	ax, dx
   880 00004717 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   881 0000471A 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   882 0000471D 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
   883                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
   884 00004721 66C1E205            <1> 	shl	dx, 5
   885                              <1> 	;add	edx, 511
   886 00004725 6681C2FF01          <1> 	add	dx, 511
   887                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
   888 0000472A 66C1EA09            <1> 	shr	dx, 9
   889 0000472E 015668              <1> 	add 	[esi+LD_DATABegin], edx
   890                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   891 00004731 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   892 00004735 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   893 00004738 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
   894                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   895 0000473B 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
   896 0000473E 80F901              <1> 	cmp	cl, 1
   897 00004741 7605                <1> 	jna	short save_fd_fatfs_cluster_count
   898                              <1> 	;sub	edx, edx
   899 00004743 6629D2              <1> 	sub	dx, dx ; 0
   900 00004746 F7F1                <1> 	div	ecx
   901                              <1> save_fd_fatfs_cluster_count:
   902 00004748 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 0000474B 29C0                <1> 	sub	eax, eax ; 0  
   909 0000474D A2[96DB0000]        <1> 	mov	[FAT_BuffValidData], al ; 0
   910 00004752 A2[97DB0000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
   911 00004757 A3[9ADB0000]        <1> 	mov	[FAT_BuffSector], eax ; 0
   912                              <1> 
   913                              <1> read_fd_FAT_sectors:
   914 0000475C BB001C0900          <1>   	mov	ebx, FAT_Buffer
   915 00004761 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
   916                              <1> 	;mov	ecx, 3
   917 00004765 B103                <1> 	mov	cl, 3 ; 3 sectors
   918 00004767 E8C7760000          <1> 	call	chs_read
   919 0000476C 7240                <1> 	jc	short read_fd_FAT_sectors_retn
   920                              <1> use_fd_FAT_sectors:
   921 0000476E 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
   922 00004771 0441                <1> 	add	al, 'A' 
   923 00004773 A2[97DB0000]        <1> 	mov	[FAT_BuffDrvName], al 
   924 00004778 C605[96DB0000]01    <1>  	mov	byte [FAT_BuffValidData], 1
   925 0000477F E82B000000          <1> 	call	fd_init_calculate_free_clusters
   926 00004784 7228                <1> 	jc	short read_fd_FAT_sectors_retn
   927                              <1>   
   928                              <1> loc_use_fd_boot_sector_params_FAT:
   929 00004786 C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
   930 0000478A C6460401            <1> 	mov	byte [esi+LD_FSType], 1
   931 0000478E 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
   932                              <1> loc_cont_use_fd_boot_sector_params:
   933 00004791 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
   934 00004794 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
   935 00004797 88FB                <1> 	mov	bl, bh
   936 00004799 80C341              <1> 	add	bl, 'A'
   937 0000479C 881E                <1> 	mov	byte [esi+LD_Name], bl
   938 0000479E C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
   939 000047A2 C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
   940 000047A6 C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
   941 000047AA C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
   942                              <1> 
   943                              <1> read_fd_FAT_sectors_retn:
   944 000047AE 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 000047AF 29C0                <1> 	sub	eax, eax
   955 000047B1 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
   956 000047B4 B002                <1> 	mov	al, 2 ; eax = 2
   957                              <1> 
   958                              <1> fd_init_loop_get_next_cluster:
   959 000047B6 E830000000          <1> 	call	fd_init_get_next_cluster
   960 000047BB 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 000047BD 6621C0              <1> 	and	ax, ax
   968 000047C0 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
   969                              <1> 	;inc	dword [esi+LD_FreeSectors]
   970 000047C2 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 000047C6 66A1[92DB0000]      <1> 	mov	ax, [FAT_CurrentCluster]
   975                              <1> 	;cmp	eax, [esi+LD_Clusters]
   976 000047CC 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
   977 000047D0 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
   978                              <1> 	;inc	eax
   979 000047D2 6640                <1> 	inc	ax
   980 000047D4 EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
   981                              <1> 
   982                              <1> retn_from_fd_init_calculate_free_clusters:
   983 000047D6 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
   984 000047D9 3C01                <1>   	cmp	al, 1
   985 000047DB 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
   986                              <1> 	;movzx	eax, al
   987 000047DD 6698                <1> 	cbw
   988                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
   989 000047DF 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
   990                              <1>   	;mul	ecx
   991 000047E3 66F7E1              <1> 	mul	cx
   992                              <1> 	;mov	[esi+LD_FreeSectors], eax
   993 000047E6 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
   994                              <1> fd_init_calculate_free_clusters_retn:
   995 000047EA 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 000047EB A3[92DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
  1010                              <1> fd_init_get_next_cluster_readnext:
  1011 000047F0 29D2                <1> 	sub	edx, edx ; 0
  1012 000047F2 BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1013 000047F7 F7F3                <1>   	div	ebx
  1014                              <1>   	; EAX = Count of 3 FAT sectors
  1015                              <1>   	; EDX = Buffer entry index
  1016 000047F9 89C1                <1> 	mov	ecx, eax
  1017                              <1> 	;mov	eax, 3
  1018 000047FB B003                <1> 	mov	al, 3
  1019 000047FD F7E2                <1> 	mul	edx ; Multiply by 3
  1020 000047FF 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1021 00004802 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1022 00004804 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1023 0000480A 89C8                <1> 	mov	eax, ecx
  1024                              <1> 	;mov	edx, 3
  1025 0000480C 66BA0300            <1> 	mov	dx, 3
  1026 00004810 F7E2                <1> 	mul	edx 
  1027                              <1>   	; EAX = FAT Beginning Sector
  1028                              <1> 	; EDX = 0
  1029 00004812 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1030                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1031                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1032 00004814 3A0D[97DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1033 0000481A 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1034 0000481C 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
  1035 00004822 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1036                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1037 00004824 A0[92DB0000]        <1> 	mov	al, [FAT_CurrentCluster]
  1038                              <1> 	;shr	eax, 1
  1039 00004829 D0E8                <1> 	shr	al, 1
  1040 0000482B 668B03              <1> 	mov	ax, [ebx]
  1041 0000482E 7306                <1>   	jnc	short fd_init_gnc_even
  1042 00004830 66C1E804            <1> 	shr	ax, 4
  1043                              <1> fd_init_gnc_clc_retn:
  1044 00004834 F8                  <1> 	clc
  1045 00004835 C3                  <1> 	retn
  1046                              <1> 
  1047                              <1> fd_init_gnc_even:
  1048 00004836 80E40F              <1> 	and	ah, 0Fh
  1049 00004839 C3                  <1> 	retn
  1050                              <1> 
  1051                              <1> fd_init_load_FAT_sectors0:
  1052 0000483A 880D[97DB0000]      <1> 	mov 	[FAT_BuffDrvName], cl
  1053                              <1> fd_init_load_FAT_sectors1:
  1054 00004840 C605[96DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1055 00004847 A3[9ADB0000]        <1> 	mov	[FAT_BuffSector], eax
  1056 0000484C 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1057 0000484F BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1058                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1059 00004854 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1060 00004858 662B0D[9ADB0000]    <1> 	sub	cx, [FAT_BuffSector]
  1061                              <1>         ;cmp	ecx, 3
  1062 0000485F 6683F903            <1> 	cmp	cx, 3
  1063 00004863 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1064                              <1> 	;mov	ecx, 3
  1065 00004865 B903000000          <1> 	mov	ecx, 3
  1066                              <1> fdinit_pass_fix_sector_count_3:  
  1067 0000486A E8C4750000          <1> 	call	chs_read
  1068 0000486F 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1069 00004871 C605[96DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1070                              <1> 		; Drv not ready or read Error !
  1071 00004878 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1072                              <1> 	;xor	edx, edx
  1073 0000487D C3                  <1> 	retn
  1074                              <1> 
  1075                              <1> fd_init_FAT_sectors_no_load_error:
  1076 0000487E C605[96DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1077 00004885 A1[92DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
  1078 0000488A 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 0000488F 89DE                <1> 	mov	esi, ebx
  1096 00004891 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1097 00004897 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1098 0000489D 8A06                <1> 	mov     al, [esi+LD_Name]
  1099 0000489F 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1100 000048A2 80FC01              <1> 	cmp     ah, 1
  1101 000048A5 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1102 000048A7 3C41                <1> 	cmp 	al, 'A'
  1103 000048A9 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1104 000048AB 80FC02              <1> 	cmp 	ah, 2 
  1105 000048AE 7708                <1> 	ja      short get_FAT32_root_cluster
  1106                              <1> 	
  1107 000048B0 E8784E0000          <1> 	call    load_FAT_root_directory
  1108 000048B5 730B                <1> 	jnc     short loc_get_volume_name
  1109                              <1> 
  1110                              <1> loc_gfvn_dir_load_err:
  1111 000048B7 C3                  <1> 	retn
  1112                              <1> 
  1113                              <1> get_FAT32_root_cluster:
  1114 000048B8 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1115 000048BB E8F84E0000          <1> 	call    load_FAT_sub_directory
  1116 000048C0 7224                <1> 	jc	short loc_get_volume_name_retn
  1117                              <1> 
  1118                              <1> loc_get_volume_name:
  1119 000048C2 BE00000800          <1>         mov     esi, Directory_Buffer
  1120 000048C7 6631C9              <1> 	xor	cx, cx ; 0
  1121                              <1> check_root_volume_name:
  1122 000048CA 8A06                <1> 	mov	al, [esi]
  1123 000048CC 08C0                <1> 	or      al, al
  1124 000048CE 7416                <1> 	jz      short loc_get_volume_name_retn
  1125 000048D0 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1126 000048D4 7410                <1> 	je      short loc_get_volume_name_retn
  1127 000048D6 663B0D[ABDB0000]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1128 000048DD 7308                <1> 	jnb     short pass_check_root_volume_name
  1129 000048DF 6641                <1> 	inc     cx
  1130 000048E1 83C620              <1> 	add     esi, 32
  1131 000048E4 EBE4                <1> 	jmp     short check_root_volume_name
  1132                              <1> 
  1133                              <1> loc_get_volume_name_retn:
  1134 000048E6 C3                  <1> 	retn
  1135                              <1>     
  1136                              <1> pass_check_root_volume_name:
  1137 000048E7 803D[A7DB0000]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1138 000048EE 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1139                              <1> 
  1140 000048F0 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1141 000048F5 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1142 000048FA 31C0                <1> 	xor	eax, eax
  1143 000048FC 8A25[A6DB0000]      <1> 	mov	ah, [DirBuff_DRV]
  1144 00004902 80EC41              <1> 	sub	ah, 'A' 
  1145 00004905 01C6                <1> 	add	esi, eax
  1146 00004907 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  1147 0000490C E8C14C0000          <1> 	call	get_next_cluster
  1148 00004911 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1149                              <1>   	
  1150 00004913 83F801              <1> 	cmp     eax, 1
  1151 00004916 F5                  <1> 	cmc
  1152 00004917 C3                  <1> 	retn
  1153                              <1>   
  1154                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1155 00004918 E89B4E0000          <1> 	call	load_FAT_sub_directory
  1156 0000491D 73A3                <1> 	jnc	short loc_get_volume_name
  1157 0000491F C3                  <1> 	retn
  1158                              <1> 
  1159                              <1> loc_get_volume_name_retn_xor:
  1160 00004920 31C0                <1> 	xor 	eax, eax
  1161 00004922 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 00004923 B416                <1> 	mov	ah, 16h
  1173 00004925 E8FBDEFFFF          <1>   	call	int13h
  1174 0000492A 80FC06              <1> 	cmp	ah, 06h
  1175 0000492D 7405                <1> 	je	short loc_gmc_status_retn
  1176 0000492F 08E4                <1> 	or	ah, ah
  1177 00004931 7401                <1> 	jz	short loc_gmc_status_retn
  1178                              <1> loc_gmc_status_stc_retn:    
  1179 00004933 F9                  <1> 	stc
  1180                              <1> loc_gmc_status_retn:
  1181 00004934 C3                  <1> 	retn
  1905                                  %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 00004935 31DB                <1> 	xor	ebx, ebx
    33 00004937 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 00004939 BE00010900          <1> 	mov	esi, Logical_DOSDisks
    42 0000493E 01DE                <1> 	add	esi, ebx
    43                              <1> loc_ccdrv_dos_drive_name_check:
    44 00004940 80FA02              <1> 	cmp	dl, 2
    45 00004943 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    46                              <1> 
    47 00004945 8A06                <1> 	mov	al, [esi+LD_Name]
    48 00004947 2C41                <1> 	sub	al, 'A'
    49 00004949 38D0                <1> 	cmp	al, dl
    50 0000494B 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    51                              <1> 
    52                              <1> loc_ccdrv_drive_not_ready_err:
    53 0000494D B815000000          <1> 	mov	eax, 15h ; Drive not ready
    54                              <1> loc_change_current_drive_stc_retn:
    55 00004952 F9                  <1> 	stc
    56 00004953 C3                  <1> 	retn  
    57                              <1> 
    58                              <1> loc_ccdrv_dos_drive_name_check_ok:
    59 00004954 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    60 00004957 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    61 0000495A 7450                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    62                              <1> 
    63 0000495C 80FA01              <1> 	cmp	dl, 1
    64 0000495F 7778                <1> 	ja	short loc_gmcs_init_drv_hd
    65                              <1> 
    66                              <1> loc_gmcs_init_drv_fd:
    67 00004961 08E4                <1> 	or	ah, ah 
    68                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    69 00004963 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    70                              <1> 
    71 00004965 E8B9FFFFFF          <1> 	call	get_media_change_status
    72 0000496A 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    73                              <1> 
    74 0000496C 20E4                <1> 	and	ah, ah
    75 0000496E 7471                <1> 	jz	short loc_change_current_drv3
    76                              <1> 
    77 00004970 80F406              <1> 	xor	ah, 6
    78 00004973 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    79                              <1> 
    80                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    81 00004975 E8440A0000          <1> 	call	get_volume_serial_number
    82 0000497A 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
    83                              <1> 
    84                              <1> loc_ccdrv_call_fd_init:
    85 0000497C E86DFCFFFF          <1> 	call	floppy_drv_init
    86 00004981 7315                <1> 	jnc	short loc_reset_drv_fd_current_dir
    87                              <1> 
    88                              <1> loc_ccdrv_fdinit_fail_retn:
    89 00004983 C3                  <1> 	retn
    90                              <1> 
    91                              <1> loc_ccdrv_check_vol_serial:
    92 00004984 A3[74D30000]        <1> 	mov	[Current_VolSerial], eax
    93                              <1> 	;mov	dl, bh
    94 00004989 E860FCFFFF          <1> 	call	floppy_drv_init
    95 0000498E 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
    96                              <1> 
    97 00004990 3B05[74D30000]      <1> 	cmp	eax, [Current_VolSerial]
    98 00004996 7445                <1> 	je	short loc_change_current_drv2
    99                              <1> 
   100                              <1> loc_reset_drv_fd_current_dir:
   101 00004998 31C0                <1> 	xor	eax, eax              
   102 0000499A 88467F              <1>         mov	[esi+LD_CDirLevel], al
   103 0000499D 89F7                <1> 	mov	edi, esi
   104 0000499F 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   105 000049A5 B920000000          <1> 	mov	ecx, 32
   106 000049AA F3AB                <1> 	rep	stosd   
   107                              <1>  
   108                              <1> loc_ccdrv_get_FAT_volume_name_0:
   109 000049AC 8A4603              <1> 	mov	al, [esi+LD_FATType]
   110 000049AF 08C0                <1> 	or	al, al
   111 000049B1 742A                <1> 	jz	short loc_change_current_drv2
   112                              <1> 
   113 000049B3 56                  <1> 	push	esi 
   114 000049B4 3C02                <1> 	cmp	al, 2
   115 000049B6 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   116                              <1>              
   117                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   118 000049B8 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   119 000049BB EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   120                              <1> 
   121                              <1> loc_ccdrv_get_FAT32_vol_name:
   122 000049BD 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   123                              <1> loc_ccdrv_get_FAT_volume_name_1:
   124 000049C0 53                  <1> 	push	ebx
   125 000049C1 56                  <1> 	push	esi
   126 000049C2 E8C8FEFFFF          <1> 	call	get_FAT_volume_name
   127 000049C7 5F                  <1> 	pop	edi
   128 000049C8 5B                  <1> 	pop	ebx
   129                              <1> 	; BL = 0
   130 000049C9 720B                <1> 	jc	short loc_change_current_drv1
   131 000049CB 20C0                <1> 	and	al, al
   132 000049CD 7407                <1> 	jz	short loc_change_current_drv1
   133                              <1> 
   134                              <1> loc_ccdrv_move_FAT_volume_name:
   135 000049CF B90B000000          <1> 	mov	ecx, 11
   136 000049D4 F3A4                <1> 	rep	movsb
   137                              <1> 
   138                              <1> loc_change_current_drv1:
   139 000049D6 5E                  <1> 	pop	esi
   140 000049D7 EB04                <1> 	jmp	short loc_change_current_drv2
   141                              <1> 
   142                              <1> loc_gmcs_init_drv_hd:
   143 000049D9 08E4                <1> 	or	ah, ah
   144 000049DB 7404                <1> 	jz	short loc_change_current_drv3
   145                              <1> 	; BL = 0, BH = Logical DOS drive number
   146                              <1> loc_change_current_drv2:
   147 000049DD C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   148                              <1> loc_change_current_drv3:
   149 000049E1 883D[7ED30000]      <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 000049E7 8A4603              <1> 	mov	al, [esi+LD_FATType]
   168 000049EA A2[7DD30000]        <1> 	mov	[Current_FATType], al
   169                              <1> 
   170 000049EF 8A26                <1> 	mov	ah, [esi+LD_Name] 
   171 000049F1 8825[7FD30000]      <1> 	mov	[Current_Dir_Drv], ah
   172                              <1> 
   173 000049F7 20C0                <1> 	and	al, al
   174 000049F9 741D                <1> 	jz	short loc_restore_FS_current_directory
   175                              <1> 
   176                              <1> loc_restore_FAT_current_directory:
   177 000049FB 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   178 000049FE 8825[7CD30000]      <1> 	mov	[Current_Dir_Level], ah
   179 00004A04 08E4                <1> 	or	ah, ah
   180 00004A06 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   181                              <1> 
   182 00004A08 0FB6D4              <1> 	movzx	edx, ah
   183 00004A0B C0E204              <1> 	shl	dl, 4 ; * 16
   184 00004A0E 01F2                <1>         add	edx, esi
   185 00004A10 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   186 00004A16 EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   187                              <1> 
   188                              <1> loc_restore_FS_current_directory:
   189 00004A18 E8D64D0000          <1> 	call	load_current_FS_directory 
   190 00004A1D C3                  <1> 	retn 
   191                              <1> 
   192                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   193 00004A1E 3C03                <1> 	cmp	al, 3
   194 00004A20 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   195                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   196 00004A22 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   197 00004A25 EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   198                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   199 00004A27 30C0                <1> 	xor	al, al  ; xor eax, eax
   200 00004A29 31D2                <1> 	xor	edx, edx
   201                              <1> loc_ccdrv_check_rootdir_sign:
   202 00004A2B 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   203 00004A32 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   204                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   205 00004A34 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   206 00004A3A C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   206 00004A43 54                  <1>
   207                              <1> 
   208                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   209 00004A44 A3[78D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   210                              <1> 
   211 00004A49 BF[DFDB0000]        <1> 	mov	edi, PATH_Array
   212 00004A4E 89F2                <1> 	mov	edx, esi
   213 00004A50 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   214 00004A56 B920000000          <1> 	mov	ecx, 32
   215 00004A5B F3A5                <1> 	rep	movsd
   216                              <1> 
   217 00004A5D E8852D0000          <1> 	call	change_prompt_dir_string
   218                              <1> 	
   219 00004A62 89D6                <1> 	mov	esi, edx
   220                              <1> 	
   221 00004A64 29C0                <1>         sub	eax, eax
   222                              <1>        ;sub	edx, edx
   223 00004A66 BF[7FD30000]        <1> 	mov	edi, Current_Dir_Drv
   224                              <1> 
   225 00004A6B A2[19C20000]        <1> 	mov	[Restore_CDIR], al ; 0
   226 00004A70 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 00004A71 C705[2CE00000]-     <1> 	mov	dword [mainprog_return_addr], return_from_command_intepreter
   238 00004A77 [254B0000]          <1>
   239                              <1> 
   240                              <1> loc_TRDOS_prompt:
   241 00004A7B BF[7ED40000]        <1> 	mov	edi, TextBuffer
   242 00004A80 C6075B              <1> 	mov	byte [edi], "["
   243 00004A83 47                  <1> 	inc	edi
   244 00004A84 BE[6CC20000]        <1> 	mov	esi, TRDOSPromptLabel
   245                              <1> get_next_prompt_label_char:
   246 00004A89 803E20              <1> 	cmp	byte [esi], 20h
   247 00004A8C 7203                <1> 	jb	short pass_prompt_label
   248 00004A8E A4                  <1> 	movsb
   249 00004A8F EBF8                <1> 	jmp	short get_next_prompt_label_char
   250                              <1> pass_prompt_label:
   251 00004A91 C6075D              <1> 	mov	byte [edi], "]"
   252 00004A94 47                  <1> 	inc	edi
   253 00004A95 C60720              <1> 	mov	byte [edi], 20h
   254 00004A98 47                  <1> 	inc	edi
   255 00004A99 BE[7FD30000]        <1> 	mov	esi, Current_Dir_Drv
   256 00004A9E 66A5                <1> 	movsw
   257 00004AA0 A4                  <1> 	movsb 
   258                              <1> loc_prompt_current_directory:
   259 00004AA1 803E20              <1> 	cmp	byte [esi], 20h
   260 00004AA4 7203                <1> 	jb	short pass_prompt_current_directory
   261 00004AA6 A4                  <1> 	movsb
   262 00004AA7 EBF8                <1> 	jmp	short loc_prompt_current_directory  
   263                              <1> pass_prompt_current_directory:
   264 00004AA9 C6073E              <1> 	mov	byte [edi], '>'
   265 00004AAC 47                  <1> 	inc	edi
   266 00004AAD C60700              <1> 	mov	byte [edi], 0  
   267 00004AB0 BE[7ED40000]        <1> 	mov	esi, TextBuffer
   268 00004AB5 E876F5FFFF          <1> 	call	print_msg
   269                              <1>         
   270                              <1> 	;sub	bh, bh ; video page = 0
   271                              <1> 	;call	get_cpos ; get cursor position
   272 00004ABA 668B15[D6D20000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   273 00004AC1 8815[DED30000]      <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 00004AC7 E899000000          <1> 	call	rw_char
   293                              <1> loc_move_command:
   294 00004ACC BE[2ED40000]        <1> 	mov	esi, CommandBuffer
   295 00004AD1 89F7                <1> 	mov	edi, esi
   296 00004AD3 31C9                <1> 	xor	ecx, ecx
   297                              <1> first_command_char:
   298 00004AD5 AC                  <1> 	lodsb
   299 00004AD6 3C20                <1> 	cmp	al, 20h
   300 00004AD8 772E                <1> 	ja	short pass_space_control
   301 00004ADA 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   302 00004ADC 81FE[7DD40000]      <1> 	cmp	esi, CommandBuffer + 79
   303 00004AE2 72F1                <1> 	jb	short first_command_char
   304 00004AE4 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   305                              <1> 
   306                              <1> next_command_char:
   307 00004AE6 AC                  <1> 	lodsb
   308 00004AE7 3C20                <1> 	cmp	al, 20h
   309 00004AE9 771D                <1> 	ja	short pass_space_control
   310 00004AEB 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   311                              <1> 
   312                              <1> loc_1st_cmd_arg: ; 30/01/2016
   313 00004AED AC                  <1> 	lodsb
   314 00004AEE 3C20                <1> 	cmp	al, 20h
   315 00004AF0 74FB                <1> 	je	short loc_1st_cmd_arg
   316 00004AF2 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   317                              <1> 	
   318 00004AF4 C60700              <1>         mov     byte [edi], 0
   319 00004AF7 47                  <1> 	inc	edi
   320                              <1> 
   321                              <1> loc_move_cmd_arguments:
   322 00004AF8 AA                  <1> 	stosb
   323 00004AF9 81FE[7DD40000]      <1> 	cmp	esi, CommandBuffer + 79
   324 00004AFF 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   325 00004B01 AC                  <1>         lodsb
   326 00004B02 3C20                <1> 	cmp	al, 20h
   327 00004B04 73F2                <1> 	jnb	short loc_move_cmd_arguments
   328 00004B06 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   329                              <1> 
   330                              <1> pass_space_control:
   331 00004B08 3C61                <1> 	cmp	al, 61h
   332 00004B0A 7206                <1> 	jb	short pass_capitalize
   333 00004B0C 3C7A                <1> 	cmp	al, 7Ah
   334 00004B0E 7702                <1> 	ja	short pass_capitalize
   335 00004B10 24DF                <1> 	and	al, 0DFh
   336                              <1> pass_capitalize:
   337 00004B12 AA                  <1> 	stosb   
   338 00004B13 FEC1                <1> 	inc     cl
   339 00004B15 81FE[7DD40000]      <1>         cmp     esi, CommandBuffer + 79
   340 00004B1B 72C9                <1> 	jb      short next_command_char 
   341                              <1> 
   342                              <1> loc_move_cmd_arguments_ok:
   343 00004B1D C60700              <1>         mov     byte [edi], 0
   344                              <1>        
   345                              <1> call_command_intepreter:
   346 00004B20 E8D4080000          <1> 	call    command_interpreter
   347                              <1> 
   348                              <1> return_from_command_intepreter:
   349 00004B25 B950000000          <1>         mov	ecx, 80
   350                              <1> 	;mov	cx, 80
   351 00004B2A BF[2ED40000]        <1> 	mov	edi, CommandBuffer
   352 00004B2F 30C0                <1> 	xor	al, al
   353 00004B31 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 00004B33 803D[16CD0000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   359 00004B3A 741D                <1> 	je	short pass_set_txt_mode
   360                              <1> 
   361 00004B3C E8B8C8FFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   362                              <1> 
   363                              <1> loc_check_active_page:
   364 00004B41 30C0                <1> 	xor	al, al
   365 00004B43 3805[E6D20000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   366 00004B49 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   367                              <1> 	; AL = 0 = video page 0
   368 00004B4F E871C9FFFF          <1> 	call	set_active_page
   369 00004B54 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   370                              <1> 
   371                              <1> pass_set_txt_mode: 
   372 00004B59 BE[52CF0000]        <1> 	mov	esi, nextline
   373 00004B5E E8CDF4FFFF          <1> 	call	print_msg
   374 00004B63 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 00004B65 30E4                <1> 	xor     ah, ah
   390 00004B67 E84ABFFFFF          <1> 	call	int16h
   391 00004B6C 20C0                <1> 	and	al, al
   392 00004B6E 7434                <1> 	jz	short loc_arrow    
   393 00004B70 3CE0                <1> 	cmp	al, 0E0h          
   394 00004B72 7430                <1> 	je	short loc_arrow
   395 00004B74 3C08                <1> 	cmp	al, 08h             
   396 00004B76 7544                <1> 	jne	short char_return
   397                              <1> loc_back:
   398 00004B78 3A15[DED30000]      <1> 	cmp	dl, [CursorColumn]
   399 00004B7E 76E5                <1> 	jna     short readnextchar
   400                              <1> prev_column:
   401 00004B80 FECA                <1> 	dec	dl
   402                              <1> set_cursor_pos:
   403 00004B82 6652                <1> 	push	dx
   404                              <1> 	;xor	bh, bh ; 0 = video page 0
   405                              <1> 	; DH = Row, DL = Column
   406 00004B84 E804CCFFFF          <1> 	call	_set_cpos ; 17/01/2016
   407 00004B89 665A                <1>         pop	dx
   408                              <1> 	;movzx	ebx, dl
   409 00004B8B 88D3                <1> 	mov	bl, dl
   410 00004B8D 2A1D[DED30000]      <1> 	sub	bl, [CursorColumn] 
   411 00004B93 B020                <1> 	mov	al, 20h
   412 00004B95 8883[2ED40000]      <1> 	mov	[CommandBuffer+ebx], al
   413                              <1> 	;sub	bh, bh ; video page 0
   414                              <1> 	;mov	cx, 1
   415 00004B9B B307                <1> 	mov	bl, 7 ; color attribute
   416 00004B9D E823CBFFFF          <1> 	call	_write_c_current ; 17/01/2016
   417                              <1> 	;mov	dx, [CURSOR_POSN]
   418 00004BA2 EBC1                <1> 	jmp	short readnextchar
   419                              <1> loc_arrow:    
   420 00004BA4 80FC4B              <1> 	cmp	ah, 4Bh
   421 00004BA7 74CF                <1> 	je	short loc_back
   422 00004BA9 80FC53              <1> 	cmp	ah, 53h
   423 00004BAC 74CA                <1> 	je      short loc_back
   424 00004BAE 80FC4D              <1> 	cmp	ah, 4Dh
   425 00004BB1 75B2                <1> 	jne	short readnextchar
   426 00004BB3 80FA4F              <1> 	cmp	dl, 79
   427 00004BB6 73AD                <1> 	jnb	short readnextchar
   428 00004BB8 FEC2                <1> 	inc	dl
   429 00004BBA EBC6                <1> 	jmp	short set_cursor_pos
   430                              <1> char_return:
   431 00004BBC 0FB6DA              <1> 	movzx	ebx, dl
   432 00004BBF 2A1D[DED30000]      <1> 	sub	bl, [CursorColumn] 
   433 00004BC5 3C20                <1> 	cmp	al, 20h
   434 00004BC7 7220                <1> 	jb	short loc_escape
   435 00004BC9 8883[2ED40000]      <1> 	mov	[CommandBuffer+ebx], al
   436 00004BCF 80FA4F              <1> 	cmp	dl, 79
   437 00004BD2 7391                <1> 	jnb	short readnextchar
   438 00004BD4 66BB0700            <1> 	mov	bx, 7 ; color attribute
   439 00004BD8 E825CBFFFF          <1> 	call	_write_tty
   440 00004BDD 668B15[D6D20000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   441 00004BE4 E97CFFFFFF          <1>         jmp     readnextchar
   442                              <1> loc_escape:
   443 00004BE9 3C1B                <1> 	cmp	al, 1Bh
   444 00004BEB 7418                <1> 	je	short rw_char_retn
   445                              <1> 	;
   446 00004BED 3C0D                <1> 	cmp	al, 0Dh ; CR
   447 00004BEF 0F8570FFFFFF        <1>         jne     readnextchar
   448                              <1> 	; 13/05/2016
   449 00004BF5 66BB0700            <1> 	mov	bx, 7 ; attribute/color (bl)
   450                              <1> 		      ; video page 0 (bh=0)	
   451 00004BF9 E804CBFFFF          <1> 	call	_write_tty
   452                              <1> 	;mov	bx, 7  ; attribute/color
   453                              <1> 		      ; video page 0 (bh=0)
   454 00004BFE B00A                <1> 	mov	al, 0Ah ; LF
   455 00004C00 E8FDCAFFFF          <1> 	call	_write_tty
   456                              <1> rw_char_retn:
   457 00004C05 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 00004C06 E84FF1FFFF          <1> 	call	RTC_40	; GET RTC DATE
   466                              <1> 
   467 00004C0B 88D0                <1> 	mov	al, dl
   468 00004C0D E89BBEFFFF          <1>   	call	bcd_to_ascii
   469 00004C12 66A3[61C30000]      <1> 	mov	[Day], ax
   470                              <1> 
   471 00004C18 88F0                <1> 	mov	al, dh
   472 00004C1A E88EBEFFFF          <1>   	call	bcd_to_ascii
   473 00004C1F 66A3[64C30000]      <1> 	mov	[Month], ax
   474                              <1> 
   475 00004C25 88E8                <1> 	mov	al, ch
   476 00004C27 E881BEFFFF          <1>   	call	bcd_to_ascii
   477 00004C2C 66A3[67C30000]      <1> 	mov	[Century], ax
   478                              <1> 
   479 00004C32 88C8                <1> 	mov	al, cl
   480 00004C34 E874BEFFFF          <1>   	call	bcd_to_ascii
   481 00004C39 66A3[69C30000]      <1> 	mov	word [Year], ax
   482                              <1> 
   483 00004C3F BE[51C30000]        <1> 	mov	esi, Msg_Show_Date
   484 00004C44 E8E7F3FFFF          <1> 	call	print_msg
   485                              <1> 
   486 00004C49 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 00004C4A BE[35C30000]        <1> 	mov	esi, Msg_Enter_Date
   494 00004C4F E8DCF3FFFF          <1> 	call	print_msg
   495                              <1> 
   496                              <1> loc_enter_day_1:
   497 00004C54 30E4                <1> 	xor     ah, ah
   498 00004C56 E85BBEFFFF          <1> 	call	int16h
   499                              <1> 	; AL = ASCII Code of the Character
   500 00004C5B 3C0D                <1> 	cmp	al, 13
   501 00004C5D 0F84B7010000        <1> 	je	loc_set_date_retn
   502 00004C63 3C1B                <1> 	cmp	al, 27
   503 00004C65 0F84AF010000        <1> 	je	loc_set_date_retn
   504 00004C6B A2[61C30000]        <1> 	mov	[Day], al
   505 00004C70 3C30                <1> 	cmp	al, '0'
   506 00004C72 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   507 00004C78 3C33                <1> 	cmp	al, '3'
   508 00004C7A 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 00004C80 B307                <1> 	mov	bl, 7
   513 00004C82 E87BCAFFFF          <1> 	call	_write_tty
   514                              <1> loc_enter_day_2:
   515 00004C87 30E4                <1> 	xor     ah, ah
   516 00004C89 E828BEFFFF          <1> 	call	int16h
   517                              <1> 	; AL = ASCII Code of the Character
   518 00004C8E 3C1B                <1> 	cmp	al, 27
   519 00004C90 0F8484010000        <1>         je      loc_set_date_retn
   520 00004C96 A2[62C30000]        <1> 	mov	[Day+1], al
   521 00004C9B 3C30                <1> 	cmp	al, '0'
   522 00004C9D 0F828C010000        <1>         jb      loc_set_date_stc_1
   523 00004CA3 3C39                <1> 	cmp	al, '9'
   524 00004CA5 0F8784010000        <1>         ja      loc_set_date_stc_1
   525 00004CAB 803D[61C30000]33    <1> 	cmp	byte [Day], '3'
   526 00004CB2 7208                <1> 	jb	short pass_set_day_31
   527 00004CB4 3C31                <1> 	cmp	al, '1'
   528 00004CB6 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 00004CBC B307                <1> 	mov	bl, 7
   534 00004CBE E83FCAFFFF          <1> 	call	_write_tty
   535                              <1> loc_enter_separator_1:
   536 00004CC3 28E4                <1> 	sub     ah, ah ; 0
   537 00004CC5 E8ECBDFFFF          <1> 	call	int16h
   538                              <1> 	; AL = ASCII Code of the Character
   539 00004CCA 3C1B                <1> 	cmp	al, 27
   540 00004CCC 0F8448010000        <1>         je      loc_set_date_retn
   541 00004CD2 3C2D                <1> 	cmp	al, '-'
   542 00004CD4 7408                <1> 	je	short pass_set_date_separator_1
   543 00004CD6 3C2F                <1> 	cmp	al, '/'
   544 00004CD8 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 00004CDE B307                <1> 	mov	bl, 7	
   550 00004CE0 E81DCAFFFF          <1> 	call	_write_tty
   551                              <1> loc_enter_month_1:
   552 00004CE5 30E4                <1> 	xor     ah, ah ; 0
   553 00004CE7 E8CABDFFFF          <1> 	call	int16h
   554                              <1> 	; AL = ASCII Code of the Character
   555 00004CEC 3C1B                <1> 	cmp	al, 27
   556 00004CEE 0F8426010000        <1>         je      loc_set_date_retn
   557 00004CF4 A2[64C30000]        <1> 	mov	[Month], al
   558 00004CF9 3C30                <1> 	cmp	al, '0'
   559 00004CFB 0F8264010000        <1>         jb      loc_set_date_stc_3
   560 00004D01 3C31                <1> 	cmp	al, '1'
   561 00004D03 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 00004D09 B307                <1> 	mov	bl, 7
   566 00004D0B E8F2C9FFFF          <1> 	call	_write_tty
   567                              <1> loc_enter_month_2:
   568 00004D10 30E4                <1> 	xor     ah, ah
   569 00004D12 E89FBDFFFF          <1> 	call	int16h
   570                              <1> 	; AL = ASCII Code of the Character
   571 00004D17 3C1B                <1> 	cmp	al, 27
   572 00004D19 0F84FB000000        <1>         je      loc_set_date_retn
   573 00004D1F A2[65C30000]        <1> 	mov	[Month+1], al
   574 00004D24 3C30                <1> 	cmp	al, '0'
   575 00004D26 0F8254010000        <1>         jb      loc_set_date_stc_4
   576 00004D2C 3C39                <1> 	cmp	al, '9'
   577 00004D2E 0F874C010000        <1>         ja      loc_set_date_stc_4
   578 00004D34 803D[64C30000]31    <1> 	cmp	byte [Month], '1'
   579 00004D3B 7208                <1> 	jb	short pass_set_month_12
   580 00004D3D 3C32                <1> 	cmp	al, '2'
   581 00004D3F 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 00004D45 B307                <1> 	mov	bl, 7	
   587 00004D47 E8B6C9FFFF          <1> 	call	_write_tty
   588                              <1> loc_enter_separator_2:
   589 00004D4C 28E4                <1> 	sub     ah, ah
   590 00004D4E E863BDFFFF          <1> 	call	int16h
   591                              <1> 	; AL = ASCII Code of the Character
   592 00004D53 3C1B                <1> 	cmp	al, 27
   593 00004D55 0F84BF000000        <1>         je      loc_set_date_retn
   594 00004D5B 3C2D                <1> 	cmp	al, '-'
   595 00004D5D 7408                <1> 	je	short pass_set_date_separator_2
   596 00004D5F 3C2F                <1> 	cmp	al, '/'
   597 00004D61 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 00004D67 B307                <1> 	mov	bl, 7
   603 00004D69 E894C9FFFF          <1> 	call	_write_tty
   604                              <1> loc_enter_year_1:
   605 00004D6E 30E4                <1> 	xor    ah, ah
   606 00004D70 E841BDFFFF          <1> 	call	int16h
   607                              <1> 	; AL = ASCII Code of the Character
   608 00004D75 3C1B                <1> 	cmp	al, 27
   609 00004D77 0F849D000000        <1>         je      loc_set_date_retn
   610 00004D7D A2[69C30000]        <1> 	mov	[Year], al
   611 00004D82 3C30                <1> 	cmp	al, '0'
   612 00004D84 0F822C010000        <1>         jb      loc_set_date_stc_6
   613 00004D8A 3C39                <1> 	cmp	al, '9'
   614 00004D8C 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 00004D92 B307                <1> 	mov	bl, 7	
   619 00004D94 E869C9FFFF          <1> 	call	_write_tty
   620                              <1> loc_enter_year_2:
   621 00004D99 30E4                <1> 	xor	ah, ah
   622 00004D9B E816BDFFFF          <1> 	call	int16h
   623                              <1> 	; AL = ASCII Code of the Character
   624 00004DA0 3C1B                <1> 	cmp	al, 27
   625 00004DA2 7476                <1> 	je	short loc_set_date_retn
   626 00004DA4 A2[6AC30000]        <1> 	mov	byte [Year+1], al
   627 00004DA9 3C30                <1> 	cmp	al, '0'
   628 00004DAB 0F8220010000        <1>         jb      loc_set_date_stc_7
   629 00004DB1 3C39                <1> 	cmp	al, '9'
   630 00004DB3 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 00004DB9 B307                <1> 	mov	bl, 7	
   635 00004DBB E842C9FFFF          <1> 	call	_write_tty
   636                              <1> loc_set_date_get_lchar_again:
   637 00004DC0 28E4                <1> 	sub	ah, ah ; 0
   638 00004DC2 E8EFBCFFFF          <1> 	call	int16h
   639                              <1> 	; AL = ASCII Code of the Character
   640 00004DC7 3C0D                <1> 	cmp	al, 13 ; ENTER key
   641 00004DC9 7412                <1> 	je	short loc_set_date_progress
   642 00004DCB 3C1B                <1> 	cmp	al, 27 ; ESC key
   643 00004DCD 744B                <1> 	je	short loc_set_date_retn
   644                              <1> 	;
   645 00004DCF E82A010000          <1> 	call	check_for_backspace
   646 00004DD4 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   647                              <1> 
   648                              <1> loc_set_date_bs_8:
   649 00004DD6 E811010000          <1> 	call	write_backspace
   650 00004DDB 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 00004DDD E878EFFFFF          <1> 	call	RTC_40	; GET RTC DATE
   657                              <1> 	; CH = century (in BCD)
   658                              <1> 
   659 00004DE2 66A1[69C30000]      <1> 	mov	ax, [Year]
   660 00004DE8 662D3030            <1> 	sub	ax, '00'
   661 00004DEC C0E004              <1> 	shl	al, 4 ; * 16
   662 00004DEF 88C1                <1> 	mov	cl, al
   663 00004DF1 00E1                <1> 	add	cl, ah
   664 00004DF3 66A1[64C30000]      <1> 	mov	ax, [Month]
   665 00004DF9 662D3030            <1> 	sub	ax, '00'
   666 00004DFD C0E004              <1> 	shl	al, 4 ; * 16
   667 00004E00 88C6                <1> 	mov	dh, al
   668 00004E02 00E6                <1> 	add	dh, ah
   669 00004E04 66A1[61C30000]      <1> 	mov	ax, [Day]
   670 00004E0A 662D3030            <1> 	sub	ax, '00'
   671 00004E0E C0E004              <1> 	shl	al, 4 ; * 16
   672 00004E11 88C2                <1> 	mov	dl, al
   673 00004E13 00E2                <1> 	add	dl, ah
   674                              <1> 
   675                              <1> 	;mov	ah, 05h
   676                              <1> 	;call	int1Ah
   677 00004E15 E86DEFFFFF          <1> 	call	RTC_50	; SET RTC DATE
   678                              <1> 
   679                              <1> loc_set_date_retn:
   680 00004E1A BE[52CF0000]        <1> 	mov	esi, nextline
   681 00004E1F E80CF2FFFF          <1> 	call	print_msg
   682 00004E24 C3                  <1> 	retn
   683                              <1> 
   684                              <1> loc_set_date_stc_0:
   685                              <1> 	;xor	bh, bh ; video page 0
   686 00004E25 E8ADC9FFFF          <1> 	call	beeper ; BEEP !
   687 00004E2A E925FEFFFF          <1>         jmp     loc_enter_day_1
   688                              <1> loc_set_date_stc_1:
   689 00004E2F E8CA000000          <1> 	call	check_for_backspace
   690 00004E34 740A                <1> 	je	short loc_set_date_bs_1
   691                              <1> 	;xor	bh, bh ; video page 0
   692 00004E36 E89CC9FFFF          <1> 	call	beeper ; BEEP !
   693 00004E3B E947FEFFFF          <1>         jmp     loc_enter_day_2
   694                              <1> loc_set_date_bs_1:
   695 00004E40 E8A7000000          <1> 	call	write_backspace
   696 00004E45 E90AFEFFFF          <1>         jmp     loc_enter_day_1
   697                              <1> loc_set_date_stc_2:
   698 00004E4A E8AF000000          <1> 	call	check_for_backspace
   699 00004E4F 740A                <1> 	je	short loc_set_date_bs_2
   700                              <1> 	;xor	bh, bh ; video page 0
   701 00004E51 E881C9FFFF          <1> 	call	beeper ; BEEP !
   702 00004E56 E968FEFFFF          <1>         jmp     loc_enter_separator_1
   703                              <1> loc_set_date_bs_2:
   704 00004E5B E88C000000          <1> 	call	write_backspace
   705 00004E60 E922FEFFFF          <1>         jmp     loc_enter_day_2
   706                              <1> loc_set_date_stc_3:
   707 00004E65 E894000000          <1> 	call	check_for_backspace	
   708 00004E6A 740A                <1> 	je short loc_set_date_bs_3
   709                              <1> 	;xor	bh, bh ; video page 0
   710 00004E6C E866C9FFFF          <1> 	call	beeper ; BEEP !
   711 00004E71 E96FFEFFFF          <1>         jmp     loc_enter_month_1
   712                              <1> loc_set_date_bs_3:
   713 00004E76 E871000000          <1> 	call	write_backspace
   714 00004E7B E943FEFFFF          <1>         jmp     loc_enter_separator_1
   715                              <1> loc_set_date_stc_4:
   716 00004E80 E879000000          <1> 	call	check_for_backspace	
   717 00004E85 740A                <1> 	je	short loc_set_date_bs_4
   718                              <1> 	;xor	bh, bh ; video page 0
   719 00004E87 E84BC9FFFF          <1> 	call	beeper ; BEEP !
   720 00004E8C E97FFEFFFF          <1>         jmp     loc_enter_month_2
   721                              <1> loc_set_date_bs_4:
   722 00004E91 E856000000          <1> 	call	write_backspace
   723 00004E96 E94AFEFFFF          <1>         jmp     loc_enter_month_1
   724                              <1> loc_set_date_stc_5:
   725 00004E9B E85E000000          <1> 	call	check_for_backspace
   726 00004EA0 740A                <1> 	je	short loc_set_date_bs_5
   727                              <1> 	;xor	bh, bh ; video page 0
   728 00004EA2 E830C9FFFF          <1> 	call	beeper ; BEEP !
   729 00004EA7 E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   730                              <1> loc_set_date_bs_5:
   731 00004EAC E83B000000          <1> 	call	write_backspace
   732 00004EB1 E95AFEFFFF          <1>         jmp     loc_enter_month_2
   733                              <1> loc_set_date_stc_6:
   734 00004EB6 E843000000          <1> 	call	check_for_backspace
   735 00004EBB 740A                <1>         je      short  loc_set_date_bs_6
   736                              <1> 	;xor	bh, bh ; video page 0
   737 00004EBD E815C9FFFF          <1> 	call	beeper ; BEEP !
   738 00004EC2 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   739                              <1> loc_set_date_bs_6:
   740 00004EC7 E820000000          <1> 	call	write_backspace
   741 00004ECC E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   742                              <1> loc_set_date_stc_7:
   743 00004ED1 E828000000          <1> 	call	check_for_backspace
   744 00004ED6 740A                <1> 	je	short loc_set_date_bs_7
   745                              <1> 	;xor	bh, bh ; video page 0
   746 00004ED8 E8FAC8FFFF          <1> 	call	beeper ; BEEP !
   747 00004EDD E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   748                              <1> loc_set_date_bs_7:
   749 00004EE2 E805000000          <1> 	call	write_backspace
   750 00004EE7 E982FEFFFF          <1>         jmp     loc_enter_year_1
   751                              <1> 
   752                              <1> write_backspace:
   753                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   754 00004EEC B008                <1> 	mov	al, 08h ; BACKSPACE
   755                              <1> 	; 13/05/2016
   756 00004EEE 66BB0700            <1> 	mov	bx, 7 ; bl = attribute/color
   757                              <1> 		      ; bh = video page = 0	
   758 00004EF2 E80BC8FFFF          <1> 	call	_write_tty
   759 00004EF7 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 00004EF9 E9C7C7FFFF          <1> 	jmp	_write_c_current
   764                              <1> 
   765                              <1> check_for_backspace:
   766                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   767 00004EFE 663D080E            <1> 	cmp	ax, 0E08h
   768 00004F02 7410                <1> 	je	short cfbs_retn
   769 00004F04 663DE04B            <1> 	cmp	ax, 4BE0h
   770 00004F08 740A                <1> 	je	short cfbs_retn
   771 00004F0A 663D004B            <1> 	cmp	ax, 4B00h
   772 00004F0E 7404                <1> 	je	short cfbs_retn
   773 00004F10 663DE053            <1> 	cmp	ax, 53E0h
   774                              <1> cfbs_retn:
   775 00004F14 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 00004F15 E8CFEDFFFF          <1> 	call	RTC_20	; GET RTC TIME
   784                              <1> 	
   785 00004F1A 88E8                <1> 	mov	al, ch
   786 00004F1C E88CBBFFFF          <1> 	call	bcd_to_ascii
   787 00004F21 66A3[8FC30000]      <1> 	mov	[Hour], ax
   788                              <1> 
   789 00004F27 88C8                <1> 	mov	al, cl
   790 00004F29 E87FBBFFFF          <1> 	call	bcd_to_ascii
   791 00004F2E 66A3[92C30000]      <1> 	mov	[Minute], ax
   792                              <1> 
   793 00004F34 88F0                <1> 	mov	al, dh
   794 00004F36 E872BBFFFF          <1> 	call	bcd_to_ascii
   795 00004F3B 66A3[95C30000]      <1> 	mov	[Second], ax
   796                              <1> 
   797 00004F41 BE[7FC30000]        <1> 	mov	esi, Msg_Show_Time
   798 00004F46 E8E5F0FFFF          <1> 	call	print_msg
   799 00004F4B 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 00004F4C BE[6EC30000]        <1> 	mov 	esi, Msg_Enter_Time
   807 00004F51 E8DAF0FFFF          <1> 	call	print_msg
   808                              <1> 
   809                              <1> loc_enter_hour_1:
   810 00004F56 30E4                <1> 	xor     ah, ah
   811 00004F58 E859BBFFFF          <1> 	call	int16h
   812                              <1> 	; AL = ASCII Code of the Character
   813 00004F5D 3C0D                <1> 	cmp	al, 13 ; ENTER key
   814 00004F5F 0F84AE010000        <1>         je      loc_set_time_retn
   815 00004F65 3C1B                <1> 	cmp	al, 27 ; ESC key
   816 00004F67 0F84A6010000        <1>         je      loc_set_time_retn
   817 00004F6D A2[8FC30000]        <1> 	mov	[Hour], al
   818 00004F72 3C30                <1> 	cmp	al, '0'
   819 00004F74 0F82A4010000        <1>         jb      loc_set_time_stc_0
   820 00004F7A 3C32                <1> 	cmp	al, '2'
   821 00004F7C 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 00004F82 B307                <1> 	mov	bl, 7	
   826 00004F84 E879C7FFFF          <1> 	call	_write_tty
   827                              <1> loc_enter_hour_2:
   828 00004F89 30E4                <1> 	xor     ah, ah
   829 00004F8B E826BBFFFF          <1> 	call	int16h
   830                              <1> 	; AL = ASCII Code of the Character
   831 00004F90 3C1B                <1> 	cmp	al, 27
   832 00004F92 0F847B010000        <1>         je      loc_set_time_retn
   833 00004F98 A2[90C30000]        <1> 	mov	[Hour+1], al
   834 00004F9D 3C30                <1> 	cmp	al, '0'
   835 00004F9F 0F8283010000        <1>         jb      loc_set_time_stc_1
   836 00004FA5 3C39                <1> 	cmp	al, '9'
   837 00004FA7 0F877B010000        <1> 	ja	loc_set_time_stc_1
   838 00004FAD 803D[8FC30000]32    <1>         cmp     byte [Hour], '2'
   839 00004FB4 7208                <1> 	jb	short pass_set_time_24
   840 00004FB6 3C34                <1> 	cmp	al, '4'
   841 00004FB8 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 00004FBE B307                <1> 	mov	bl, 7	
   847 00004FC0 E83DC7FFFF          <1> 	call	_write_tty
   848                              <1> loc_enter_time_separator_1:
   849 00004FC5 28E4                <1> 	sub    ah, ah ; 0
   850 00004FC7 E8EABAFFFF          <1> 	call	int16h
   851                              <1> 	; AL = ASCII Code of the Character
   852 00004FCC 3C1B                <1> 	cmp	al, 27
   853 00004FCE 0F843F010000        <1>         je      loc_set_time_retn
   854 00004FD4 3C3A                <1> 	cmp	al, ':'
   855 00004FD6 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 00004FDC B307                <1> 	mov	bl, 7	
   860 00004FDE E81FC7FFFF          <1> 	call	_write_tty
   861                              <1> loc_enter_minute_1:
   862 00004FE3 30E4                <1> 	xor     ah, ah
   863 00004FE5 E8CCBAFFFF          <1> 	call	int16h
   864                              <1> 	; AL = ASCII Code of the Character
   865 00004FEA 3C1B                <1> 	cmp	al, 27
   866 00004FEC 0F8421010000        <1>         je      loc_set_time_retn
   867 00004FF2 A2[92C30000]        <1> 	mov	[Minute], al
   868 00004FF7 3C30                <1> 	cmp	al, '0'
   869 00004FF9 0F825F010000        <1>         jb      loc_set_time_stc_3
   870 00004FFF 3C35                <1> 	cmp	al, '5'
   871 00005001 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 00005007 B307                <1> 	mov	bl, 7	
   876 00005009 E8F4C6FFFF          <1> 	call	_write_tty
   877                              <1> loc_enter_minute_2:
   878 0000500E 30E4                <1> 	xor     ah, ah
   879 00005010 E8A1BAFFFF          <1> 	call	int16h
   880                              <1> 	; AL = ASCII Code of the Character
   881 00005015 3C1B                <1> 	cmp	al, 27
   882 00005017 0F84F6000000        <1>         je      loc_set_time_retn
   883 0000501D A2[93C30000]        <1> 	mov	[Minute+1], al
   884 00005022 3C30                <1> 	cmp	al, '0'
   885 00005024 0F824F010000        <1>         jb      loc_set_time_stc_4
   886 0000502A 3C39                <1> 	cmp	al, '9'
   887 0000502C 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 00005032 B307                <1> 	mov	bl, 7	
   892 00005034 E8C9C6FFFF          <1> 	call	_write_tty
   893                              <1> loc_enter_time_separator_2:
   894 00005039 66C705[95C30000]30- <1> 	mov	word [Second], 3030h
   894 00005041 30                  <1>
   895 00005042 28E4                <1> 	sub     ah, ah
   896 00005044 E86DBAFFFF          <1> 	call	int16h
   897                              <1> 	; AL = ASCII Code of the Character
   898 00005049 3C0D                <1> 	cmp	al, 13
   899 0000504B 0F8485000000        <1>         je      loc_set_time_progress
   900 00005051 3C1B                <1> 	cmp	al, 27
   901 00005053 0F84BA000000        <1>         je      loc_set_time_retn
   902 00005059 3C3A                <1> 	cmp	al, ':'
   903 0000505B 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 00005061 B307                <1> 	mov	bl, 7	
   908 00005063 E89AC6FFFF          <1> 	call	_write_tty
   909                              <1> loc_enter_second_1:
   910 00005068 30E4                <1> 	xor     ah, ah
   911 0000506A E847BAFFFF          <1> 	call	int16h
   912                              <1> 	; AL = ASCII Code of the Character
   913 0000506F 3C0D                <1> 	cmp	al, 13
   914 00005071 7463                <1> 	je	short loc_set_time_progress
   915 00005073 3C1B                <1> 	cmp	al, 27
   916 00005075 0F8498000000        <1>         je      loc_set_time_retn
   917 0000507B A2[95C30000]        <1> 	mov	[Second], al
   918 00005080 3C30                <1> 	cmp	al, '0'
   919 00005082 0F8227010000        <1>         jb      loc_set_time_stc_6
   920 00005088 3C35                <1> 	cmp	al, '5'
   921 0000508A 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 00005090 B307                <1> 	mov	bl, 7	
   926 00005092 E86BC6FFFF          <1> 	call	_write_tty
   927                              <1> loc_enter_second_2:
   928 00005097 30E4                <1> 	xor     ah, ah
   929 00005099 E818BAFFFF          <1> 	call	int16h
   930                              <1> 	; AL = ASCII Code of the Character
   931 0000509E 3C1B                <1> 	cmp	al, 27
   932 000050A0 7471                <1> 	je	short loc_set_time_retn
   933 000050A2 3C30                <1> 	cmp	al, '0'
   934 000050A4 0F8229010000        <1>         jb      loc_set_time_stc_7
   935 000050AA 3C39                <1> 	cmp	al, '9'
   936 000050AC 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 000050B2 B307                <1> 	mov	bl, 7	
   941 000050B4 E849C6FFFF          <1> 	call	_write_tty
   942                              <1> loc_set_time_get_lchar_again:
   943 000050B9 28E4                <1> 	sub	ah, ah ; 0
   944 000050BB E8F6B9FFFF          <1> 	call	int16h
   945                              <1> 	; AL = ASCII Code of the Character
   946 000050C0 3C0D                <1> 	cmp	al, 13
   947 000050C2 7412                <1> 	je	short loc_set_time_progress
   948 000050C4 3C1B                <1> 	cmp	al, 27
   949 000050C6 744B                <1> 	je	short loc_set_time_retn
   950                              <1> 	;
   951 000050C8 E831FEFFFF          <1> 	call	check_for_backspace
   952 000050CD 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   953                              <1> 
   954                              <1> loc_set_time_bs_8:
   955 000050CF E818FEFFFF          <1> 	call	write_backspace
   956 000050D4 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 000050D6 E80EECFFFF          <1> 	call	RTC_20	; GET RTC TIME
   963                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   964                              <1> 
   965 000050DB 66A1[8FC30000]      <1> 	mov	ax, [Hour]
   966 000050E1 662D3030            <1> 	sub	ax, '00'
   967 000050E5 C0E004              <1> 	shl	al, 4 ; * 16
   968 000050E8 88C5                <1> 	mov	ch, al
   969 000050EA 00E5                <1> 	add	ch, ah
   970 000050EC 66A1[92C30000]      <1> 	mov	ax, [Minute]
   971 000050F2 662D3030            <1> 	sub	ax, '00'
   972 000050F6 C0E004              <1> 	shl	al, 4 ; * 16
   973 000050F9 88C1                <1> 	mov	cl, al
   974 000050FB 00E1                <1> 	add	cl, ah
   975 000050FD 66A1[95C30000]      <1> 	mov	ax, [Second]
   976 00005103 662D3030            <1> 	sub	ax, '00'
   977 00005107 C0E004              <1> 	shl	al, 4 ; * 16
   978 0000510A 88C6                <1> 	mov	dh, al
   979 0000510C 00E6                <1> 	add	dh, ah
   980                              <1> 	
   981                              <1> 	;mov	ah, 03h
   982                              <1> 	;call	int1Ah
   983 0000510E E805ECFFFF          <1> 	call	RTC_30	; SET RTC TIME
   984                              <1> 
   985                              <1> loc_set_time_retn:
   986 00005113 BE[52CF0000]        <1> 	mov 	esi, nextline
   987 00005118 E813EFFFFF          <1> 	call	print_msg
   988 0000511D C3                  <1> 	retn
   989                              <1> 
   990                              <1> loc_set_time_stc_0:
   991                              <1> 	;xor	bh, bh ; video page 0
   992 0000511E E8B4C6FFFF          <1> 	call	beeper ; BEEP !
   993 00005123 E92EFEFFFF          <1>         jmp     loc_enter_hour_1
   994                              <1> loc_set_time_stc_1:
   995 00005128 E8D1FDFFFF          <1> 	call	check_for_backspace
   996 0000512D 740A                <1> 	je	short loc_set_time_bs_1
   997                              <1> 	;xor	bh, bh ; video page 0
   998 0000512F E8A3C6FFFF          <1> 	call	beeper ; BEEP !
   999 00005134 E950FEFFFF          <1>         jmp     loc_enter_hour_2
  1000                              <1> loc_set_time_bs_1:
  1001 00005139 E8AEFDFFFF          <1> 	call	write_backspace
  1002 0000513E E913FEFFFF          <1>         jmp     loc_enter_hour_1
  1003                              <1> loc_set_time_stc_2:
  1004 00005143 E8B6FDFFFF          <1> 	call	check_for_backspace
  1005 00005148 740A                <1> 	je	short loc_set_time_bs_2
  1006                              <1> 	;xor	bh, bh ; video page 0
  1007 0000514A E888C6FFFF          <1> 	call	beeper ; BEEP !
  1008 0000514F E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
  1009                              <1> loc_set_time_bs_2:
  1010 00005154 E893FDFFFF          <1> 	call	write_backspace
  1011 00005159 E92BFEFFFF          <1>         jmp     loc_enter_hour_2
  1012                              <1> loc_set_time_stc_3:
  1013 0000515E E89BFDFFFF          <1> 	call	check_for_backspace
  1014 00005163 740A                <1> 	je	short loc_set_time_bs_3
  1015                              <1> 	;xor	bh, bh ; video page 0
  1016 00005165 E86DC6FFFF          <1> 	call	beeper ; BEEP !6
  1017 0000516A E974FEFFFF          <1>         jmp     loc_enter_minute_1
  1018                              <1> loc_set_time_bs_3:
  1019 0000516F E878FDFFFF          <1> 	call	write_backspace
  1020 00005174 E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
  1021                              <1> loc_set_time_stc_4:
  1022 00005179 E880FDFFFF          <1> 	call	check_for_backspace
  1023 0000517E 740A                <1> 	je	short loc_set_time_bs_4
  1024                              <1> 	;xor	bh, bh ; video page 0
  1025 00005180 E852C6FFFF          <1> 	call	beeper ; BEEP !
  1026 00005185 E984FEFFFF          <1>         jmp     loc_enter_minute_2
  1027                              <1> loc_set_time_bs_4:
  1028 0000518A E85DFDFFFF          <1> 	call	write_backspace
  1029 0000518F E94FFEFFFF          <1>         jmp     loc_enter_minute_1
  1030                              <1> loc_set_time_stc_5:
  1031 00005194 E865FDFFFF          <1> 	call	check_for_backspace
  1032 00005199 740A                <1> 	je	short loc_set_time_bs_5
  1033                              <1> 	;xor	bh, bh ; video page 0
  1034 0000519B E837C6FFFF          <1> 	call	beeper ; BEEP !
  1035 000051A0 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1036                              <1> loc_set_time_bs_5:
  1037 000051A5 E842FDFFFF          <1> 	call	write_backspace
  1038 000051AA E95FFEFFFF          <1>         jmp     loc_enter_minute_2
  1039                              <1> loc_set_time_stc_6:
  1040 000051AF E84AFDFFFF          <1> 	call	check_for_backspace
  1041 000051B4 7413                <1> 	je	short loc_set_time_bs_6
  1042                              <1> 	;xor	bh, bh ; video page 0
  1043 000051B6 E81CC6FFFF          <1> 	call	beeper ; BEEP !
  1044 000051BB 66C705[95C30000]30- <1> 	mov	word [Second], 3030h
  1044 000051C3 30                  <1>
  1045 000051C4 E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1046                              <1> loc_set_time_bs_6:
  1047 000051C9 E81EFDFFFF          <1> 	call	write_backspace
  1048 000051CE E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1049                              <1> loc_set_time_stc_7:
  1050 000051D3 E826FDFFFF          <1> 	call	check_for_backspace
  1051 000051D8 740A                <1> 	je	short loc_set_time_bs_7
  1052                              <1> 	;xor	bh, bh ; video page 0
  1053 000051DA E8F8C5FFFF          <1> 	call	beeper ; BEEP !
  1054 000051DF E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1055                              <1> loc_set_time_bs_7:
  1056 000051E4 E803FDFFFF          <1> 	call	write_backspace
  1057 000051E9 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 000051EE 88C4                <1> 	mov	ah, al
  1076 000051F0 28C0                <1> 	sub	al, al
  1077 000051F2 0FB7F0              <1> 	movzx	esi, ax	
  1078 000051F5 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1079 000051FB 8A06                <1> 	mov	al, [esi]
  1080 000051FD 3C41                <1> 	cmp	al, 'A'  
  1081 000051FF 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1082 00005201 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1083 00005204 C3                  <1> 	retn
  1084                              <1> 
  1085                              <1> loc_pvi_set_vol_name:
  1086 00005205 A2[C9C30000]        <1> 	mov	[Vol_Drv_Name], al
  1087 0000520A 56                  <1> 	push	esi
  1088 0000520B E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1089 00005210 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1090 00005212 5E                  <1> 	pop	esi
  1091 00005213 C3                  <1> 	retn
  1092                              <1> 
  1093                              <1> loc_pvi_mvn_ok:
  1094 00005214 8B3424              <1> 	mov	esi, [esp]
  1095 00005217 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1096 0000521B 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1097 0000521D 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1098 00005220 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1099 00005224 EB07                <1> 	jmp	short loc_vol_size_mul32
  1100                              <1> loc_pvi_fat_vol_size:
  1101 00005226 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1102 00005229 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1103                              <1> loc_vol_size_mul32:
  1104 0000522D F7E3                <1> 	mul	ebx
  1105 0000522F 09D2                <1> 	or	edx, edx
  1106 00005231 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1107                              <1> loc_vol_size_in_bytes:
  1108 00005233 B9[A7C30000]        <1> 	mov	ecx, VolSize_Bytes
  1109 00005238 EB0D                <1> 	jmp	short loc_write_vol_size_str
  1110                              <1> loc_vol_size_in_kbytes:
  1111 0000523A 66BB0004            <1> 	mov	bx, 1024
  1112 0000523E F7F3                <1> 	div	ebx
  1113 00005240 B9[9AC30000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1114 00005245 31D2                <1> 	xor	edx, edx ; 0
  1115                              <1> loc_write_vol_size_str:
  1116 00005247 890D[B7DB0000]      <1> 	mov	[VolSize_Unit1], ecx
  1117                              <1> 	; 
  1118 0000524D BF[CDDB0000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1119                              <1>         ;mov	byte [edi], 0
  1120 00005252 B90A000000          <1> 	mov	ecx, 10
  1121                              <1> loc_write_vol_size_chr:
  1122 00005257 F7F1                <1> 	div	ecx
  1123 00005259 80C230              <1> 	add	dl, '0'
  1124 0000525C 4F                  <1> 	dec	edi	
  1125 0000525D 8817                <1> 	mov	[edi], dl
  1126 0000525F 85C0                <1> 	test	eax, eax
  1127 00005261 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1128 00005263 28D2                <1> 	sub	dl, dl ; 0
  1129 00005265 EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1130                              <1> 
  1131                              <1> loc_write_vol_size_str_ok:
  1132 00005267 893D[BFDB0000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1133                              <1> 	;
  1134 0000526D BF[B2C30000]        <1> 	mov	edi, Vol_FS_Name
  1135 00005272 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1136 00005275 20C9                <1> 	and	cl, cl ; 0 ?
  1137 00005277 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1138 00005279 66C7075452          <1> 	mov	word [edi], 'TR'
  1139 0000527E C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1140                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1141 00005285 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1142 00005289 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1143 0000528C EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1144                              <1> 
  1145                              <1> loc_write_vol_FAT_str_1:
  1146 0000528E 66B83332            <1> 	mov	ax, '32' ; FAT32
  1147 00005292 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1148 00005295 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1149 00005297 66B83132            <1> 	mov	ax, '12' ; FAT12
  1150 0000529B 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1151 0000529D B436                <1> 	mov	ah, '6'  ; FAT16
  1152                              <1> loc_write_vol_FAT_str_2:
  1153 0000529F C70746415420        <1> 	mov	dword [edi], 'FAT '
  1154 000052A5 66894704            <1> 	mov	word [edi+4], ax
  1155                              <1> 	;
  1156                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1157 000052A9 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1158 000052AD 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1159                              <1> 
  1160                              <1> loc_vol_freespace_recalc0:
  1161                              <1> 	; 01/03/2016
  1162 000052B0 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1163 000052B3 720F                <1> 	jb	short loc_vol_freespace_mul32
  1164                              <1> 	;inc	eax ; 0
  1165 000052B5 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1166 000052B7 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1167 000052B9 53                  <1> 	push	ebx
  1168 000052BA 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1169 000052BE E88B490000          <1> 	call	calculate_fat_freespace
  1170 000052C3 5B                  <1> 	pop	ebx
  1171                              <1> 
  1172                              <1> loc_vol_freespace_mul32:
  1173 000052C4 F7E3                <1> 	mul	ebx
  1174 000052C6 09D2                <1> 	or	edx, edx
  1175 000052C8 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1176                              <1> loc_vol_fspace_in_bytes:
  1177 000052CA B9[A7C30000]        <1> 	mov	ecx, VolSize_Bytes
  1178 000052CF EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1179                              <1> loc_vol_fspace_in_kbytes:
  1180 000052D1 66BB0004            <1> 	mov	bx, 1024
  1181 000052D5 F7F3                <1> 	div	ebx
  1182 000052D7 B9[9AC30000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1183 000052DC 31D2                <1> 	xor	edx, edx ; 0
  1184                              <1> loc_write_vol_fspace_str:
  1185 000052DE 890D[BBDB0000]      <1> 	mov	[VolSize_Unit2], ecx
  1186                              <1> 	;	
  1187 000052E4 BF[DDDB0000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1188                              <1>         ;mov	byte [edi], 0
  1189 000052E9 B90A000000          <1> 	mov	ecx, 10
  1190                              <1> loc_write_vol_fspace_chr:
  1191 000052EE F7F1                <1> 	div	ecx
  1192 000052F0 80C230              <1> 	add	dl, '0'
  1193 000052F3 4F                  <1> 	dec	edi	
  1194 000052F4 8817                <1> 	mov	[edi], dl
  1195 000052F6 85C0                <1> 	test	eax, eax
  1196 000052F8 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1197 000052FA 28D2                <1> 	sub	dl, dl ; 0
  1198 000052FC EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1199                              <1> 
  1200                              <1> loc_write_vol_fspace_str_ok:
  1201 000052FE 893D[CFDB0000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1202                              <1> 	;
  1203 00005304 BE[B0C30000]        <1> 	mov	esi, Volume_in_drive
  1204 00005309 E822EDFFFF          <1> 	call	print_msg
  1205 0000530E BE[F0C30000]        <1> 	mov	esi, Vol_Name
  1206 00005313 E818EDFFFF          <1> 	call	print_msg
  1207 00005318 BE[52CF0000]        <1> 	mov	esi, nextline
  1208 0000531D E80EEDFFFF          <1> 	call	print_msg
  1209                              <1> 	;
  1210 00005322 BE[51C40000]        <1> 	mov	esi, Vol_Total_Sector_Header
  1211 00005327 E804EDFFFF          <1> 	call	print_msg
  1212 0000532C 8B35[BFDB0000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1213 00005332 E8F9ECFFFF          <1> 	call	print_msg
  1214 00005337 8B35[B7DB0000]      <1> 	mov	esi, [VolSize_Unit1]
  1215 0000533D E8EEECFFFF          <1> 	call	print_msg
  1216                              <1> 	;
  1217 00005342 BE[62C40000]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1218 00005347 E8E4ECFFFF          <1> 	call	print_msg
  1219 0000534C 8B35[CFDB0000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1220 00005352 E8D9ECFFFF          <1> 	call	print_msg
  1221 00005357 8B35[BBDB0000]      <1> 	mov	esi, [VolSize_Unit2]
  1222 0000535D E8CEECFFFF          <1> 	call	print_msg
  1223                              <1> 	;
  1224 00005362 5E                  <1> 	pop	esi
  1225                              <1> 	
  1226                              <1> 	;mov	ah, [esi+LD_FSType]
  1227                              <1> 	;mov	al, [esi+LD_FATType]
  1228 00005363 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1229                              <1> 
  1230 00005367 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 00005368 BF[F0C30000]        <1> 	mov 	edi, Vol_Name
  1248                              <1> 
  1249                              <1> 	;mov	ah, [esi+LD_FSType]
  1250                              <1> 	;mov	al, [esi+LD_FATType]
  1251 0000536D 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1252 00005371 80FCA1              <1> 	cmp	ah, 0A1h
  1253 00005374 7418                <1> 	je	short mvn_2
  1254 00005376 08E4                <1> 	or	ah, ah
  1255 00005378 7404                <1> 	jz	short mvn_0
  1256 0000537A 08C0                <1> 	or	al, al
  1257 0000537C 7504                <1> 	jnz	short mvn_1
  1258                              <1> mvn_0:
  1259 0000537E 8A06                <1> 	mov	al, [esi]
  1260 00005380 F9                  <1> 	stc
  1261 00005381 C3                  <1> 	retn
  1262                              <1> mvn_1:
  1263 00005382 3C02                <1> 	cmp	al, 2
  1264 00005384 7717                <1> 	ja	short mvn_3 
  1265                              <1> 	;or	al, al
  1266                              <1> 	;jz	short mvn_2
  1267 00005386 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1268 00005389 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1269 0000538C EB15                <1> 	jmp	short mvn_4
  1270                              <1> mvn_2:
  1271 0000538E 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1272 00005391 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1273 00005394 B910000000          <1> 	mov	ecx, 16
  1274 00005399 F3A5                <1> 	rep	movsd
  1275 0000539B EB10                <1> 	jmp	short mvn_5
  1276                              <1> mvn_3:
  1277 0000539D 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1278 000053A0 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1279                              <1> mvn_4:
  1280 000053A3 B90B000000          <1> 	mov	ecx, 11
  1281 000053A8 F3A4                <1> 	rep	movsb
  1282 000053AA C60700              <1> 	mov	byte [edi], 0
  1283                              <1> mvn_5:
  1284                              <1> 	;mov	[Current_VolSerial], eax  
  1285 000053AD E876C5FFFF          <1> 	call	dwordtohex
  1286 000053B2 8915[45C40000]      <1> 	mov	[Vol_Serial1], edx
  1287 000053B8 A3[4AC40000]        <1> 	mov	[Vol_Serial2], eax
  1288                              <1> 	; ecx = 0
  1289 000053BD 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 000053BE 31DB                <1> 	xor	ebx, ebx
  1302 000053C0 88D7                <1> 	mov	bh, dl
  1303 000053C2 3815[18C20000]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1304 000053C8 7304                <1> 	jnb	short loc_gvsn_start
  1305                              <1> loc_gvsn_stc_retn:
  1306 000053CA 31C0                <1> 	xor	eax, eax
  1307 000053CC F9                  <1> 	stc 
  1308 000053CD C3                  <1>         retn 
  1309                              <1> loc_gvsn_start:
  1310 000053CE 56                  <1> 	push	esi
  1311 000053CF BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1312 000053D4 01DE                <1> 	add	esi, ebx
  1313 000053D6 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1314 000053D9 20DB                <1> 	and	bl, bl
  1315 000053DB 740F                <1> 	jz	short loc_gvsn_fs
  1316 000053DD 80FB02              <1> 	cmp	bl, 2
  1317 000053E0 7705                <1> 	ja	short loc_gvsn_fat32
  1318                              <1> loc_gvsn_fat:
  1319 000053E2 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1320 000053E5 EB0E                <1> 	jmp	short loc_gvsn_return
  1321                              <1> loc_gvsn_fat32: 
  1322 000053E7 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1323 000053EA EB09                <1> 	jmp	short loc_gvsn_return 
  1324                              <1> loc_gvsn_fs:
  1325 000053EC 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1326 000053F0 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1327 000053F2 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1328                              <1> loc_gvsn_return:
  1329 000053F5 8B06                <1> 	mov	eax, [esi]
  1330 000053F7 5E                  <1> 	pop	esi
  1331 000053F8 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 000053F9 C605[70DC0000]00    <1> 	mov	byte [Program_Exit],0
  1352 00005400 80F904              <1> 	cmp	cl, 4
  1353 00005403 0F87AE020000        <1>         ja      c_6
  1354 00005409 0F822E010000        <1>         jb      c_2
  1355                              <1> c_4:
  1356                              <1> 
  1357                              <1> cmp_cmd_exit:
  1358 0000540F BF[86C20000]        <1> 	mov	edi, Cmd_Exit
  1359 00005414 E8C9030000          <1> 	call	cmp_cmd	
  1360 00005419 7208                <1> 	jc	short cmp_cmd_date
  1361                              <1> 
  1362 0000541B C605[70DC0000]01    <1>         mov     byte [Program_Exit], 1
  1363 00005422 C3                  <1>         retn
  1364                              <1> 
  1365                              <1> cmp_cmd_date:
  1366 00005423 B104                <1> 	mov	cl, 4
  1367 00005425 BF[A2C20000]        <1> 	mov	edi, Cmd_Date
  1368 0000542A E8B3030000          <1> 	call	cmp_cmd	
  1369 0000542F 720B                <1>         jc	short cmp_cmd_time
  1370                              <1> 	
  1371 00005431 E8D0F7FFFF          <1> 	call	show_date
  1372 00005436 E80FF8FFFF          <1> 	call	set_date
  1373 0000543B C3                  <1> 	retn
  1374                              <1> 
  1375                              <1> cmp_cmd_time:
  1376 0000543C B104                <1> 	mov	cl, 4
  1377 0000543E BF[A7C20000]        <1> 	mov	edi, Cmd_Time
  1378 00005443 E89A030000          <1>    	call	cmp_cmd	
  1379 00005448 720B                <1> 	jc	short cmp_cmd_show
  1380                              <1> 
  1381 0000544A E8C6FAFFFF          <1> 	call	show_time
  1382 0000544F E8F8FAFFFF          <1> 	call	set_time
  1383 00005454 C3                  <1> 	retn
  1384                              <1> 
  1385                              <1> cmp_cmd_show:
  1386 00005455 B104                <1> 	mov	cl, 4
  1387 00005457 BF[B8C20000]        <1> 	mov	edi, Cmd_Show
  1388 0000545C E881030000          <1>    	call	cmp_cmd	
  1389 00005461 0F83F6090000        <1>         jnc     show_file
  1390                              <1> 
  1391                              <1> cmp_cmd_echo:
  1392 00005467 B104                <1> 	mov	cl, 4
  1393 00005469 BF[FDC20000]        <1> 	mov	edi, Cmd_Echo
  1394 0000546E E86F030000          <1>    	call	cmp_cmd	
  1395 00005473 721B                <1> 	jc	short cmp_cmd_copy
  1396                              <1> 
  1397                              <1> 	; 14/04/2016
  1398 00005475 56                  <1> 	push	esi
  1399                              <1> cmd_echo_asciiz:
  1400 00005476 46                  <1>         inc	esi
  1401 00005477 8A06                <1> 	mov	al, [esi]
  1402 00005479 3C20                <1> 	cmp	al, 20h
  1403 0000547B 73F9                <1> 	jnb	short cmd_echo_asciiz
  1404 0000547D C60600              <1> 	mov	byte [esi], 0                 
  1405 00005480 5E                  <1> 	pop	esi  
  1406 00005481 E8AAEBFFFF          <1> 	call	print_msg
  1407 00005486 BE[C3CF0000]        <1> 	mov	esi, NextLine
  1408                              <1> 	;call	print_msg   
  1409                              <1> 	;retn
  1410 0000548B E9A0EBFFFF          <1> 	jmp	print_msg
  1411                              <1> 
  1412                              <1> cmp_cmd_copy:
  1413 00005490 B104                <1> 	mov	cl, 4
  1414 00005492 BF[DBC20000]        <1> 	mov	edi, Cmd_Copy
  1415 00005497 E846030000          <1>    	call	cmp_cmd	
  1416 0000549C 0F8301180000        <1> 	jnc	copy_file
  1417                              <1> 
  1418                              <1> cmp_cmd_move:
  1419 000054A2 B104                <1> 	mov	cl, 4
  1420 000054A4 BF[E0C20000]        <1> 	mov	edi, Cmd_Move
  1421 000054A9 E834030000          <1>    	call	cmp_cmd	
  1422 000054AE 0F8395160000        <1> 	jnc	move_file
  1423                              <1> 
  1424                              <1> cmp_cmd_path:
  1425 000054B4 B104                <1> 	mov	cl, 4
  1426 000054B6 BF[E5C20000]        <1> 	mov	edi, Cmd_Path
  1427 000054BB E822030000          <1>    	call	cmp_cmd	
  1428 000054C0 0F83351A0000        <1> 	jnc	set_get_path
  1429                              <1> 
  1430                              <1> cmp_cmd_beep:
  1431 000054C6 B104                <1> 	mov	cl, 4
  1432 000054C8 BF[1BC30000]        <1> 	mov	edi, Cmd_Beep
  1433 000054CD E810030000          <1>    	call	cmp_cmd	
  1434 000054D2 720B                <1> 	jc	short cmp_cmd_find
  1435                              <1> 	; 13/05/2016
  1436 000054D4 8A3D[E6D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  1437 000054DA E9F8C2FFFF          <1> 	jmp	beeper
  1438                              <1> 
  1439                              <1> cmp_cmd_find:
  1440 000054DF B104                <1> 	mov	cl, 4
  1441 000054E1 BF[EFC20000]        <1> 	mov	edi, Cmd_Find
  1442 000054E6 E8F7020000          <1>    	call	cmp_cmd	
  1443 000054EB 0F82D4020000        <1>         jc      cmp_cmd_external
  1444                              <1> 
  1445                              <1> 	;call	find_and_list_files
  1446 000054F1 E9EC220000          <1> 	jmp	find_and_list_files
  1447                              <1> 	;retn
  1448                              <1> 
  1449                              <1> c_1:
  1450 000054F6 AD                  <1> 	lodsd
  1451                              <1> cmp_cmd_help:
  1452 000054F7 3C3F                <1> 	cmp	al, '?'
  1453 000054F9 751D                <1>         jne     short cmp_cmd_remark
  1454                              <1> 
  1455 000054FB BE[78C20000]        <1> 	mov	esi, Command_List
  1456                              <1> cmd_help_next_w:
  1457 00005500 E82BEBFFFF          <1> 	call	print_msg
  1458                              <1> 
  1459 00005505 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1460 00005508 7232                <1> 	jb	short cmd_help_retn
  1461                              <1> 	
  1462 0000550A 56                  <1> 	push	esi
  1463 0000550B BE[52CF0000]        <1> 	mov	esi, nextline
  1464 00005510 E81BEBFFFF          <1> 	call	print_msg
  1465 00005515 5E                  <1> 	pop	esi
  1466 00005516 EBE8                <1> 	jmp	short cmd_help_next_w	
  1467                              <1> 
  1468                              <1> cmp_cmd_remark:
  1469 00005518 3C2A                <1> 	cmp	al, '*'
  1470 0000551A 0F85A5020000        <1>         jne     cmp_cmd_external
  1471 00005520 46                  <1> 	inc	esi
  1472 00005521 BF[E0D30000]        <1> 	mov	edi, Remark
  1473 00005526 8A06                <1> 	mov	al, [esi]
  1474 00005528 3C20                <1> 	cmp	al, 20h
  1475 0000552A 7707                <1> 	ja	short cmd_remark_write
  1476 0000552C 89FE                <1> 	mov	esi, edi ; Remark
  1477 0000552E E9FDEAFFFF          <1> 	jmp	print_msg
  1478                              <1> 
  1479                              <1> cmd_remark_write:
  1480 00005533 AA                  <1> 	stosb
  1481 00005534 AC                  <1> 	lodsb
  1482 00005535 3C20                <1> 	cmp	al, 20h
  1483 00005537 73FA                <1> 	jnb	short cmd_remark_write
  1484 00005539 C60700              <1> 	mov	byte [edi], 0
  1485                              <1> 
  1486                              <1> cmd_help_retn:
  1487                              <1> cmd_remark_retn:
  1488                              <1> cd_retn:
  1489 0000553C C3                  <1> 	retn
  1490                              <1> 
  1491                              <1> c_2:
  1492 0000553D 80F902              <1> 	cmp	cl, 2
  1493 00005540 0F87B1000000        <1>         ja      c_3
  1494 00005546 BE[2ED40000]        <1> 	mov	esi, CommandBuffer
  1495 0000554B 72A9                <1> 	jb	short c_1
  1496                              <1> 
  1497                              <1> cmp_cmd_cd:
  1498 0000554D 66AD                <1> 	lodsw
  1499 0000554F 663D4344            <1> 	cmp	ax, 'CD'
  1500 00005553 7553                <1> 	jne	short cmp_cmd_drive
  1501 00005555 46                  <1>         inc	esi
  1502                              <1> cd_0:
  1503 00005556 668B06              <1> 	mov	ax, [esi]	
  1504 00005559 3C20                <1> 	cmp	al, 20h
  1505 0000555B 76DF                <1> 	jna	short cd_retn
  1506                              <1> 	; 10/02/2016
  1507 0000555D 80FC3A              <1> 	cmp	ah, ':'
  1508 00005560 7504                <1> 	jne	short cd_1
  1509 00005562 46                  <1> 	inc	esi
  1510 00005563 46                  <1> 	inc	esi
  1511 00005564 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 00005566 B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1521                              <1> 
  1522 00005568 E85A230000          <1> 	call	change_current_directory
  1523 0000556D 0F8374220000        <1>         jnc     change_prompt_dir_string
  1524                              <1> 
  1525                              <1> cd_error_messages:
  1526 00005573 3C03                <1> 	cmp	al, 3
  1527 00005575 740C                <1> 	je	short cd_path_not_found
  1528 00005577 3C15                <1> 	cmp	al, 15h 
  1529 00005579 745B                <1> 	je	short cd_drive_not_ready
  1530 0000557B 3C18                <1> 	cmp	al, 18h ; Bad request structure length 
  1531 0000557D 746C                <1> 	je	short cd_command_failed
  1532 0000557F 3C1A                <1> 	cmp	al, 1Ah ; Unknown media type, non-DOS disk
  1533 00005581 7468                <1>         je      short cd_command_failed
  1534                              <1> 
  1535                              <1> cd_path_not_found:
  1536 00005583 6650                <1> 	push	ax	
  1537 00005585 BE[24C50000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1538 0000558A E8A1EAFFFF          <1> 	call	print_msg
  1539 0000558F 6658                <1> 	pop	ax
  1540 00005591 3A25[7CD30000]      <1> 	cmp	ah, [Current_Dir_Level]
  1541 00005597 0F834A220000        <1>         jnb     change_prompt_dir_string
  1542 0000559D 8825[7CD30000]      <1> 	mov	[Current_Dir_Level], ah
  1543 000055A3 E93F220000          <1>         jmp     change_prompt_dir_string   
  1544                              <1> 
  1545                              <1> cmp_cmd_drive: ; change current drive
  1546                              <1> 	; C:, D:, E: etc.
  1547 000055A8 80FC3A              <1> 	cmp	ah, ':'
  1548 000055AB 0F8514020000        <1>         jne     cmp_cmd_external
  1549                              <1> 
  1550                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1551 000055B1 803E20              <1> 	cmp	byte [esi], 20h
  1552 000055B4 0F8715020000        <1>         ja      loc_cmd_failed
  1553                              <1> 
  1554 000055BA 24DF                <1> 	and	al, 0DFh
  1555 000055BC 2C41                <1> 	sub	al, 'A'
  1556 000055BE 0F820B020000        <1>         jc      loc_cmd_failed
  1557                              <1> 
  1558 000055C4 3A05[18C20000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1559 000055CA 770A                <1>         ja	short cd_drive_not_ready
  1560                              <1> 	
  1561 000055CC 88C2                <1> 	mov	dl, al
  1562 000055CE E862F3FFFF          <1> 	call 	change_current_drive
  1563 000055D3 7201                <1> 	jc	short cd_drive_not_ready	
  1564 000055D5 C3                  <1> 	retn
  1565                              <1> 
  1566                              <1> cd_drive_not_ready:
  1567 000055D6 BE[E1C40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1568 000055DB E850EAFFFF          <1> 	call	print_msg
  1569                              <1> 
  1570                              <1> cd_fail_drive_restart:
  1571 000055E0 8A15[7ED30000]      <1> 	mov	dl, [Current_Drv]
  1572                              <1> 	;call 	change_current_drive
  1573 000055E6 E94AF3FFFF          <1>         jmp     change_current_drive
  1574                              <1> 	;retn
  1575                              <1> 
  1576                              <1> cd_command_failed:
  1577 000055EB BE[C2C40000]        <1> 	mov	esi, Msg_Bad_Command
  1578 000055F0 E83BEAFFFF          <1> 	call	print_msg
  1579 000055F5 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1580                              <1> 
  1581                              <1> c_3:
  1582                              <1> cmp_cmd_dir:
  1583 000055F7 BF[78C20000]        <1> 	mov	edi, Cmd_Dir
  1584 000055FC E8E1010000          <1> 	call	cmp_cmd	
  1585 00005601 0F8380020000        <1> 	jnc	print_directory_list
  1586                              <1> 
  1587                              <1> cmp_cmd_cls:
  1588 00005607 B103                <1> 	mov	cl, 3
  1589 00005609 BF[B4C20000]        <1> 	mov	edi, Cmd_Cls
  1590 0000560E E8CF010000          <1> 	call	cmp_cmd	
  1591 00005613 0F832DEAFFFF        <1>         jnc	clear_screen
  1592                              <1> 
  1593                              <1> cmp_cmd_ver:
  1594 00005619 B103                <1> 	mov	cl, 3
  1595 0000561B BF[82C20000]        <1> 	mov	edi, Cmd_Ver
  1596 00005620 E8BD010000          <1> 	call	cmp_cmd	
  1597 00005625 720A                <1> 	jc	short cmp_cmd_mem
  1598                              <1> 
  1599 00005627 BE[20C20000]        <1> 	mov	esi, mainprog_Version
  1600                              <1> 	;call	print_msg
  1601 0000562C E9FFE9FFFF          <1> 	jmp	print_msg
  1602                              <1> 	;retn
  1603                              <1> 
  1604                              <1> cmp_cmd_mem:
  1605 00005631 B103                <1> 	mov	cl, 3
  1606 00005633 BF[EAC20000]        <1> 	mov	edi, Cmd_Mem
  1607 00005638 E8A5010000          <1> 	call	cmp_cmd	
  1608 0000563D 0F8330C2FFFF        <1> 	jnc	memory_info
  1609                              <1> 
  1610                              <1> cmp_cmd_del:
  1611 00005643 B103                <1> 	mov	cl, 3
  1612 00005645 BF[BDC20000]        <1> 	mov	edi, Cmd_Del
  1613 0000564A E893010000          <1> 	call	cmp_cmd	
  1614 0000564F 0F83340F0000        <1>         jnc     delete_file
  1615                              <1> 
  1616                              <1> cmp_cmd_set:
  1617 00005655 B103                <1> 	mov	cl, 3
  1618 00005657 BF[B0C20000]        <1> 	mov	edi, Cmd_Set
  1619 0000565C E881010000          <1> 	call	cmp_cmd	
  1620 00005661 0F830C180000        <1>         jnc     set_get_env
  1621                              <1> 
  1622                              <1> cmp_cmd_run:
  1623 00005667 B103                <1> 	mov	cl, 3
  1624 00005669 BF[ACC20000]        <1> 	mov	edi, Cmd_Run
  1625 0000566E E86F010000          <1> 	call	cmp_cmd	
  1626                              <1> 	; 07/05/2016
  1627 00005673 0F824C010000        <1>         jc      cmp_cmd_external
  1628 00005679 E9431E0000          <1> 	jmp	load_and_execute_file
  1629                              <1> c_5:
  1630                              <1> cmp_cmd_mkdir:
  1631 0000567E BF[D5C20000]        <1> 	mov	edi, Cmd_Mkdir
  1632 00005683 E85A010000          <1> 	call	cmp_cmd	
  1633 00005688 0F83930A0000        <1>         jnc     make_directory
  1634                              <1> 
  1635                              <1> cmp_cmd_rmdir:
  1636 0000568E B105                <1> 	mov	cl, 5
  1637 00005690 BF[CFC20000]        <1> 	mov	edi, Cmd_Rmdir
  1638 00005695 E848010000          <1> 	call	cmp_cmd	
  1639 0000569A 0F83A00B0000        <1>         jnc     delete_directory
  1640                              <1> 
  1641                              <1> cmp_cmd_chdir:
  1642 000056A0 B105                <1> 	mov	cl, 5
  1643 000056A2 BF[15C30000]        <1> 	mov	edi, Cmd_Chdir
  1644 000056A7 E836010000          <1> 	call	cmp_cmd	
  1645 000056AC 0F8213010000        <1>         jc      cmp_cmd_external
  1646                              <1> 
  1647 000056B2 E99FFEFFFF          <1> 	jmp	cd_0
  1648                              <1> 
  1649                              <1> c_6:
  1650 000056B7 80F906              <1> 	cmp	cl, 6
  1651 000056BA 0F87DF000000        <1>         ja      c_8
  1652 000056C0 72BC                <1> 	jb	short c_5
  1653                              <1> cmp_cmd_prompt:
  1654 000056C2 BF[8BC20000]        <1> 	mov	edi, Cmd_Prompt
  1655 000056C7 E816010000          <1> 	call	cmp_cmd	
  1656 000056CC 722E                <1>         jc	short cmp_cmd_volume
  1657                              <1> get_prompt_name_fchar:
  1658 000056CE AC                  <1> 	lodsb
  1659 000056CF 3C20                <1> 	cmp	al, 20h
  1660 000056D1 74FB                <1> 	je	short get_prompt_name_fchar
  1661 000056D3 7712                <1> 	ja	short loc_change_prompt_label
  1662 000056D5 BE[6CC20000]        <1> 	mov	esi, TRDOSPromptLabel
  1663 000056DA C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1664 000056E0 66C746045300        <1>        	mov	word [esi+4], "S" 
  1665                              <1> loc_cmd_prompt_return:
  1666 000056E6 C3                  <1> 	retn
  1667                              <1> loc_change_prompt_label:
  1668 000056E7 66B90B00            <1> 	mov	cx, 11
  1669 000056EB BF[6CC20000]        <1> 	mov	edi, TRDOSPromptLabel
  1670                              <1> put_char_new_prompt_label:
  1671 000056F0 AA                  <1> 	stosb
  1672 000056F1 AC                  <1> 	lodsb
  1673 000056F2 3C20                <1> 	cmp	al, 20h
  1674 000056F4 7202                <1> 	jb	short pass_put_new_prompt_label
  1675 000056F6 E2F8                <1> 	loop	put_char_new_prompt_label
  1676                              <1> pass_put_new_prompt_label:
  1677 000056F8 C60700              <1> 	mov	byte [edi], 0
  1678 000056FB C3                  <1> 	retn
  1679                              <1> 
  1680                              <1> cmp_cmd_volume:
  1681 000056FC B106                <1> 	mov	cl, 6
  1682 000056FE BF[92C20000]        <1> 	mov	edi, Cmd_Volume
  1683 00005703 E8DA000000          <1> 	call	cmp_cmd	
  1684 00005708 7255                <1>         jc	short cmp_cmd_attrib
  1685                              <1> 
  1686                              <1> cmd_vol1:
  1687 0000570A AC                  <1> 	lodsb
  1688 0000570B 3C20                <1> 	cmp	al, 20h
  1689 0000570D 7707                <1> 	ja	short cmd_vol2
  1690 0000570F A0[7ED30000]        <1> 	mov	al, [Current_Drv]
  1691 00005714 EB3D                <1> 	jmp	short cmd_vol4
  1692                              <1> cmd_vol2:
  1693 00005716 3C41                <1> 	cmp	al, 'A'
  1694 00005718 0F82B1000000        <1>         jb      loc_cmd_failed
  1695 0000571E 3C7A                <1> 	cmp	al, 'z'
  1696 00005720 0F87A9000000        <1>         ja      loc_cmd_failed
  1697 00005726 3C5A                <1> 	cmp	al, 'Z'
  1698 00005728 760A                <1> 	jna	short cmd_vol3
  1699 0000572A 3C61                <1> 	cmp	al, 'a'
  1700 0000572C 0F829D000000        <1>         jb      loc_cmd_failed
  1701 00005732 24DF                <1> 	and	al, 0DFh
  1702                              <1> cmd_vol3:
  1703 00005734 8A26                <1> 	mov	ah, [esi]
  1704 00005736 80FC3A              <1> 	cmp	ah, ':'
  1705 00005739 0F8590000000        <1>         jne     loc_cmd_failed
  1706 0000573F 2C41                <1> 	sub	al, 'A'
  1707 00005741 3A05[18C20000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1708 00005747 760A                <1> 	jna	short cmd_vol4
  1709                              <1> 
  1710 00005749 BE[E1C40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1711 0000574E E9DDE8FFFF          <1> 	jmp	print_msg
  1712                              <1> 	
  1713                              <1> cmd_vol4:
  1714 00005753 E896FAFFFF          <1> 	call	print_volume_info
  1715 00005758 0F8278FEFFFF        <1>         jc      cd_drive_not_ready
  1716 0000575E C3                  <1> 	retn
  1717                              <1> 
  1718                              <1> cmp_cmd_attrib:
  1719 0000575F B106                <1> 	mov	cl, 6
  1720 00005761 BF[C1C20000]        <1> 	mov	edi, Cmd_Attrib
  1721 00005766 E877000000          <1> 	call	cmp_cmd	
  1722 0000576B 0F83380F0000        <1>         jnc     set_file_attributes
  1723                              <1> 
  1724                              <1> cmp_cmd_rename:
  1725 00005771 B106                <1> 	mov	cl, 6
  1726 00005773 BF[C8C20000]        <1> 	mov	edi, Cmd_Rename
  1727 00005778 E865000000          <1> 	call	cmp_cmd	
  1728 0000577D 0F836E110000        <1>         jnc     rename_file
  1729                              <1> 
  1730                              <1> cmp_cmd_device:
  1731 00005783 B106                <1> 	mov	cl, 6
  1732 00005785 BF[06C30000]        <1> 	mov	edi, Cmd_Device
  1733 0000578A E853000000          <1> 	call	cmp_cmd	
  1734 0000578F 7234                <1>         jc	short cmp_cmd_external
  1735                              <1> 
  1736 00005791 C3                  <1> 	retn
  1737                              <1> 
  1738                              <1> c_7:
  1739                              <1> cmp_cmd_devlist:
  1740 00005792 BF[0DC30000]        <1> 	mov	edi, Cmd_DevList
  1741 00005797 E846000000          <1> 	call	cmp_cmd	
  1742 0000579C 7227                <1>         jc	short cmp_cmd_external
  1743                              <1> 
  1744 0000579E C3                  <1> 	retn
  1745                              <1> 
  1746                              <1> c_8:
  1747 0000579F 80F908              <1>         cmp	cl, 8
  1748 000057A2 7721                <1> 	ja	short cmp_cmd_external
  1749 000057A4 72EC                <1> 	jb	short c_7
  1750                              <1> 
  1751                              <1> cmp_cmd_longname:
  1752 000057A6 BF[99C20000]        <1> 	mov	edi, Cmd_LongName
  1753 000057AB E832000000          <1> 	call	cmp_cmd	
  1754 000057B0 0F8351060000        <1>         jnc     get_and_print_longname
  1755                              <1> 
  1756                              <1> cmp_cmd_readfile:
  1757 000057B6 B108                <1> 	mov	cl, 8
  1758 000057B8 BF[F4C20000]        <1> 	mov	edi, Cmd_ReadFile
  1759 000057BD E820000000          <1> 	call	cmp_cmd	
  1760 000057C2 7201                <1>         jc	short cmp_cmd_external
  1761                              <1> 
  1762                              <1> loc_cmd_return:
  1763 000057C4 C3                  <1> 	retn
  1764                              <1> 
  1765                              <1> cmp_cmd_external:
  1766                              <1> 	; 07/05/2016
  1767                              <1> 	; 22/04/2016
  1768 000057C5 BE[2ED40000]        <1> 	mov	esi, CommandBuffer
  1769 000057CA E9F21C0000          <1> 	jmp	loc_run_check_filename 
  1770                              <1> 
  1771                              <1> loc_cmd_failed:
  1772 000057CF 803D[2ED40000]20    <1> 	cmp	byte [CommandBuffer], 20h
  1773 000057D6 76EC                <1> 	jna	short loc_cmd_return
  1774 000057D8 BE[C2C40000]        <1> 	mov	esi, Msg_Bad_Command
  1775                              <1> ;	call	print_msg
  1776                              <1> ;loc_cmd_return:
  1777                              <1> ;	retn
  1778 000057DD E94EE8FFFF          <1> 	jmp	print_msg
  1779                              <1> 
  1780                              <1> cmp_cmd:
  1781                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1782 000057E2 BE[2ED40000]        <1>          mov	esi, CommandBuffer
  1783                              <1>          ; edi = internal command word (ASCIIZ)
  1784                              <1> 	 ; ecx = command length (<=8)
  1785                              <1> cmp_cmd_1:
  1786 000057E7 AC                  <1> 	lodsb
  1787 000057E8 AE                  <1> 	scasb
  1788 000057E9 750D                <1> 	jne	short cmp_cmd_3
  1789 000057EB E2FA                <1> 	loop	cmp_cmd_1
  1790 000057ED AC                  <1>  	lodsb
  1791 000057EE 3C20                <1> 	cmp	al, 20h
  1792 000057F0 7703                <1> 	ja	short cmp_cmd_2
  1793 000057F2 30C0                <1> 	xor	al, al
  1794                              <1> 	; ZF = 1 -> internal command word matches
  1795 000057F4 C3                  <1> 	retn
  1796                              <1> cmp_cmd_2:
  1797                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1798 000057F5 58                  <1> 	pop	eax ; no return to the caller from here 
  1799 000057F6 EBCD                <1> 	jmp	cmp_cmd_external	
  1800                              <1> cmp_cmd_3:
  1801 000057F8 F9                  <1> 	stc
  1802                              <1> 	; CF = 1 -> internal command word does not match
  1803 000057F9 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 000057FA 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 000057FF 3C01                <1> 	cmp	al, 1
  1817 00005801 74CC                <1> 	je	loc_cmd_failed
  1818                              <1> loc_run_dir_not_found:
  1819 00005803 3C03                <1> 	cmp	al, 3
  1820 00005805 750A                <1> 	jne	short loc_run_file_notfound_msg
  1821                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1822 00005807 BE[24C50000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1823 0000580C E91FE8FFFF          <1> 	jmp	print_msg
  1824                              <1> 
  1825                              <1> loc_run_file_notfound_msg:
  1826 00005811 3C02                <1> 	cmp	al, 2 ; File not found
  1827 00005813 750A                <1> 	jne	short loc_run_file_drv_read_err
  1828                              <1> 
  1829                              <1> loc_print_file_notfound_msg: 
  1830 00005815 BE[3BC50000]        <1>         mov     esi, Msg_File_Not_Found
  1831                              <1> 	;call	proc_printmsg
  1832                              <1> 	;retn
  1833 0000581A E911E8FFFF          <1> 	jmp	print_msg
  1834                              <1> 
  1835                              <1> loc_run_file_drv_read_err:
  1836                              <1> 	; Err: 1Eh (Read fault)
  1837 0000581F 3C1E                <1> 	cmp	al, 1Eh ; Drive not ready or read error
  1838 00005821 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1839                              <1> 	;
  1840 00005823 3C15                <1> 	cmp	al, 15h ; Drive not ready (or read error)
  1841 00005825 750A                <1> 	jne	short loc_run_file_toobig
  1842                              <1> 
  1843                              <1> loc_run_file_print_drv_read_err:
  1844 00005827 BE[E1C40000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1845 0000582C E9FFE7FFFF          <1> 	jmp	print_msg
  1846                              <1> 
  1847                              <1> loc_run_file_toobig:
  1848 00005831 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1849 00005833 750A                <1> 	jne	short loc_run_misc_error
  1850 00005835 BE[83C50000]        <1> 	mov	esi, Msg_Insufficient_Memory
  1851 0000583A 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 0000583F E8A4C0FFFF          <1> 	call	bytetohex
  1858 00005844 66A3[B7C50000]      <1>         mov     [error_code_hex], ax
  1859                              <1> 	
  1860 0000584A BE[9AC50000]        <1> 	mov	esi, Msg_Error_Code 
  1861                              <1> 	;call	print_msg 
  1862                              <1> 	;retn
  1863                              <1> 
  1864 0000584F 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 00005854 50                  <1> 	push	eax
  1869 00005855 8A3D[DEDB0000]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1870                              <1> 				; of the 'run' command.
  1871 0000585B 3A3D[7ED30000]      <1> 	cmp	bh, [Current_Drv]
  1872 00005861 7409                <1> 	je	short loc_run_restore_cdir
  1873 00005863 88FA                <1> 	mov	dl, bh
  1874 00005865 E8CBF0FFFF          <1> 	call	change_current_drive 
  1875 0000586A EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1876                              <1> 
  1877                              <1> loc_run_restore_cdir:
  1878 0000586C 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1879 00005873 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1880 00005875 30DB                <1> 	xor	bl, bl
  1881 00005877 0FB7F3              <1> 	movzx	esi, bx
  1882 0000587A 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1883 00005880 E862F1FFFF          <1> 	call	restore_current_directory
  1884                              <1> 
  1885                              <1> loc_run_err_pass_restore_cdir:
  1886 00005885 58                  <1> 	pop	eax
  1887 00005886 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 00005887 66C705[20DD0000]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1894 0000588F 08                  <1>
  1895 00005890 A0[7ED30000]        <1> 	mov	al, [Current_Drv]
  1896 00005895 A2[DEDB0000]        <1> 	mov	[RUN_CDRV], al
  1897                              <1> get_dfname_fchar:
  1898 0000589A AC                  <1> 	lodsb
  1899 0000589B 3C20                <1> 	cmp	al, 20h
  1900 0000589D 74FB                <1> 	je	short get_dfname_fchar
  1901 0000589F 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1902 000058A5 3C2D                <1> 	cmp	al, '-'
  1903 000058A7 7542                <1> 	jne	short loc_print_dir_call_flt
  1904                              <1> get_next_attr_char:
  1905 000058A9 AC                  <1> 	lodsb
  1906 000058AA 3C20                <1> 	cmp	al, 20h
  1907 000058AC 74FB                <1> 	je	short get_next_attr_char
  1908 000058AE 0F821BFFFFFF        <1>         jb      loc_cmd_failed
  1909 000058B4 24DF                <1> 	and	al, 0DFh
  1910 000058B6 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1911 000058B8 7512                <1> 	jne	short pass_only_directories
  1912 000058BA AC                  <1> 	lodsb
  1913 000058BB 3C20                <1> 	cmp	al, 20h
  1914 000058BD 0F870CFFFFFF        <1>         ja      loc_cmd_failed
  1915 000058C3 800D[20DD0000]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1916 000058CA EB18                <1> 	jmp	short get_dfname_fchar_attr
  1917                              <1> pass_only_directories:
  1918 000058CC 3C46                <1> 	cmp	al, 'F'	; files only ?
  1919 000058CE 0F85B0000000        <1>         jne     check_attr_s
  1920 000058D4 AC                  <1> 	lodsb
  1921 000058D5 3C20                <1> 	cmp	al, 20h
  1922 000058D7 0F87F2FEFFFF        <1>         ja      loc_cmd_failed
  1923 000058DD 800D[21DD0000]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1924                              <1> get_dfname_fchar_attr:
  1925 000058E4 AC                  <1> 	lodsb
  1926 000058E5 3C20                <1> 	cmp	al, 20h
  1927 000058E7 74FB                <1> 	je	short get_dfname_fchar_attr
  1928 000058E9 725E                <1> 	jb	short loc_print_dir_call_all
  1929                              <1> 
  1930                              <1> loc_print_dir_call_flt:
  1931 000058EB 4E                  <1> 	dec	esi
  1932 000058EC BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  1933 000058F1 E8E5250000          <1> 	call	parse_path_name
  1934 000058F6 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1935 000058F8 3C01                <1> 	cmp	al, 1
  1936 000058FA 0F87FAFEFFFF        <1>         ja      loc_run_cmd_failed
  1937                              <1> 
  1938                              <1> loc_print_dir_change_drv_1:
  1939 00005900 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  1940                              <1> loc_print_dir_change_drv_2:
  1941 00005906 3A15[DEDB0000]      <1> 	cmp	dl, [RUN_CDRV]
  1942 0000590C 740B                <1> 	je	short loc_print_dir_change_directory 
  1943 0000590E E822F0FFFF          <1> 	call	change_current_drive
  1944 00005913 0F82E1FEFFFF        <1>         jc      loc_run_cmd_failed
  1945                              <1> loc_print_dir_change_directory:
  1946 00005919 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1947 00005920 761D                <1> 	jna	short pass_print_dir_change_directory
  1948                              <1> 
  1949 00005922 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  1950 00005928 BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  1951 0000592D 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1952 0000592F E8931F0000          <1> 	call	change_current_directory
  1953 00005934 0F82C0FEFFFF        <1>         jc      loc_run_cmd_failed
  1954                              <1> 
  1955                              <1> loc_print_dir_change_prompt_dir_string:
  1956 0000593A E8A81E0000          <1> 	call	change_prompt_dir_string
  1957                              <1> 
  1958                              <1> pass_print_dir_change_directory:
  1959 0000593F BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  1960 00005944 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1961 00005947 7706                <1> 	ja	short loc_print_dir_call
  1962                              <1> 
  1963                              <1> loc_print_dir_call_all:
  1964 00005949 C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1965                              <1> loc_print_dir_call:
  1966 0000594F E87E000000          <1> 	call	print_directory
  1967                              <1> 
  1968 00005954 8A15[DEDB0000]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1969 0000595A 3A15[7ED30000]      <1> 	cmp	dl, [Current_Drv]
  1970 00005960 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1971 00005962 E8CEEFFFFF          <1> 	call	change_current_drive 
  1972 00005967 C3                  <1> 	retn
  1973                              <1> 
  1974                              <1> loc_print_dir_call_restore_cdir_retn:
  1975 00005968 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1976 0000596F 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  1977                              <1> 
  1978 00005971 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1979 00005976 31C0                <1> 	xor	eax, eax
  1980 00005978 88D4                <1> 	mov	ah, dl
  1981 0000597A 01C6                <1> 	add	esi, eax
  1982                              <1> 
  1983 0000597C E866F0FFFF          <1> 	call	restore_current_directory
  1984                              <1> 
  1985                              <1> pass_print_dir_call_restore_cdir_retn:
  1986 00005981 C3                  <1> 	retn
  1987                              <1> 
  1988                              <1> check_attr_s_cap:
  1989 00005982 24DF                <1> 	and	al, 0DFh
  1990                              <1> check_attr_s:
  1991 00005984 3C53                <1> 	cmp	al, 'S'
  1992 00005986 7514                <1> 	jne	short pass_attr_s
  1993 00005988 800D[20DD0000]04    <1> 	or	byte [AttributesMask], 4 ; system
  1994 0000598F AC                  <1> 	lodsb
  1995 00005990 3C20                <1> 	cmp	al, 20h
  1996 00005992 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  1997 00005998 72AF                <1> 	jb	short loc_print_dir_call_all
  1998 0000599A 24DF                <1> 	and	al, 0DFh
  1999                              <1> pass_attr_s:
  2000 0000599C 3C48                <1> 	cmp	al, 'H'
  2001 0000599E 7514                <1> 	jne	short pass_attr_h
  2002 000059A0 800D[20DD0000]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  2003                              <1> pass_attr_shr:
  2004 000059A7 AC                  <1> 	lodsb
  2005 000059A8 3C20                <1> 	cmp	al, 20h
  2006 000059AA 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  2007 000059B0 7297                <1> 	jb	short loc_print_dir_call_all
  2008 000059B2 EBCE                <1> 	jmp	short check_attr_s_cap
  2009                              <1> 
  2010                              <1> pass_attr_h:
  2011 000059B4 3C52                <1> 	cmp	al, 'R'
  2012 000059B6 7509                <1> 	jne	short pass_attr_r
  2013 000059B8 800D[20DD0000]01    <1> 	or	byte [AttributesMask], 1 ; read only
  2014 000059BF EBE6                <1> 	jmp	short pass_attr_shr
  2015                              <1> 
  2016                              <1> pass_attr_r:
  2017 000059C1 3C41                <1> 	cmp	al, 'A'
  2018 000059C3 0F8506FEFFFF        <1>         jne     loc_cmd_failed
  2019 000059C9 800D[20DD0000]20    <1> 	or	byte [AttributesMask], 20h ; archive
  2020 000059D0 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 000059D2 56                  <1> 	push	esi
  2034                              <1> 
  2035 000059D3 29C0                <1> 	sub	eax, eax
  2036                              <1> 
  2037 000059D5 66A3[ACDD0000]      <1> 	mov	word [Dir_Count], ax ; 0
  2038 000059DB 66A3[AADD0000]      <1> 	mov 	word [File_Count], ax ; 0
  2039 000059E1 A3[AEDD0000]        <1> 	mov 	dword [Total_FSize], eax ; 0
  2040                              <1> 
  2041 000059E6 E85BE6FFFF          <1> 	call    clear_screen
  2042                              <1> 	
  2043 000059EB 31C9                <1> 	xor	ecx, ecx	
  2044 000059ED 8A2D[7ED30000]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  2045 000059F3 A0[7FD30000]        <1> 	mov     al, [Current_Dir_Drv] 
  2046 000059F8 A2[DFC30000]        <1> 	mov     [Dir_Drive_Name], al
  2047 000059FD BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2048 00005A02 01CE                <1> 	add	esi, ecx
  2049                              <1> 
  2050 00005A04 E85FF9FFFF          <1> 	call	move_volume_name_and_serial_no
  2051 00005A09 730C                <1> 	jnc	short print_dir_strlen_check
  2052                              <1> 
  2053 00005A0B 5E                  <1> 	pop	esi
  2054 00005A0C 8A3D[E6D20000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  2055                              <1> 	;call	beeper
  2056                              <1> 	;retn
  2057 00005A12 E9C0BDFFFF          <1> 	jmp	beeper  ; beep ! and return
  2058                              <1> 
  2059                              <1> print_dir_strlen_check:
  2060 00005A17 BE[81D30000]        <1> 	mov	esi, Current_Dir_Root
  2061 00005A1C BF[7CC40000]        <1> 	mov	edi, Dir_Str_Root
  2062                              <1> 	
  2063                              <1> 	;xor	ecx, ecx
  2064 00005A21 8A0D[DDD30000]      <1>         mov     cl, [Current_Dir_StrLen]
  2065 00005A27 FEC1                <1> 	inc	cl
  2066 00005A29 80F940              <1> 	cmp	cl, 64
  2067 00005A2C 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2068 00005A2E 46                  <1> 	inc	esi
  2069 00005A2F 01CE                <1> 	add	esi, ecx
  2070 00005A31 83EE40              <1> 	sub	esi, 64 
  2071 00005A34 47                  <1> 	inc	edi
  2072 00005A35 B82E2E2E20          <1> 	mov	eax, '... ' 
  2073 00005A3A AB                  <1> 	stosd
  2074                              <1>  
  2075                              <1> pass_print_dir_strlen_shorting:
  2076 00005A3B F3A4                <1> 	rep	movsb
  2077                              <1> 
  2078 00005A3D BE[D2C30000]        <1> 	mov	esi, Dir_Drive_Str
  2079 00005A42 E8E9E5FFFF          <1> 	call	print_msg
  2080                              <1> 
  2081 00005A47 BE[31C40000]        <1> 	mov	esi, Vol_Serial_Header
  2082 00005A4C E8DFE5FFFF          <1> 	call	print_msg
  2083                              <1> 
  2084 00005A51 BE[71C40000]        <1> 	mov	esi, Dir_Str_Header
  2085 00005A56 E8D5E5FFFF          <1> 	call	print_msg
  2086                              <1> 	
  2087 00005A5B BE[50CF0000]        <1> 	mov	esi, next2line
  2088 00005A60 E8CBE5FFFF          <1> 	call	print_msg
  2089                              <1> 
  2090                              <1> loc_print_dir_first_file:
  2091 00005A65 C605[C1DD0000]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2092 00005A6C 66A1[20DD0000]      <1> 	mov	ax, [AttributesMask]
  2093 00005A72 5E                  <1> 	pop	esi
  2094                              <1> 
  2095 00005A73 E859020000          <1> 	call	find_first_file
  2096 00005A78 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 00005A7E F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2101 00005A81 741B                <1> 	jz	short loc_not_dir
  2102                              <1> 
  2103 00005A83 66FF05[ACDD0000]    <1> 	inc	word [Dir_Count]
  2104 00005A8A 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2105 00005A8C BE[BEC50000]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2106 00005A91 BF[D5C50000]        <1> 	mov	edi, Dir_Or_FileSize
  2107                              <1> 	; move 10 bytes
  2108 00005A96 A5                  <1> 	movsd
  2109 00005A97 A5                  <1> 	movsd
  2110 00005A98 66A5                <1> 	movsw	    	
  2111 00005A9A 89D6                <1> 	mov	esi, edx
  2112 00005A9C EB36                <1> 	jmp     short loc_dir_attribute
  2113                              <1> 
  2114                              <1> loc_not_dir:
  2115 00005A9E 66FF05[AADD0000]    <1> 	inc	word [File_Count]
  2116 00005AA5 0105[AEDD0000]      <1> 	add	[Total_FSize], eax
  2117                              <1> 
  2118 00005AAB B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2119 00005AB0 89CF                <1> 	mov	edi, ecx
  2120 00005AB2 81C7[D5C50000]      <1> 	add	edi, Dir_Or_FileSize
  2121                              <1> loc_dir_rdivide:
  2122 00005AB8 29D2                <1> 	sub	edx, edx
  2123 00005ABA F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2124 00005ABC 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2125 00005ABF 4F                  <1> 	dec	edi
  2126 00005AC0 8817                <1> 	mov     [edi], dl
  2127 00005AC2 21C0                <1> 	and	eax, eax
  2128 00005AC4 75F2                <1> 	jnz	short loc_dir_rdivide
  2129                              <1> 
  2130                              <1> loc_dir_fill_space:
  2131 00005AC6 81FF[D5C50000]      <1> 	cmp     edi, Dir_Or_FileSize
  2132 00005ACC 7606                <1> 	jna     short loc_dir_attribute
  2133 00005ACE 4F                  <1> 	dec     edi
  2134 00005ACF C60720              <1> 	mov     byte [edi], 20h
  2135 00005AD2 EBF2                <1> 	jmp     short loc_dir_fill_space
  2136                              <1> 
  2137                              <1> loc_dir_attribute:
  2138 00005AD4 C705[E0C50000]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2138 00005ADC 2020                <1>
  2139                              <1> 
  2140 00005ADE 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2141 00005AE1 7207                <1> 	jb	short loc_dir_pass_arch
  2142 00005AE3 C605[E3C50000]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2143                              <1> 
  2144                              <1> loc_dir_pass_arch:
  2145 00005AEA 80E307              <1> 	and	bl, 7
  2146 00005AED 7428                <1> 	jz	short loc_dir_file_name
  2147 00005AEF 88DF                <1> 	mov	bh, bl
  2148 00005AF1 80E303              <1> 	and	bl, 3
  2149 00005AF4 38DF                <1> 	cmp	bh, bl
  2150 00005AF6 7607                <1> 	jna	short loc_dir_pass_s
  2151 00005AF8 C605[E0C50000]53    <1> 	mov	byte [File_Attribute], 'S'
  2152                              <1> 
  2153                              <1> loc_dir_pass_s:
  2154 00005AFF 80E302              <1> 	and     bl,2
  2155 00005B02 7407                <1> 	jz      short loc_dir_pass_h
  2156 00005B04 C605[E1C50000]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2157                              <1> loc_dir_pass_h:
  2158 00005B0B 80E701              <1> 	and     bh,1
  2159 00005B0E 7407                <1> 	jz      short loc_dir_file_name
  2160 00005B10 C605[E2C50000]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 00005B17 8B5E16              <1> 	mov	ebx, [esi+16h]
  2165 00005B1A 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2166 00005B1C BF[C8C50000]        <1> 	mov     edi, File_Name
  2167                              <1> 	; move 8 bytes
  2168 00005B21 A5                  <1> 	movsd
  2169 00005B22 A5                  <1> 	movsd
  2170 00005B23 C60720              <1> 	mov	byte [edi], 20h
  2171 00005B26 47                  <1> 	inc	edi
  2172                              <1> 	; move 3 bytes
  2173 00005B27 66A5                <1> 	movsw
  2174 00005B29 A4                  <1> 	movsb
  2175 00005B2A 89CE                <1> 	mov	esi, ecx
  2176                              <1> 
  2177                              <1> Dir_Time_start:
  2178                              <1> 	;mov	ax, dx		; Time
  2179 00005B2C 6689D8              <1> 	mov	ax, bx
  2180 00005B2F 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2181 00005B33 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2182 00005B37 D40A                <1> 	aam			; Q([AL]/10)->AH
  2183                              <1> 				; R([AL]/10)->AL
  2184                              <1> 				; [AL]+[AH]= Minute as BCD
  2185 00005B39 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2186 00005B3D 86E0                <1> 	xchg	ah, al
  2187 00005B3F 66A3[F3C50000]      <1> 	mov	[File_Minute], ax
  2188                              <1> 
  2189                              <1> 	;mov	al, dh
  2190 00005B45 88F8                <1> 	mov	al, bh
  2191 00005B47 C0E803              <1> 	shr	al, 3		; shift right 3 times
  2192 00005B4A D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2193 00005B4C 660D3030            <1> 	or	ax, '00'
  2194 00005B50 86E0                <1> 	xchg	ah, al
  2195 00005B52 66A3[F0C50000]      <1> 	mov     [File_Hour], ax
  2196                              <1> 
  2197 00005B58 C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2198                              <1> 	
  2199                              <1> Dir_Date_start:
  2200 00005B5B 6689D8              <1> 	mov	ax, bx		; Date
  2201 00005B5E 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2202 00005B62 D40A                <1> 	aam			; Q([AL]/10)->AH
  2203                              <1> 				; R([AL]/10)->AL
  2204                              <1> 				; [AL]+[AH]= Day as BCD
  2205 00005B64 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2206 00005B68 86C4                <1> 	xchg	al, ah
  2207                              <1> 
  2208 00005B6A 66A3[E5C50000]      <1> 	mov	[File_Day], ax
  2209                              <1> 
  2210 00005B70 6689D8              <1> 	mov	ax, bx
  2211 00005B73 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2212 00005B77 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2213 00005B7B D40A                <1> 	aam
  2214 00005B7D 660D3030            <1> 	or	ax, '00'
  2215 00005B81 86E0                <1> 	xchg	ah, al
  2216 00005B83 66A3[E8C50000]      <1> 	mov	[File_Month], ax
  2217                              <1> 
  2218 00005B89 6689D8              <1> 	mov	ax, bx
  2219 00005B8C 66C1E809            <1> 	shr     ax, 9
  2220 00005B90 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2221 00005B94 6605BC07            <1> 	add	ax, 1980
  2222                              <1> 
  2223 00005B98 B10A                <1> 	mov	cl, 10
  2224 00005B9A F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2225 00005B9C 80CC30              <1> 	or	ah, '0'
  2226 00005B9F 8825[EEC50000]      <1> 	mov	[File_Year+3], ah
  2227 00005BA5 D40A                <1> 	aam
  2228 00005BA7 86E0                <1> 	xchg	ah, al
  2229 00005BA9 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2230 00005BAC 8825[EDC50000]      <1> 	mov	[File_Year+2], ah
  2231 00005BB2 D40A                <1> 	aam
  2232 00005BB4 86C4                <1> 	xchg	al, ah
  2233 00005BB6 660D3030            <1> 	or	ax, '00'
  2234 00005BBA 66A3[EBC50000]      <1> 	mov	[File_Year], ax
  2235                              <1> 
  2236                              <1> loc_show_line:
  2237 00005BC0 56                  <1> 	push	esi
  2238 00005BC1 BE[C8C50000]        <1> 	mov     esi, File_Name
  2239 00005BC6 E865E4FFFF          <1> 	call	print_msg
  2240 00005BCB BE[52CF0000]        <1> 	mov	esi, nextline
  2241 00005BD0 E85BE4FFFF          <1> 	call	print_msg
  2242 00005BD5 5E                  <1> 	pop	esi
  2243                              <1> 
  2244 00005BD6 FE0D[C1DD0000]      <1> 	dec	byte [PrintDir_RowCounter]
  2245 00005BDC 0F84D4000000        <1>         jz      pause_dir_scroll
  2246                              <1> 
  2247                              <1> loc_next_entry:
  2248 00005BE2 E899010000          <1> 	call	find_next_file
  2249 00005BE7 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2250                              <1> 
  2251                              <1> loc_dir_ok:
  2252 00005BED B90A000000          <1> 	mov     ecx, 10
  2253 00005BF2 66A1[ACDD0000]      <1> 	mov	ax, [Dir_Count]
  2254 00005BF8 BF[09C60000]        <1> 	mov	edi, Decimal_Dir_Count
  2255 00005BFD 6639C8              <1> 	cmp	ax, cx ; 10
  2256 00005C00 7216                <1> 	jb	short pass_ddc
  2257 00005C02 47                  <1> 	inc	edi
  2258 00005C03 6683F864            <1> 	cmp	ax, 100
  2259 00005C07 720F                <1> 	jb	short pass_ddc
  2260 00005C09 47                  <1> 	inc	edi
  2261 00005C0A 663DE803            <1> 	cmp	ax, 1000
  2262 00005C0E 7208                <1> 	jb	short pass_ddc
  2263 00005C10 47                  <1> 	inc	edi
  2264 00005C11 663D1027            <1> 	cmp	ax, 10000
  2265 00005C15 7201                <1> 	jb	short pass_ddc
  2266 00005C17 47                  <1> 	inc	edi
  2267                              <1> pass_ddc:
  2268 00005C18 886F01              <1> 	mov     [edi+1], ch ; 0
  2269                              <1> loc_ddc_rediv:
  2270 00005C1B 31D2                <1> 	xor     edx, edx
  2271 00005C1D 66F7F1              <1> 	div     cx	; 10
  2272 00005C20 80C230              <1> 	add     dl, '0'
  2273 00005C23 8817                <1> 	mov     [edi], dl
  2274 00005C25 4F                  <1> 	dec     edi
  2275 00005C26 6609C0              <1> 	or	ax, ax
  2276 00005C29 75F0                <1> 	jnz	short loc_ddc_rediv
  2277                              <1> 
  2278 00005C2B 66A1[AADD0000]      <1> 	mov     ax, [File_Count]
  2279 00005C31 BF[F8C50000]        <1> 	mov     edi, Decimal_File_Count
  2280 00005C36 6639C8              <1> 	cmp     ax, cx ; 10
  2281 00005C39 7216                <1> 	jb      short pass_dfc
  2282 00005C3B 47                  <1> 	inc     edi
  2283 00005C3C 6683F864            <1> 	cmp     ax, 100
  2284 00005C40 720F                <1> 	jb      short pass_dfc
  2285 00005C42 47                  <1> 	inc     edi
  2286 00005C43 663DE803            <1> 	cmp     ax, 1000
  2287 00005C47 7208                <1> 	jb      short pass_dfc
  2288 00005C49 47                  <1> 	inc     edi
  2289 00005C4A 663D1027            <1> 	cmp     ax, 10000
  2290 00005C4E 7201                <1> 	jb      short pass_dfc
  2291 00005C50 47                  <1> 	inc     edi
  2292                              <1> pass_dfc:
  2293                              <1> 	;mov    cx, 10
  2294 00005C51 886F01              <1> 	mov     [edi+1], ch ; 00
  2295                              <1> loc_dfc_rediv:
  2296                              <1> 	;xor	dx, dx
  2297 00005C54 30D2                <1> 	xor	dl, dl
  2298 00005C56 66F7F1              <1> 	div	cx
  2299 00005C59 80C230              <1> 	add	dl, '0'
  2300 00005C5C 8817                <1> 	mov	[edi], dl
  2301 00005C5E 4F                  <1> 	dec	edi
  2302 00005C5F 6609C0              <1> 	or	ax, ax
  2303 00005C62 75F0                <1> 	jnz	short loc_dfc_rediv
  2304                              <1> 
  2305 00005C64 BF[C0DD0000]        <1> 	mov     edi, TFS_Dec_End
  2306                              <1>         ;mov    byte [edi], 0
  2307 00005C69 A1[AEDD0000]        <1> 	mov     eax, [Total_FSize]
  2308                              <1> 	;mov    ecx, 10
  2309                              <1> rediv_tfs_hex:
  2310                              <1> 	;sub	edx, edx
  2311 00005C6E 28D2                <1> 	sub	dl, dl
  2312 00005C70 F7F1                <1> 	div	ecx
  2313 00005C72 80C230              <1> 	add	dl, '0'
  2314 00005C75 4F                  <1> 	dec     edi
  2315 00005C76 8817                <1> 	mov     [edi], dl
  2316 00005C78 21C0                <1> 	and	eax, eax
  2317 00005C7A 75F2                <1> 	jnz	short rediv_tfs_hex
  2318                              <1> 	
  2319 00005C7C 893D[B2DD0000]      <1> 	mov	[TFS_Dec_Begin], edi
  2320 00005C82 BE[F6C50000]        <1> 	mov	esi, Decimal_File_Count_Header
  2321 00005C87 E8A4E3FFFF          <1> 	call	print_msg
  2322 00005C8C BE[FEC50000]        <1> 	mov	esi, str_files
  2323 00005C91 E89AE3FFFF          <1> 	call	print_msg
  2324 00005C96 BE[0FC60000]        <1> 	mov	esi, str_dirs
  2325 00005C9B E890E3FFFF          <1> 	call	print_msg
  2326 00005CA0 8B35[B2DD0000]      <1> 	mov	esi, [TFS_Dec_Begin]
  2327 00005CA6 E885E3FFFF          <1> 	call	print_msg
  2328 00005CAB BE[20C60000]        <1> 	mov	esi, str_bytes
  2329 00005CB0 E87BE3FFFF          <1> 	call	print_msg
  2330                              <1> 
  2331 00005CB5 C3                  <1> 	retn
  2332                              <1> 
  2333                              <1> pause_dir_scroll:
  2334 00005CB6 28E4                <1> 	sub	ah, ah           
  2335 00005CB8 E8F9ADFFFF          <1> 	call	int16h
  2336 00005CBD 3C1B                <1> 	cmp	al, 1Bh
  2337 00005CBF 0F8428FFFFFF        <1>         je      loc_dir_ok
  2338 00005CC5 C605[C1DD0000]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2339 00005CCC 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 00005CD1 66A3[72DD0000]      <1> 	mov	[FindFile_AttributesMask], ax
  2374 00005CD7 BF[74DD0000]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2375 00005CDC 31C0                <1> 	xor	eax, eax
  2376 00005CDE B90B000000          <1> 	mov	ecx, 11
  2377 00005CE3 F3AB                <1> 	rep	stosd	; 44 bytes
  2378                              <1> 	;stosw		; +2 bytes 
  2379                              <1> 	    
  2380 00005CE5 BF[64DD0000]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2381 00005CEA 39FE                <1> 	cmp	esi, edi
  2382 00005CEC 7408                <1> 	je	short loc_fff_mfn_ok
  2383 00005CEE 89FA                <1> 	mov	edx, edi 
  2384                              <1> 	 ; move 13 bytes
  2385 00005CF0 A5                  <1> 	movsd
  2386 00005CF1 A5                  <1> 	movsd
  2387 00005CF2 A5                  <1> 	movsd
  2388 00005CF3 AA                  <1> 	stosb
  2389 00005CF4 89D6                <1> 	mov	esi, edx
  2390                              <1> loc_fff_mfn_ok:
  2391 00005CF6 BF[13DD0000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2392 00005CFB E810210000          <1> 	call	convert_file_name
  2393 00005D00 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2394                              <1> 
  2395 00005D02 66A1[72DD0000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2396                              <1> 	;xor	ecx, ecx
  2397 00005D08 30C9                <1> 	xor	cl, cl  
  2398 00005D0A E80C1E0000          <1> 	call	locate_current_dir_file
  2399 00005D0F 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 00005D11 30ED                <1> 	xor	ch, ch 
  2405 00005D13 80F60F              <1> 	xor	dh, 0Fh
  2406 00005D16 7408                <1> 	jz	short loc_fff_longname_yes
  2407 00005D18 882D[71DD0000]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2408 00005D1E EB0C                <1> 	jmp	short loc_fff_longname_no
  2409                              <1> 
  2410                              <1> loc_fff_longname_yes:
  2411                              <1> 	;inc	byte [FindFile_LongNameYes]
  2412 00005D20 8A0D[7EDC0000]      <1> 	mov	cl, [LFN_EntryLength]  
  2413 00005D26 880D[71DD0000]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2414                              <1> 
  2415                              <1> loc_fff_longname_no:
  2416                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2417 00005D2C 66891D[9CDD0000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2418 00005D33 6689C2              <1> 	mov	dx, ax ; Ambigouos Filename chars used sign > 0
  2419                              <1> 
  2420 00005D36 A0[7ED30000]        <1> 	mov	al, [Current_Drv]
  2421 00005D3B A2[22DD0000]        <1> 	mov	[FindFile_Drv], al 
  2422                              <1> 
  2423 00005D40 A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2424 00005D45 A3[94DD0000]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2425                              <1> 
  2426 00005D4A A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2427 00005D4F A3[98DD0000]        <1> 	mov	[FindFile_DirCluster], eax
  2428                              <1> 
  2429 00005D54 66FF05[9EDD0000]    <1> 	inc	word [FindFile_MatchCounter]
  2430                              <1> 
  2431 00005D5B 89FB                <1> 	mov	ebx, edi
  2432 00005D5D 89FE                <1> 	mov	esi, edi
  2433 00005D5F BF[74DD0000]        <1> 	mov	edi, FindFile_DirEntry
  2434 00005D64 89F8                <1> 	mov	eax, edi
  2435 00005D66 B108                <1> 	mov	cl, 8
  2436 00005D68 F3A5                <1> 	rep	movsd
  2437 00005D6A 89C6                <1> 	mov	esi, eax
  2438 00005D6C 89DF                <1> 	mov	edi, ebx
  2439                              <1> 
  2440 00005D6E A1[90DD0000]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2441                              <1> 
  2442 00005D73 8A1D[7FDD0000]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2443 00005D79 8A3D[71DD0000]      <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 00005D7F 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 00005D80 66833D[9EDD0000]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2474 00005D88 7707                <1> 	ja	short loc_start_search_next_file
  2475                              <1> 
  2476                              <1> loc_fnf_stc_retn:
  2477 00005D8A F9                  <1> 	stc
  2478                              <1> loc_fnf_ax12h_retn:
  2479 00005D8B B812000000          <1> 	mov	eax, 12h ; 18, No More files
  2480                              <1> ;loc_fnf_retn:
  2481 00005D90 C3                  <1> 	retn
  2482                              <1> 
  2483                              <1> loc_start_search_next_file:
  2484 00005D91 668B1D[9CDD0000]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2485 00005D98 6643                <1> 	inc	bx
  2486 00005D9A 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2487 00005DA1 7719                <1> 	ja	short loc_cont_search_next_file
  2488                              <1> 
  2489                              <1> loc_fnf_search:
  2490 00005DA3 BE[13DD0000]        <1> 	mov	esi, Dir_Entry_Name
  2491 00005DA8 66A1[72DD0000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2492 00005DAE 6631C9              <1> 	xor	cx, cx
  2493 00005DB1 E8671E0000          <1> 	call	find_directory_entry
  2494 00005DB6 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2495                              <1> 
  2496                              <1> loc_cont_search_next_file:
  2497 00005DBC 31DB                <1> 	xor	ebx, ebx
  2498 00005DBE 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  2499 00005DC4 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2500 00005DC9 01DE                <1> 	add	esi, ebx
  2501                              <1> 
  2502 00005DCB 803D[7CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2503 00005DD2 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2504 00005DD4 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2505 00005DD8 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2506 00005DDA EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2507                              <1>  
  2508                              <1> loc_fnf_check_FAT_type:
  2509 00005DDC 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2510 00005DE0 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2511                              <1> 
  2512                              <1> loc_fnf_check_next_cluster:
  2513 00005DE2 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2514 00005DE7 E8E6370000          <1> 	call	get_next_cluster
  2515 00005DEC 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2516 00005DEE 09C0                <1> 	or	eax, eax
  2517 00005DF0 7498                <1> 	jz	short loc_fnf_stc_retn
  2518                              <1> 	;mov	eax, 15h ;Drive not ready or read error
  2519 00005DF2 F5                  <1>  	cmc	;stc
  2520                              <1> loc_fnf_retn:
  2521 00005DF3 C3                  <1> 	retn
  2522                              <1> 
  2523                              <1> loc_fnf_load_next_dir_cluster:
  2524 00005DF4 E8BF390000          <1> 	call	load_FAT_sub_directory
  2525 00005DF9 72F8                <1> 	jc	short loc_fnf_retn
  2526 00005DFB 6631DB              <1> 	xor	bx, bx
  2527 00005DFE 66891D[9CDD0000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2528 00005E05 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 00005E07 803E20              <1> 	cmp	byte [esi], 20h
  2536 00005E0A 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 00005E0C C3                  <1> 	retn
  2542                              <1> loc_find_longname:
  2543 00005E0D E872210000          <1> 	call	find_longname
  2544 00005E12 7320                <1> 	jnc	short loc_print_longname
  2545                              <1> 	
  2546 00005E14 08C0                <1> 	or	al, al
  2547 00005E16 7412                <1> 	jz	short loc_longname_not_found
  2548                              <1> 	  
  2549 00005E18 3C15                <1> 	cmp	al, 15h
  2550 00005E1A 0F84B6F7FFFF        <1> 	je	cd_drive_not_ready
  2551                              <1> 
  2552                              <1> loc_ln_file_dir_not_found:
  2553 00005E20 BE[4DC50000]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2554                              <1> 	;call	print_msg	
  2555                              <1>         ;retn
  2556 00005E25 E906E2FFFF          <1> 	jmp	print_msg
  2557                              <1> 
  2558                              <1> loc_longname_not_found:
  2559 00005E2A BE[6CC50000]        <1>         mov     esi, Msg_LongName_Not_Found
  2560                              <1> 	;call	print_msg	
  2561                              <1>         ;retn
  2562 00005E2F E9FCE1FFFF          <1> 	jmp	print_msg
  2563                              <1> 
  2564                              <1> loc_print_longname:
  2565                              <1> 	;mov	esi, LongFileName
  2566 00005E34 BF[7ED40000]        <1> 	mov	edi, TextBuffer
  2567 00005E39 57                  <1> 	push	edi 
  2568 00005E3A 3C00                <1> 	cmp	al, 0
  2569 00005E3C 7708                <1> 	ja	short loc_print_longname_1
  2570                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2571 00005E3E AC                  <1> 	lodsb
  2572 00005E3F AA                  <1> 	stosb  
  2573 00005E40 08C0                <1> 	or	al, al
  2574 00005E42 75FA                <1> 	jnz	short loc_print_FS_longname
  2575 00005E44 EB07                <1> 	jmp	short loc_print_longname_2
  2576                              <1> 	;
  2577                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2578 00005E46 66AD                <1> 	lodsw
  2579 00005E48 AA                  <1> 	stosb  
  2580 00005E49 08C0                <1> 	or	al, al
  2581 00005E4B 75F9                <1> 	jnz	short loc_print_longname_1
  2582                              <1> 	;
  2583                              <1> loc_print_longname_2:	
  2584 00005E4D 5E                  <1> 	pop	esi
  2585 00005E4E E8DDE1FFFF          <1> 	call	print_msg
  2586 00005E53 BE[52CF0000]        <1>   	mov	esi, nextline
  2587                              <1> 	;call	print_msg
  2588                              <1> 	;retn
  2589 00005E58 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 00005E5D BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  2600 00005E62 E874200000          <1> 	call	parse_path_name
  2601 00005E67 0F8262F9FFFF        <1> 	jc	loc_cmd_failed
  2602                              <1> 
  2603                              <1> loc_show_check_filename_exists:
  2604 00005E6D BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  2605 00005E72 803E20              <1> 	cmp	byte [esi], 20h
  2606 00005E75 0F8654F9FFFF        <1> 	jna	loc_cmd_failed
  2607                              <1> 
  2608                              <1> 	; 15/02/2016 (invalid file name check)
  2609 00005E7B E809020000          <1> 	call	check_filename 	
  2610 00005E80 730A                <1> 	jnc	short loc_show_change_drv
  2611                              <1> 
  2612 00005E82 BE[36C60000]        <1> 	mov	esi, Msg_invalid_name_chars
  2613 00005E87 E9A4E1FFFF          <1> 	jmp	print_msg
  2614                              <1>    
  2615                              <1> loc_show_change_drv:
  2616 00005E8C 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  2617 00005E92 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  2618 00005E98 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  2619 00005E9E 38F2                <1> 	cmp	dl, dh
  2620 00005EA0 740B                <1> 	je	short loc_show_change_directory
  2621 00005EA2 E88EEAFFFF          <1> 	call	change_current_drive
  2622                              <1> 	;jc	loc_file_rw_cmd_failed
  2623 00005EA7 0F824DF9FFFF        <1> 	jc	loc_run_cmd_failed
  2624                              <1> 
  2625                              <1> loc_show_change_directory:
  2626 00005EAD 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2627 00005EB4 7618                <1> 	jna	short loc_findload_showfile
  2628                              <1> 
  2629 00005EB6 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2630 00005EBC BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  2631 00005EC1 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2632 00005EC3 E8FF190000          <1> 	call	change_current_directory
  2633                              <1> 	;jc	loc_file_rw_cmd_failed
  2634 00005EC8 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 00005ECE BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  2642 00005ED3 BF[13DD0000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2643 00005ED8 E8331F0000          <1> 	call	convert_file_name
  2644 00005EDD 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2645                              <1> 
  2646 00005EDF 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2647                              <1> 	; Directory attribute : 10h
  2648                              <1> 	; Volume name attribute: 8h
  2649 00005EE1 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2650                              <1> 	;
  2651 00005EE3 6631C9              <1> 	xor	cx, cx  
  2652 00005EE6 E8301C0000          <1> 	call	locate_current_dir_file
  2653                              <1> 	;jc	loc_file_rw_cmd_failed
  2654 00005EEB 0F8209F9FFFF        <1> 	jc	loc_run_cmd_failed
  2655                              <1> 
  2656                              <1> loc_show_load_file:
  2657                              <1> 	; EDI = Directory Entry
  2658 00005EF1 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2659 00005EF5 C1E010              <1> 	shl	eax, 16
  2660 00005EF8 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2661 00005EFC A3[CCDD0000]        <1> 	mov	[Show_Cluster], eax
  2662 00005F01 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2663 00005F04 21C0                <1> 	and	eax, eax ; Empty file !
  2664 00005F06 0F8491000000        <1>         jz      end_of_show_file 
  2665 00005F0C A3[D0DD0000]        <1> 	mov	[Show_FileSize], eax
  2666 00005F11 31C0                <1> 	xor	eax, eax
  2667 00005F13 A3[D4DD0000]        <1> 	mov	[Show_FilePointer], eax ; 0
  2668 00005F18 66A3[D8DD0000]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2669 00005F1E 29DB                <1> 	sub	ebx, ebx
  2670 00005F20 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  2671 00005F26 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2672 00005F2B 01DE                <1> 	add	esi, ebx
  2673 00005F2D 8935[C8DD0000]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2674                              <1> 
  2675 00005F33 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2676 00005F37 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 00005F39 8B15[CCDD0000]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2680 00005F3F 8915[C4DD0000]      <1> 	mov	[Show_FDT], edx
  2681 00005F45 31C0                <1> 	xor	eax, eax
  2682 00005F47 A3[CCDD0000]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2683                              <1> 				    ; (next time it will be 1)			
  2684                              <1> loc_show_calculate_cluster_size:
  2685 00005F4C 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 00005F50 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 00005F53 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 00005F55 66A3[DADD0000]      <1> 	mov	[Show_ClusterSize], ax
  2694                              <1> 
  2695                              <1> loc_start_show_file:
  2696 00005F5B BE[52CF0000]        <1> 	mov	esi, nextline
  2697 00005F60 E8CBE0FFFF          <1> 	call	print_msg
  2698                              <1> 
  2699 00005F65 A1[CCDD0000]        <1> 	mov	eax, [Show_Cluster]
  2700 00005F6A C605[DCDD0000]17    <1> 	mov	byte [Show_RowCount], 23
  2701                              <1> 
  2702                              <1> 	; 17/02/2016
  2703 00005F71 8B35[C8DD0000]      <1> 	mov	esi, [Show_LDDDT]
  2704                              <1> 
  2705                              <1> loc_show_next_cluster:
  2706                              <1> 	; 15/02/2016
  2707 00005F77 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2708                              <1> 	; ESI = Logical DOS drv description table address
  2709 00005F7C E875380000          <1> 	call	read_cluster
  2710                              <1> 	;jc	loc_file_rw_cmd_failed
  2711 00005F81 0F8273F8FFFF        <1> 	jc	loc_run_cmd_failed
  2712                              <1> 
  2713 00005F87 31DB                <1> 	xor 	ebx, ebx
  2714                              <1> loc_show_next_byte:
  2715 00005F89 803D[DCDD0000]00    <1> 	cmp	byte [Show_RowCount], 0
  2716 00005F90 7521                <1> 	jne	short pass_show_wait_for_key
  2717 00005F92 30E4                <1> 	xor	ah, ah
  2718 00005F94 E81DABFFFF          <1> 	call	int16h
  2719 00005F99 3C1B                <1> 	cmp	al, 1Bh
  2720 00005F9B 750F                <1> 	jne	short pass_exit_show
  2721                              <1> end_of_show_file:
  2722                              <1> pass_show_file:
  2723 00005F9D BE[52CF0000]        <1> 	mov	esi, nextline
  2724 00005FA2 E889E0FFFF          <1> 	call	print_msg
  2725 00005FA7 E94D010000          <1> 	jmp	loc_file_rw_restore_retn
  2726                              <1> 
  2727                              <1> pass_exit_show:
  2728 00005FAC C605[DCDD0000]14    <1> 	mov	byte [Show_RowCount], 20
  2729                              <1> pass_show_wait_for_key:
  2730 00005FB3 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2731 00005FB9 8A03                <1> 	mov	al, [ebx]
  2732 00005FBB 3C0D                <1> 	cmp	al, 0Dh
  2733 00005FBD 0F8590000000        <1>         jne     loc_show_check_tab_space
  2734 00005FC3 FE0D[DCDD0000]      <1> 	dec	byte [Show_RowCount]
  2735                              <1> pass_show_dec_rowcount:
  2736 00005FC9 B307                <1> 	mov	bl, 7 ; (light gray character color, black background)
  2737 00005FCB 8A3D[E6D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2738 00005FD1 E82CB7FFFF          <1> 	call	_write_tty
  2739                              <1> loc_show_check_eof:
  2740 00005FD6 FF05[D4DD0000]      <1> 	inc	dword [Show_FilePointer]
  2741 00005FDC A1[D4DD0000]        <1> 	mov	eax, [Show_FilePointer]
  2742 00005FE1 3B05[D0DD0000]      <1> 	cmp	eax, [Show_FileSize]
  2743 00005FE7 73B4                <1> 	jnb	short end_of_show_file
  2744 00005FE9 66FF05[D8DD0000]    <1> 	inc	word [Show_ClusterPointer]
  2745 00005FF0 0FB71D[D8DD0000]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2746                              <1> 
  2747                              <1> 	; 17/02/2016
  2748                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2749 00005FF7 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2750 00005FFC 758B                <1> 	jnz	short loc_show_next_byte
  2751                              <1> 
  2752                              <1> 	; 16/02/2016
  2753 00005FFE 8B35[C8DD0000]      <1> 	mov	esi, [Show_LDDDT]
  2754                              <1> 	;
  2755 00006004 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2756 00006008 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 0000600A A1[CCDD0000]        <1> 	mov	eax, [Show_Cluster]
  2761 0000600F 40                  <1> 	inc	eax
  2762 00006010 A3[CCDD0000]        <1> 	mov	[Show_Cluster], eax
  2763                              <1> 
  2764 00006015 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2765 00006018 0F856BFFFFFF        <1>         jnz	loc_show_next_byte
  2766 0000601E E954FFFFFF          <1> 	jmp     loc_show_next_cluster
  2767                              <1> 	 
  2768                              <1> loc_show_check_fat_cluster_size:
  2769                              <1> 	; 17/02/2016
  2770 00006023 663B1D[DADD0000]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2771 0000602A 0F8259FFFFFF        <1>         jb	loc_show_next_byte
  2772 00006030 66C705[D8DD0000]00- <1> 	mov	word [Show_ClusterPointer], 0
  2772 00006038 00                  <1>
  2773                              <1> 
  2774 00006039 A1[CCDD0000]        <1> 	mov	eax, [Show_Cluster]
  2775                              <1> 	;mov	esi, [Show_LDDDT]
  2776                              <1> loc_show_get_next_cluster:
  2777 0000603E E88F350000          <1> 	call	get_next_cluster
  2778                              <1> 	;jc	loc_file_rw_cmd_failed
  2779 00006043 0F82B1F7FFFF        <1> 	jc	loc_run_cmd_failed
  2780                              <1> loc_show_update_ccluster:
  2781 00006049 A3[CCDD0000]        <1> 	mov	[Show_Cluster], eax			
  2782 0000604E E924FFFFFF          <1>         jmp     loc_show_next_cluster
  2783                              <1> 
  2784                              <1> loc_show_check_tab_space:
  2785 00006053 3C09                <1> 	cmp	al, 09h
  2786 00006055 0F856EFFFFFF        <1>         jne     pass_show_dec_rowcount
  2787                              <1> loc_show_put_tab_space:
  2788 0000605B 8A3D[E6D20000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2789 00006061 E848B4FFFF          <1> 	call	get_cpos
  2790                              <1> 	; dl = cursor column
  2791 00006066 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2792                              <1> 	;shr	bh, 1 ; [ACTIVE_PAGE]
  2793 00006069 8A3D[E6D20000]      <1> 	mov	bh, [ACTIVE_PAGE]
  2794 0000606F B307                <1> 	mov	bl, 7 ; color attribute
  2795                              <1> loc_show_put_space_chars:
  2796 00006071 B020                <1> 	mov	al, 20h ; space
  2797                              <1> 	;mov	bh, [ACTIVE_PAGE] ; [ptty]
  2798                              <1> 	;mov	bl, 7 ; color attribute
  2799 00006073 6652                <1> 	push	dx
  2800 00006075 E888B6FFFF          <1> 	call	_write_tty
  2801 0000607A 665A                <1> 	pop	dx
  2802                              <1> 	; 18/02/2016
  2803 0000607C 80FA07              <1> 	cmp	dl, 7
  2804 0000607F 0F8351FFFFFF        <1> 	jnb	loc_show_check_eof
  2805 00006085 FEC2                <1> 	inc	dl
  2806 00006087 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 00006089 56                  <1> 	push	esi
  2840                              <1> 
  2841 0000608A BF[21C30000]        <1>         mov     edi, invalid_fname_chars
  2842 0000608F AC                  <1> 	lodsb
  2843                              <1> check_filename_next_char:
  2844 00006090 B914000000          <1> 	mov	ecx, sizeInvFnChars
  2845 00006095 BF[21C30000]        <1> 	mov	edi, invalid_fname_chars
  2846                              <1> loc_scan_invalid_filename_char:
  2847 0000609A AE                  <1> 	scasb 
  2848 0000609B 741F                <1> 	je	short loc_invalid_filename_stc 
  2849 0000609D E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2850 0000609F AC                  <1> 	lodsb
  2851 000060A0 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2852 000060A2 77EC                <1> 	ja	short check_filename_next_char
  2853                              <1> 
  2854                              <1> check_filename_dot:
  2855 000060A4 8B3424              <1> 	mov	esi, [esp]
  2856                              <1> 
  2857 000060A7 B421                <1> 	mov	ah, 21h
  2858 000060A9 B908000000          <1> 	mov	ecx, 8
  2859                              <1> loc_check_filename_next_char:
  2860 000060AE AC                  <1> 	lodsb
  2861 000060AF 3C2E                <1> 	cmp	al, 2Eh
  2862 000060B1 7511                <1> 	jne	short pass_check_fn_dot_check
  2863                              <1> loc_check_filename_ext_0:
  2864 000060B3 AC                  <1> 	lodsb
  2865 000060B4 38E0                <1> 	cmp	al, ah ; 21h
  2866 000060B6 7205                <1> 	jb	short loc_invalid_filename
  2867 000060B8 3C2E                <1> 	cmp	al, 2Eh
  2868 000060BA 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 000060BC F9                  <1> 	stc
  2873                              <1> loc_invalid_filename:
  2874 000060BD B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  2875                              <1> 	; Invalid file name chars
  2876                              <1> loc_check_fn_rtn:
  2877 000060C2 5E                  <1> 	pop	esi
  2878 000060C3 C3                  <1> 	retn
  2879                              <1> 
  2880                              <1> pass_check_fn_dot_check:
  2881 000060C4 38E0                <1> 	cmp	al, ah ; 21h
  2882 000060C6 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2883 000060C8 E2E4                <1> 	loop	loc_check_filename_next_char
  2884 000060CA AC                  <1> 	lodsb
  2885 000060CB 38E0                <1> 	cmp	al, ah ; 21h
  2886 000060CD 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2887 000060CF 3C2E                <1> 	cmp	al, 2Eh
  2888 000060D1 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2889 000060D3 EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2890                              <1> 
  2891                              <1> loc_check_filename_ext_1:
  2892 000060D5 AC                  <1> 	lodsb
  2893 000060D6 38E0                <1> 	cmp	al, ah ; 21h
  2894 000060D8 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2895 000060DA 3C2E                <1> 	cmp	al, 2Eh
  2896 000060DC 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2897 000060DE AC                  <1> 	lodsb
  2898 000060DF 38E0                <1> 	cmp	al, ah ; 21h
  2899 000060E1 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2900 000060E3 3C2E                <1> 	cmp	al, 2Eh
  2901 000060E5 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2902 000060E7 AC                  <1> 	lodsb
  2903 000060E8 38E0                <1> 	cmp	al, ah ; 21h
  2904 000060EA 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2905                              <1> 
  2906                              <1> loc_check_fn_clc_rtn:
  2907 000060EC 5E                  <1> 	pop	esi
  2908 000060ED F8                  <1> 	clc
  2909 000060EE C3                  <1> 	retn
  2910                              <1> 
  2911                              <1> loc_print_deleted_message:
  2912 000060EF BE[0BC70000]        <1> 	mov	esi, Msg_Deleted
  2913 000060F4 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 000060F9 9C                  <1> 	pushf 
  2922 000060FA E855F7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2923 000060FF 9D                  <1> 	popf
  2924 00006100 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2925 00006102 C3                  <1> 	retn
  2926                              <1> 
  2927                              <1> loc_permission_denied:
  2928                              <1> 	; 27/02/2016
  2929 00006103 BE[18C70000]        <1> 	mov	esi, Msg_Permission_Denied
  2930 00006108 E823DFFFFF          <1> 	call	print_msg
  2931 0000610D EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2932                              <1> 
  2933                              <1> loc_file_rw_check_write_fault:
  2934 0000610F 3C1D                <1> 	cmp	al, 1Dh ; Write Fault
  2935 00006111 0F85E8F6FFFF        <1>         jne     loc_run_cmd_failed_cmp_al
  2936 00006117 BE[02C50000]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2937                              <1> 	;call	print_msg
  2938                              <1> 	;retn
  2939 0000611C 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 00006121 803E20              <1> 	cmp	byte [esi], 20h
  2951 00006124 7701                <1>         ja	short loc_mkdir_parse_path_name
  2952                              <1> 
  2953                              <1> loc_mkdir_nodirname_retn:
  2954 00006126 C3                  <1> 	retn
  2955                              <1> 
  2956                              <1> loc_mkdir_parse_path_name:
  2957 00006127 BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  2958 0000612C E8AA1D0000          <1>         call    parse_path_name
  2959 00006131 0F8298F6FFFF        <1> 	jc	loc_cmd_failed
  2960                              <1> 
  2961                              <1> loc_mkdir_check_dirname_exists:
  2962 00006137 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  2963 0000613C 803E20              <1> 	cmp	byte [esi], 20h
  2964 0000613F 0F868AF6FFFF        <1> 	jna	loc_cmd_failed
  2965 00006145 8935[E0DD0000]      <1> 	mov	[DelFile_FNPointer], esi
  2966 0000614B E839FFFFFF          <1> 	call	check_filename
  2967 00006150 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  2968                              <1> 
  2969                              <1> loc_mkdir_drv:
  2970 00006152 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  2971 00006158 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  2972                              <1> 	
  2973 0000615E 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  2974 00006164 38F2                <1> 	cmp	dl, dh
  2975 00006166 7407                <1> 	je	short loc_mkdir_change_directory
  2976                              <1> 
  2977 00006168 E8C8E7FFFF          <1> 	call	change_current_drive
  2978 0000616D 728A                <1> 	jc	loc_file_rw_cmd_failed
  2979                              <1> 
  2980                              <1> loc_mkdir_change_directory:
  2981 0000616F 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2982 00006176 7614                <1> 	jna	short loc_mkdir_find_directory
  2983                              <1> 
  2984 00006178 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2985 0000617E BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  2986 00006183 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2987 00006185 E83D170000          <1> 	call	change_current_directory
  2988 0000618A 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 0000618C 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  2996                              <1> 	;xor	eax, eax
  2997 00006192 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  2998 00006195 E837FBFFFF          <1> 	call	find_first_file
  2999 0000619A 721E                <1> 	jc	short loc_mkdir_check_error_code
  3000                              <1> 
  3001                              <1> loc_mkdir_directory_found:
  3002 0000619C BE[63C60000]        <1> 	mov	esi, Msg_Name_Exists
  3003 000061A1 E88ADEFFFF          <1> 	call	print_msg
  3004                              <1> 
  3005 000061A6 E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3006                              <1> 
  3007                              <1> loc_mkdir_invalid_dir_name_chars:
  3008 000061AB BE[36C60000]        <1> 	mov	esi, Msg_invalid_name_chars
  3009 000061B0 E87BDEFFFF          <1> 	call	print_msg
  3010                              <1> 
  3011 000061B5 E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3012                              <1> 
  3013                              <1> loc_mkdir_check_error_code:
  3014 000061BA 3C02                <1> 	cmp	al, 2
  3015                              <1> 	;je	short loc_mkdir_directory_not_found
  3016 000061BC 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  3017 000061BE F9                  <1> 	stc
  3018 000061BF 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 000061C4 BE[84C60000]        <1> 	mov	esi, Msg_DoYouWantMkdir
  3023 000061C9 E862DEFFFF          <1> 	call	print_msg
  3024 000061CE 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3025 000061D4 E857DEFFFF          <1> 	call	print_msg
  3026 000061D9 BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  3027 000061DE E84DDEFFFF          <1> 	call	print_msg
  3028                              <1> 
  3029 000061E3 C605[ADC60000]20    <1> 	mov	byte [Y_N_nextline], 20h
  3030                              <1> 
  3031                              <1> loc_mkdir_ask_again:
  3032 000061EA 30E4                <1> 	xor	ah, ah
  3033 000061EC E8C5A8FFFF          <1> 	call	int16h
  3034 000061F1 3C1B                <1> 	cmp	al, 1Bh
  3035                              <1> 	;je	short loc_do_not_make_directory
  3036 000061F3 7447                <1> 	je	short loc_mkdir_y_n_escape
  3037 000061F5 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  3038 000061F7 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  3039 000061F9 7404                <1> 	je	short loc_mkdir_yes_make_directory
  3040 000061FB 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3041 000061FD 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 000061FF A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  3046 00006204 6650                <1> 	push	ax
  3047 00006206 BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  3048 0000620B E820DEFFFF          <1> 	call	print_msg
  3049 00006210 6658                <1> 	pop	ax
  3050                              <1> 	;cmp	al, 'Y' ; 'yes'
  3051                              <1> 	;cmc
  3052                              <1>         ;jnc	loc_file_rw_restore_retn
  3053 00006212 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3054 00006214 0F84DFFEFFFF        <1>         je	loc_file_rw_restore_retn  
  3055                              <1> 
  3056                              <1> loc_mkdir_call_make_sub_directory:
  3057 0000621A 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3058 00006220 B110                <1> 	mov	cl, 10h ; Directory attributes 
  3059 00006222 E8B31D0000          <1> 	call	make_sub_directory
  3060                              <1> loc_rename_file_ok: ; 06/03/2016
  3061 00006227 0F82CCFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  3062                              <1> move_source_file_to_destination_OK:
  3063 0000622D BE[B1C60000]        <1> 	mov	esi, Msg_OK
  3064 00006232 E8F9DDFFFF          <1> 	call	print_msg
  3065 00006237 E9BDFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3066                              <1> 
  3067                              <1> loc_mkdir_y_n_escape:
  3068 0000623C B04E                <1> 	mov	al, 'N' ; 'no'
  3069 0000623E 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 00006240 803E20              <1> 	cmp	byte [esi], 20h
  3084 00006243 7701                <1>         ja	short loc_rmdir_parse_path_name
  3085                              <1> 
  3086                              <1> loc_rmdir_nodirname_retn:
  3087 00006245 C3                  <1> 	retn
  3088                              <1> 
  3089                              <1> loc_rmdir_parse_path_name:
  3090 00006246 BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  3091 0000624B E88B1C0000          <1> 	call	parse_path_name
  3092 00006250 0F8279F5FFFF        <1> 	jc	loc_cmd_failed
  3093                              <1> 
  3094                              <1> loc_rmdir_check_dirname_exists:
  3095 00006256 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3096 0000625B 803E20              <1> 	cmp	byte [esi], 20h
  3097 0000625E 0F866BF5FFFF        <1> 	jna	loc_cmd_failed
  3098 00006264 8935[E0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3099                              <1> 
  3100                              <1> loc_rmdir_drv:
  3101 0000626A 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  3102 00006270 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3103                              <1> 
  3104 00006276 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  3105 0000627C 38F2                <1> 	cmp	dl, dh
  3106 0000627E 740B                <1> 	je	short loc_rmdir_change_directory
  3107                              <1> 
  3108 00006280 E8B0E6FFFF          <1> 	call	change_current_drive
  3109 00006285 0F826EFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3110                              <1> 
  3111                              <1> loc_rmdir_change_directory:
  3112 0000628B 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3113 00006292 7614                <1> 	jna	short loc_rmdir_find_directory
  3114                              <1> 
  3115 00006294 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3116 0000629A BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  3117 0000629F 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3118 000062A1 E821160000          <1> 	call	change_current_directory
  3119 000062A6 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 000062A8 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3127 000062AE 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3128 000062B2 E81AFAFFFF          <1> 	call	find_first_file
  3129 000062B7 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3130                              <1> 
  3131                              <1> loc_rmdir_check_error_code:
  3132 000062B9 3C02                <1> 	cmp	al, 2
  3133 000062BB 740B                <1> 	je	short loc_rmdir_directory_not_found
  3134 000062BD F9                  <1> 	stc
  3135 000062BE E936FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3136                              <1> 
  3137                              <1> loc_rmdir_ambgfn_check:
  3138 000062C3 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3139 000062C6 740F                <1> 	jz	short loc_rmdir_directory_found
  3140                              <1> 
  3141                              <1> loc_rmdir_directory_not_found:
  3142 000062C8 BE[24C50000]        <1> 	mov	esi, Msg_Dir_Not_Found
  3143 000062CD E85EDDFFFF          <1> 	call	print_msg
  3144                              <1> 
  3145 000062D2 E922FEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3146                              <1> 
  3147                              <1> loc_rmdir_directory_found:
  3148 000062D7 80E307              <1> 	and	bl, 07h ; Attributes
  3149 000062DA 0F8523FEFFFF        <1> 	jnz	loc_permission_denied
  3150                              <1> 
  3151                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3152                              <1>        ;mov	bh, [LongName_EntryLength]
  3153 000062E0 883D[EADD0000]      <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 000062E6 57                  <1> 	push	edi ; * (29/02/2016)
  3166                              <1> 
  3167 000062E7 BE[B7C60000]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3168 000062EC E83FDDFFFF          <1> 	call	print_msg
  3169 000062F1 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3170 000062F7 E834DDFFFF          <1> 	call	print_msg
  3171 000062FC BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  3172 00006301 E82ADDFFFF          <1> 	call	print_msg
  3173                              <1> 
  3174                              <1> loc_rmdir_ask_again:
  3175 00006306 30E4                <1> 	xor	ah, ah
  3176 00006308 E8A9A7FFFF          <1> 	call	int16h
  3177 0000630D 3C1B                <1> 	cmp	al, 1Bh
  3178                              <1> 	;je	short loc_do_not_delete_directory
  3179 0000630F 0F8498000000        <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3180 00006315 24DF                <1> 	and	al, 0DFh
  3181 00006317 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  3182 0000631C 3C59                <1> 	cmp	al, 'Y'
  3183 0000631E 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3184 00006320 3C4E                <1> 	cmp	al, 'N'
  3185 00006322 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 00006324 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  3190 00006329 6650                <1> 	push	ax
  3191 0000632B BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  3192 00006330 E8FBDCFFFF          <1> 	call	print_msg
  3193 00006335 6658                <1> 	pop	ax
  3194 00006337 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 00006338 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3199 0000633A 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 00006340 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3204 00006344 C1E010              <1>         shl	eax, 16
  3205 00006347 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3206                              <1> 
  3207 0000634B A3[E4DD0000]        <1> 	mov 	[DelFile_FCluster], eax
  3208                              <1> 
  3209                              <1> 	;mov	bx, [DirBuff_EntryCounter]
  3210 00006350 668B1D[9CDD0000]    <1> 	mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3211 00006357 66891D[E8DD0000]    <1> 	mov	[DelFile_EntryCounter], bx
  3212                              <1> 
  3213 0000635E 29DB                <1>     	sub	ebx, ebx
  3214 00006360 8A3D[22DD0000]      <1> 	mov	bh, [FindFile_Drv]
  3215 00006366 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3216 0000636B 01DE                <1> 	add	esi, ebx
  3217                              <1> 
  3218 0000636D 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3219 00006373 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 00006375 8B15[ADDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  3228 0000637B 8915[14DE0000]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3229                              <1> 
  3230 00006381 893D[10DE0000]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3231                              <1> 
  3232                              <1> 	; 01/03/2016
  3233 00006387 C705[9EDB0000]0000- <1> 	mov	dword [FAT_ClusterCounter], 0 ; Reset
  3233 0000638F 0000                <1>
  3234                              <1> 
  3235                              <1> loc_rmdir_get_last_cluster:
  3236 00006391 E8373A0000          <1> 	call	get_last_cluster
  3237 00006396 0F82B8000000        <1>         jc      loc_rmdir_cmd_failed
  3238                              <1> 	
  3239 0000639C 3B05[E4DD0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3240 000063A2 752F                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3241                              <1> 
  3242 000063A4 C605[0FDE0000]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3243 000063AB EB2D                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3244                              <1> 
  3245                              <1> loc_rmdir_y_n_escape:
  3246 000063AD B04E                <1> 	mov	al, 'N' ; 'no'
  3247 000063AF E970FFFFFF          <1>         jmp     loc_do_not_delete_directory
  3248                              <1> 
  3249                              <1> loc_rmdir_delete_fs_directory:
  3250 000063B4 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3251 000063B8 0F8545FDFFFF        <1> 	jne	loc_permission_denied
  3252                              <1> 
  3253 000063BE E821140000          <1> 	call	delete_fs_directory
  3254 000063C3 0F8326FDFFFF        <1> 	jnc	loc_print_deleted_message
  3255                              <1> 
  3256 000063C9 09C0                <1> 	or	eax, eax
  3257 000063CB 745D                <1> 	jz	loc_rmdir_directory_not_empty_2         
  3258 000063CD F9                  <1> 	stc
  3259 000063CE E926FDFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3260                              <1>  
  3261                              <1> loc_rmdir_multi_dir_clusters:
  3262 000063D3 C605[0FDE0000]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3263                              <1> 
  3264                              <1> pass_rmdir_multi_dir_clusters:
  3265 000063DA A3[18DE0000]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3266 000063DF 890D[1CDE0000]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3267                              <1> 
  3268                              <1> loc_rmdir_load_fat_sub_directory:
  3269 000063E5 E8CE330000          <1> 	call	load_FAT_sub_directory
  3270 000063EA 7268                <1> 	jc	loc_rmdir_cmd_failed
  3271                              <1> 
  3272                              <1> loc_rmdir_find_last_dir_entry:
  3273 000063EC 56                  <1> 	push	esi
  3274 000063ED BE[06DD0000]        <1> 	mov	esi, Dir_File_Name
  3275 000063F2 C6062A              <1> 	mov	byte [esi], '*'
  3276 000063F5 C646082A            <1> 	mov	byte [esi+8], '*'
  3277 000063F9 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3278                              <1> loc_rmdir_find_last_dir_entry_next:
  3279 000063FB 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3280 000063FF 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3281 00006402 E816180000          <1> 	call	find_directory_entry
  3282 00006407 7271                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3283 00006409 83FB01              <1> 	cmp	ebx, 1
  3284 0000640C 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3285                              <1> loc_rmdir_dot_entry_check:
  3286 0000640E 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3287 00006411 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3288 00006413 08DB                <1> 	or	bl, bl
  3289 00006415 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3290 00006417 807F0120            <1> 	cmp	byte [edi+1], 20h
  3291 0000641B EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3292                              <1> 
  3293                              <1> loc_rmdir_dotdot_entry_check:
  3294 0000641D 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3295                              <1> pass_rmdir_dot_entry_check:	
  3296 00006423 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3297 00006425 FEC3                <1> 	inc	bl
  3298 00006427 EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3299                              <1> 
  3300                              <1> 
  3301                              <1> loc_rmdir_directory_not_empty_1:
  3302 00006429 58                  <1> 	pop	eax ; pushed esi 
  3303                              <1> 
  3304                              <1> loc_rmdir_directory_not_empty_2:
  3305 0000642A BE[D8C60000]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3306 0000642F E8FCDBFFFF          <1> 	call	print_msg
  3307                              <1> 	; 01/03/2016
  3308 00006434 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3309 00006439 09C0                <1> 	or	eax, eax ; 0 ?
  3310 0000643B 0F84B8FCFFFF        <1> 	jz	loc_file_rw_restore_retn
  3311                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3312                              <1> 
  3313 00006441 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3314                              <1> 	           ; BL = 1 -> add free clusters
  3315 00006445 E804380000          <1> 	call	calculate_fat_freespace
  3316 0000644A 09C9                <1> 	or	ecx, ecx
  3317 0000644C 0F84A7FCFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3318                              <1> 	; ecx > 0 -> Error (Recalculation is neeeded)
  3319 00006452 EB0E                <1> 	jmp	short loc_rmdir_cmd_return
  3320                              <1> 
  3321                              <1> 
  3322                              <1> loc_rmdir_cmd_failed:
  3323 00006454 833D[9EDB0000]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3324 0000645B 0F8298FCFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3325 00006461 F9                  <1> 	stc
  3326                              <1> loc_rmdir_cmd_return:
  3327                              <1> 	; 01/03/2016
  3328 00006462 9C                  <1> 	pushf
  3329                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3330 00006463 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3331                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3332 00006467 50                  <1> 	push	eax
  3333 00006468 E8E1370000          <1> 	call	calculate_fat_freespace	
  3334 0000646D 58                  <1> 	pop	eax
  3335 0000646E 9D                  <1> 	popf
  3336 0000646F 0F8284FCFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3337 00006475 E97FFCFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3338                              <1> 
  3339                              <1> 
  3340                              <1> loc_rmdir_empty_dir_cluster:
  3341 0000647A 5E                  <1> 	pop	esi
  3342                              <1> 
  3343                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3344 0000647B 803D[0FDE0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3345 00006482 761D                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3346                              <1> 
  3347 00006484 A1[1CDE0000]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3348                              <1> 	;xor	ecx, ecx
  3349 00006489 49                  <1> 	dec	ecx ; FFFFFFFFh
  3350 0000648A E86D340000          <1> 	call	update_cluster
  3351 0000648F 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 00006491 83F801              <1> 	cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3356 00006494 F5                  <1> 	cmc 
  3357 00006495 72BD                <1> 	jc	short loc_rmdir_cmd_failed
  3358 00006497 EB1D                <1> 	jmp	short loc_rmdir_save_fat_buffer 
  3359                              <1> 	
  3360                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3361 00006499 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  3362 0000649E F9                  <1> 	stc
  3363 0000649F EBB3                <1> 	jmp	short loc_rmdir_cmd_failed
  3364                              <1>  
  3365                              <1> loc_rmdir_unlink_dir_last_cluster:
  3366 000064A1 A1[18DE0000]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3367 000064A6 31C9                <1> 	xor	ecx, ecx ; 0
  3368 000064A8 E84F340000          <1> 	call	update_cluster
  3369 000064AD 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 000064AF 09C0                <1> 	or	eax, eax
  3373 000064B1 7403                <1> 	jz	short loc_rmdir_save_fat_buffer ; eocc	
  3374 000064B3 F9                  <1> 	stc
  3375 000064B4 EB9E                <1>         jmp     short loc_rmdir_cmd_failed
  3376                              <1> 	 
  3377                              <1> loc_rmdir_save_fat_buffer:
  3378 000064B6 803D[96DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3379 000064BD 7525                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3380 000064BF E8F5360000          <1> 	call	save_fat_buffer
  3381 000064C4 728E                <1> 	jc	short loc_rmdir_cmd_failed
  3382                              <1> 
  3383                              <1> 	; 01/03/2016
  3384 000064C6 803D[0FDE0000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3385 000064CD 7615                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3386                              <1> 
  3387 000064CF A1[E4DD0000]        <1> 	mov	eax, [DelFile_FCluster]
  3388 000064D4 E9B8FEFFFF          <1>         jmp     loc_rmdir_get_last_cluster
  3389                              <1> 
  3390                              <1> loc_rmdir_delete_short_name_invalid_data:
  3391 000064D9 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  3392 000064DE F9                  <1> 	stc
  3393 000064DF E970FFFFFF          <1>         jmp     loc_rmdir_cmd_failed
  3394                              <1> 
  3395                              <1> loc_rmdir_calculate_FAT_freespace:
  3396 000064E4 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3397 000064E9 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 000064ED E85C370000          <1> 	call	calculate_fat_freespace
  3402                              <1> 
  3403 000064F2 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3404 000064F4 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3405                              <1> 
  3406                              <1> loc_rmdir_recalculate_FAT_freespace:
  3407 000064F6 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3408 000064FA E84F370000          <1> 	call	calculate_fat_freespace
  3409                              <1> 	          
  3410                              <1> loc_rmdir_delete_short_name_continue:
  3411 000064FF A1[14DE0000]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3412 00006504 83F802              <1> 	cmp	eax, 2
  3413 00006507 730D                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3414 00006509 E81F320000          <1> 	call	load_FAT_root_directory
  3415 0000650E 0F82E5FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3416 00006514 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 00006516 E89D320000          <1> 	call	load_FAT_sub_directory
  3420 0000651B 0F82D8FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3421                              <1> 
  3422                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3423 00006521 0FB73D[10DE0000]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3424 00006528 81C700000800        <1> 	add	edi, Directory_Buffer
  3425                              <1> 
  3426 0000652E 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3427 00006532 C1E010              <1> 	shl	eax, 16
  3428 00006535 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3429                              <1>         ; Not necessary... 
  3430 00006539 3B05[E4DD0000]      <1> 	cmp	eax, [DelFile_FCluster]
  3431 0000653F 7598                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3432                              <1> 	;
  3433 00006541 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 00006544 C605[A8DB0000]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3439                              <1> 	;
  3440 0000654B E8EF1D0000          <1> 	call	save_directory_buffer
  3441 00006550 0F82A3FBFFFF        <1> 	jc	loc_file_rw_cmd_failed 
  3442                              <1> 
  3443                              <1> loc_rmdir_del_long_name:
  3444 00006556 0FB615[EADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3445 0000655D 08D2                <1> 	or	dl, dl
  3446 0000655F 7414                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3447                              <1>              
  3448 00006561 0FB705[E8DD0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3449 00006568 29D0                <1> 	sub	eax, edx
  3450 0000656A 0F8289FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3451                              <1>  
  3452                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3453 00006570 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 00006575 E8601E0000          <1> 	call	update_parent_dir_lmdt
  3458                              <1> 	;jc	short loc_file_rw_cmd_failed
  3459                              <1> 
  3460                              <1> loc_rmdir_ok:
  3461 0000657A BE[B1C60000]        <1> 	mov	esi, Msg_OK
  3462 0000657F E8ACDAFFFF          <1> 	call	print_msg
  3463 00006584 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 00006589 803E20              <1> 	cmp	byte [esi], 20h
  3475 0000658C 7701                <1>         ja	short loc_delfile_parse_path_name
  3476                              <1> 
  3477                              <1> loc_delfile_nofilename_retn:
  3478 0000658E C3                  <1> 	retn
  3479                              <1> 
  3480                              <1> loc_delfile_parse_path_name:
  3481 0000658F BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  3482 00006594 E842190000          <1> 	call	parse_path_name
  3483 00006599 0F8230F2FFFF        <1> 	jc	loc_cmd_failed
  3484                              <1> 
  3485                              <1> loc_delfile_check_filename_exists:
  3486 0000659F BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3487 000065A4 803E20              <1> 	cmp	byte [esi], 20h
  3488 000065A7 0F8622F2FFFF        <1> 	jna	loc_cmd_failed
  3489 000065AD 8935[E0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3490                              <1> 
  3491                              <1> loc_delfile_drv:
  3492 000065B3 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  3493 000065B9 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  3494 000065BF 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3495 000065C5 38F2                <1> 	cmp	dl, dh
  3496 000065C7 740B                <1> 	je	short loc_delfile_change_directory
  3497                              <1> 
  3498 000065C9 E867E3FFFF          <1> 	call	change_current_drive
  3499 000065CE 0F8225FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3500                              <1> 
  3501                              <1> loc_delfile_change_directory:
  3502 000065D4 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3503 000065DB 7618                <1> 	jna	short loc_delfile_find
  3504                              <1> 
  3505 000065DD FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3506 000065E3 BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  3507 000065E8 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3508 000065EA E8D8120000          <1> 	call	change_current_directory
  3509 000065EF 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 000065F5 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3517 000065FB 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3518 000065FF E8CDF6FFFF          <1> 	call	find_first_file
  3519 00006604 0F82EFFAFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3520                              <1> 
  3521                              <1> loc_delfile_ambgfn_check:
  3522 0000660A 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3523 0000660D 740B                <1> 	jz	short loc_delfile_found
  3524                              <1> 
  3525                              <1> loc_file_not_found:
  3526 0000660F B802000000          <1> 	mov	eax, 2 ; File not found sign
  3527 00006614 F9                  <1> 	stc
  3528 00006615 E9DFFAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3529                              <1> 
  3530                              <1> loc_delfile_found:
  3531 0000661A 80E307              <1> 	and	bl, 07h ; Attributes
  3532 0000661D 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 00006623 57                  <1> 	push	edi ; * (29/02/2016)
  3539                              <1> 
  3540 00006624 BE[EFC60000]        <1> 	mov	esi, Msg_DoYouWantDelete
  3541 00006629 E802DAFFFF          <1> 	call	print_msg
  3542 0000662E 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3543 00006634 E8F7D9FFFF          <1> 	call	print_msg
  3544 00006639 BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  3545 0000663E E8EDD9FFFF          <1> 	call	print_msg
  3546                              <1> 
  3547                              <1> loc_delfile_ask_again:
  3548 00006643 30E4                <1> 	xor	ah, ah
  3549 00006645 E86CA4FFFF          <1> 	call	int16h
  3550 0000664A 3C1B                <1> 	cmp	al, 1Bh
  3551                              <1> 	;je	short loc_do_not_delete_file
  3552 0000664C 7457                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3553 0000664E 24DF                <1> 	and	al, 0DFh
  3554 00006650 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  3555 00006655 3C59                <1> 	cmp	al, 'Y'
  3556 00006657 7404                <1> 	je	short loc_yes_delete_file
  3557 00006659 3C4E                <1> 	cmp	al, 'N'
  3558 0000665B 75E6                <1> 	jne	short loc_delfile_ask_again
  3559                              <1> 
  3560                              <1> loc_do_not_delete_file:
  3561                              <1> loc_yes_delete_file:
  3562 0000665D A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  3563 00006662 6650                <1> 	push	ax
  3564 00006664 BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  3565 00006669 E8C2D9FFFF          <1> 	call	print_msg
  3566 0000666E 6658                <1> 	pop	ax
  3567 00006670 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 00006671 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3572 00006673 0F8480FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3573                              <1> 
  3574                              <1> loc_delete_file:
  3575 00006679 8A3D[22DD0000]      <1> 	mov	bh, [FindFile_Drv]
  3576                              <1> 	;mov	bl, [DelFile_LNEL]
  3577 0000667F 8A1D[71DD0000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3578                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3579 00006685 668B0D[9CDD0000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3580                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3581 0000668C E8F81F0000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3582 00006691 0F8358FAFFFF        <1> 	jnc	loc_print_deleted_message
  3583                              <1> 
  3584 00006697 3C05                <1> 	cmp	al, 05h
  3585 00006699 0F8464FAFFFF        <1> 	je	loc_permission_denied
  3586 0000669F F9                  <1> 	stc
  3587 000066A0 E954FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3588                              <1> 
  3589                              <1> loc_delfile_y_n_escape:
  3590 000066A5 B04E                <1> 	mov	al, 'N' ; 'no'
  3591 000066A7 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 000066A9 6631C0              <1> 	xor	ax, ax
  3602 000066AC 66A3[40C70000]      <1> 	mov	[Attr_Chars], ax
  3603 000066B2 A2[38DE0000]        <1> 	mov	[Attributes], al
  3604                              <1> 
  3605                              <1> get_attrib_fchar:
  3606                              <1> 	; esi = file name
  3607 000066B7 8A06                <1> 	mov	al, [esi]
  3608 000066B9 3C20                <1> 	cmp	al, 20h
  3609 000066BB 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3610                              <1> 
  3611                              <1> loc_scan_attrib_params:
  3612 000066BD 3C2D                <1> 	cmp	al, '-'
  3613 000066BF 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3614 000066C5 7408                <1> 	je	short loc_attr_space
  3615                              <1> 
  3616 000066C7 3C2B                <1> 	cmp	al, '+'
  3617 000066C9 0F8500F1FFFF        <1> 	jne	loc_cmd_failed
  3618                              <1> 
  3619                              <1> loc_attr_space:
  3620 000066CF 8A6601              <1> 	mov	ah, [esi+1]
  3621 000066D2 80FC20              <1>  	cmp	ah, 20h
  3622 000066D5 770A                <1> 	ja	short pass_attr_space
  3623 000066D7 0F82F2F0FFFF        <1> 	jb	loc_cmd_failed
  3624 000066DD 46                  <1> 	inc	esi
  3625 000066DE EBEF                <1> 	jmp	short loc_attr_space
  3626                              <1> 
  3627                              <1> loc_attr_file_nofilename_retn:
  3628 000066E0 C3                  <1> 	retn
  3629                              <1> 
  3630                              <1> pass_attr_space:
  3631 000066E1 80E4DF              <1> 	and	ah, 0DFh
  3632 000066E4 80FC53              <1> 	cmp	ah, 'S'
  3633 000066E7 0F87E2F0FFFF        <1> 	ja	loc_cmd_failed
  3634 000066ED 7204                <1> 	jb	short pass_attr_system
  3635 000066EF B404                <1> 	mov	ah, 04h   ; System
  3636 000066F1 EB21                <1> 	jmp	short pass_attr_archive
  3637                              <1> 
  3638                              <1> pass_attr_system:
  3639 000066F3 80FC48              <1> 	cmp	ah, 'H'
  3640 000066F6 7706                <1> 	ja	short pass_attr_hidden
  3641 000066F8 7213                <1> 	jb	short pass_attr_read_only
  3642 000066FA B402                <1> 	mov	ah, 02h    ; Hidden
  3643 000066FC EB16                <1> 	jmp	short pass_attr_archive
  3644                              <1> 
  3645                              <1> pass_attr_hidden:
  3646 000066FE 80FC52              <1> 	cmp	ah, 'R'
  3647 00006701 0F87C8F0FFFF        <1> 	ja	loc_cmd_failed
  3648 00006707 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3649 00006709 B401                <1> 	mov	ah, 01h
  3650 0000670B EB07                <1> 	jmp	short pass_attr_archive
  3651                              <1> 
  3652                              <1> pass_attr_read_only:
  3653 0000670D 80FC41              <1> 	cmp	ah, 'A'
  3654 00006710 753B                <1> 	jne	short loc_chk_attr_enter
  3655 00006712 B420                <1> 	mov	ah, 20h    ; Archive
  3656                              <1> 
  3657                              <1> pass_attr_archive:
  3658 00006714 3C2D                <1> 	cmp	al, '-'
  3659 00006716 7508                <1> 	jne	short pass_reducing_attributes
  3660 00006718 0825[40C70000]      <1> 	or	[Attr_Chars], ah
  3661 0000671E EB06                <1> 	jmp	short loc_change_attributes_inc
  3662                              <1> 
  3663                              <1> pass_reducing_attributes:
  3664 00006720 0825[41C70000]      <1> 	or	[Attr_Chars+1], ah
  3665                              <1> 
  3666                              <1> loc_change_attributes_inc:
  3667 00006726 46                  <1> 	inc	esi
  3668 00006727 8A6601              <1> 	mov	ah, [esi+1]
  3669 0000672A 80FC20              <1> 	cmp	ah, 20h
  3670 0000672D 7227                <1> 	jb	short pass_change_attr
  3671 0000672F 74F5                <1> 	je	short loc_change_attributes_inc
  3672 00006731 80FC2D              <1> 	cmp	ah, '-'
  3673 00006734 770D                <1> 	ja	short loc_chk_next_attr_char1
  3674 00006736 7405                <1> 	je	short loc_chk_next_attr_char0
  3675 00006738 80FC2B              <1> 	cmp	ah, '+'
  3676 0000673B 7506                <1> 	jne	short loc_chk_next_attr_char1
  3677                              <1> 
  3678                              <1> loc_chk_next_attr_char0:
  3679 0000673D 46                  <1> 	inc	esi
  3680 0000673E 668B06              <1> 	mov	ax, [esi]
  3681 00006741 EB9E                <1> 	jmp	short pass_attr_space
  3682                              <1> 
  3683                              <1> loc_chk_next_attr_char1:
  3684 00006743 803E2D              <1> 	cmp	byte [esi], '-'
  3685 00006746 7799                <1> 	ja	short pass_attr_space
  3686 00006748 E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3687                              <1> 
  3688                              <1> loc_chk_attr_enter:
  3689 0000674D 80FC0D              <1> 	cmp	ah, 0Dh
  3690 00006750 0F8579F0FFFF        <1> 	jne	loc_cmd_failed
  3691                              <1> 
  3692                              <1> pass_change_attr:
  3693 00006756 A0[40C70000]        <1> 	mov	al, [Attr_Chars]
  3694 0000675B F6D0                <1> 	not	al
  3695 0000675D 2005[38DE0000]      <1> 	and	[Attributes], al
  3696 00006763 A0[41C70000]        <1> 	mov	al, [Attr_Chars+1]
  3697 00006768 0805[38DE0000]      <1> 	or	[Attributes], al
  3698                              <1> 
  3699                              <1> loc_show_attributes:
  3700 0000676E BE[52CF0000]        <1> 	mov	esi, nextline
  3701 00006773 E8B8D8FFFF          <1> 	call	print_msg
  3702                              <1> 
  3703                              <1> loc_show_attributes_no_nextline:
  3704 00006778 C705[40C70000]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3704 00006780 524D                <1>
  3705 00006782 66C705[44C70000]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3705 0000678A 4C                  <1>
  3706 0000678B BE[40C70000]        <1> 	mov	esi, Attr_Chars
  3707 00006790 A0[38DE0000]        <1> 	mov	al, [Attributes]
  3708 00006795 A804                <1> 	test	al, 04h
  3709 00006797 7406                <1> 	jz	short pass_put_attr_s
  3710 00006799 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3711 0000679E 46                  <1> 	inc	esi
  3712                              <1> 
  3713                              <1> pass_put_attr_s:
  3714 0000679F A802                <1> 	test	al, 02h
  3715 000067A1 7406                <1> 	jz	short pass_put_attr_h
  3716 000067A3 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3717 000067A8 46                  <1> 	inc	esi
  3718                              <1> 
  3719                              <1> pass_put_attr_h:
  3720 000067A9 A801                <1> 	test	al, 01h
  3721 000067AB 7406                <1> 	jz	short pass_put_attr_r
  3722 000067AD 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3723 000067B2 46                  <1> 	inc	esi
  3724                              <1> 
  3725                              <1> pass_put_attr_r:
  3726 000067B3 3C20                <1> 	cmp	al, 20h
  3727 000067B5 7205                <1> 	jb	short pass_put_attr_a
  3728 000067B7 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3729                              <1> 
  3730                              <1> pass_put_attr_a:
  3731 000067BC BE[33C70000]        <1> 	mov	esi, Str_Attributes
  3732 000067C1 E86AD8FFFF          <1> 	call	print_msg
  3733 000067C6 BE[52CF0000]        <1> 	mov	esi, nextline
  3734 000067CB E860D8FFFF          <1> 	call	print_msg
  3735 000067D0 E924F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3736                              <1> 
  3737                              <1> loc_attr_file_check_fname_fchar:
  3738 000067D5 46                  <1> 	inc	esi
  3739 000067D6 803E20              <1> 	cmp	byte [esi], 20h
  3740 000067D9 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3741 000067DB 0F8275FFFFFF        <1>         jb      pass_change_attr
  3742                              <1> 		   
  3743                              <1> loc_attr_file_parse_path_name:
  3744 000067E1 BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  3745 000067E6 E8F0160000          <1> 	call	parse_path_name
  3746 000067EB 0F82DEEFFFFF        <1> 	jc	loc_cmd_failed
  3747                              <1> 
  3748                              <1> loc_attr_file_check_filename_exists:
  3749 000067F1 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3750 000067F6 803E20              <1> 	cmp	byte [esi], 20h
  3751 000067F9 0F86D0EFFFFF        <1> 	jna	loc_cmd_failed
  3752 000067FF 8935[E0DD0000]      <1> 	mov	[DelFile_FNPointer], esi 
  3753                              <1> 
  3754                              <1> loc_attr_file_drv:
  3755 00006805 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  3756 0000680B 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  3757                              <1> 
  3758 00006811 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  3759 00006817 38F2                <1> 	cmp	dl, dh
  3760 00006819 740B                <1> 	je	short loc_attr_file_change_directory
  3761                              <1> 
  3762 0000681B E815E1FFFF          <1> 	call	change_current_drive
  3763 00006820 0F82D3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3764                              <1> 
  3765                              <1> loc_attr_file_change_directory:
  3766 00006826 803D[23DD0000]20    <1>         cmp     byte [FindFile_Directory], 20h
  3767 0000682D 7618                <1> 	jna	short loc_attr_file_find
  3768                              <1> 
  3769 0000682F FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3770                              <1> 	
  3771 00006835 BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  3772 0000683A 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3773 0000683C E886100000          <1> 	call	change_current_directory
  3774 00006841 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 00006847 8B35[E0DD0000]      <1> 	mov	esi, [DelFile_FNPointer]
  3782 0000684D 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3783 00006851 E87BF4FFFF          <1> 	call	find_first_file
  3784 00006856 0F829DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3785                              <1> 
  3786                              <1> loc_attr_file_ambgfn_check:
  3787 0000685C 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 0000685F 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 00006865 66833D[40C70000]00  <1> 	cmp	word [Attr_Chars], 0
  3803 0000686D 770B                <1> 	ja	short loc_attr_file_change_attributes
  3804 0000686F 881D[38DE0000]      <1> 	mov	[Attributes], bl
  3805 00006875 E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3806                              <1> 
  3807                              <1> loc_attr_file_change_attributes:
  3808 0000687A A0[40C70000]        <1> 	mov	al, [Attr_Chars]
  3809 0000687F F6D0                <1> 	not	al
  3810 00006881 20C3                <1> 	and	bl, al
  3811 00006883 A0[41C70000]        <1> 	mov	al, [Attr_Chars+1]
  3812 00006888 08C3                <1> 	or	bl, al
  3813                              <1> 
  3814 0000688A 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3815 00006890 741D                <1> 	je	short loc_attr_file_fs_check
  3816                              <1> 
  3817 00006892 881D[38DE0000]      <1> 	mov	[Attributes], bl
  3818 00006898 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 0000689B C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3826                              <1> 
  3827 000068A2 E8981A0000          <1> 	call 	save_directory_buffer
  3828 000068A7 0F824CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3829                              <1> 
  3830 000068AD EB33                <1> 	jmp	short loc_print_attr_changed_message
  3831                              <1> 
  3832                              <1> loc_attr_file_fs_check:
  3833 000068AF 29C0                <1> 	sub	eax, eax
  3834 000068B1 8A25[A6DB0000]      <1>         mov     ah, [DirBuff_DRV]
  3835 000068B7 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3836 000068BC 01C6                <1>         add     esi, eax
  3837 000068BE 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3838 000068C2 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3839 000068C4 66B80D00            <1> 	mov	ax, 0Dh ; Invalid Data
  3840 000068C8 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 000068CD 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3845 000068CF 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3846 000068D1 E89C050000          <1> 	call	change_fs_file_attributes
  3847 000068D6 0F821DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3848                              <1> 
  3849 000068DC 881D[38DE0000]      <1> 	mov	[Attributes], bl 
  3850                              <1> 
  3851                              <1> loc_print_attr_changed_message:
  3852 000068E2 BE[2EC70000]        <1> 	mov	esi, Msg_New
  3853 000068E7 E844D7FFFF          <1> 	call	print_msg
  3854 000068EC 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 000068F1 803E20              <1> 	cmp	byte [esi], 20h
  3865 000068F4 7614                <1>         jna	short loc_rename_nofilename_retn
  3866                              <1> 
  3867 000068F6 8935[5CDE0000]      <1> 	mov	[SourceFilePath], esi
  3868                              <1> 
  3869                              <1> rename_scan_source_file:
  3870 000068FC 46                  <1> 	inc	esi
  3871 000068FD 803E20              <1> 	cmp	byte [esi], 20h
  3872 00006900 7409                <1> 	je	short rename_scan_destination_file_1
  3873                              <1> 	;jb	short loc_rename_nofilename_retn
  3874 00006902 0F82C7EEFFFF        <1> 	jb	loc_cmd_failed
  3875 00006908 EBF2                <1> 	jmp	short rename_scan_source_file
  3876                              <1> 
  3877                              <1> loc_rename_nofilename_retn: ; 08/03/2016
  3878 0000690A C3                  <1> 	retn
  3879                              <1> 
  3880                              <1> rename_scan_destination_file_1:
  3881 0000690B C60600              <1> 	mov	byte [esi], 0
  3882                              <1> 
  3883                              <1> rename_scan_destination_file_2:
  3884 0000690E 46                  <1> 	inc	esi  
  3885 0000690F 803E20              <1> 	cmp	byte [esi], 20h
  3886 00006912 74FA                <1> 	je	short rename_scan_destination_file_2
  3887                              <1> 	;jb	short loc_rename_nofilename_retn
  3888 00006914 0F82B5EEFFFF        <1> 	jb	loc_cmd_failed
  3889                              <1> 
  3890 0000691A 8935[60DE0000]      <1> 	mov	[DestinationFilePath], esi
  3891                              <1> 
  3892                              <1> rename_scan_destination_file_3:
  3893 00006920 46                  <1> 	inc	esi  
  3894 00006921 803E20              <1> 	cmp	byte [esi], 20h
  3895 00006924 77FA                <1> 	ja	short rename_scan_destination_file_3
  3896                              <1> 
  3897 00006926 C60600              <1> 	mov	byte [esi], 0
  3898                              <1> 
  3899                              <1> loc_rename_save_current_drive:
  3900 00006929 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  3901 0000692F 8835[DEDB0000]      <1> 	mov	byte [RUN_CDRV], dh
  3902                              <1> 
  3903                              <1> loc_rename_sf_parse_path_name:
  3904 00006935 8B35[5CDE0000]      <1> 	mov	esi, [SourceFilePath] 
  3905 0000693B BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  3906 00006940 E896150000          <1> 	call	parse_path_name
  3907 00006945 0F8284EEFFFF        <1> 	jc	loc_cmd_failed
  3908                              <1> 
  3909                              <1> loc_rename_sf_check_filename_exists:
  3910 0000694B BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3911 00006950 803E20              <1> 	cmp	byte [esi], 20h
  3912 00006953 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 00006959 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  3921 0000695F 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  3922 00006961 740B                <1> 	je	short rename_sf_change_directory
  3923                              <1> 
  3924 00006963 E8CDDFFFFF          <1> 	call	change_current_drive
  3925 00006968 0F828BF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3926                              <1> 
  3927                              <1> rename_sf_change_directory:
  3928 0000696E 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3929 00006975 7618                <1> 	jna	short rename_sf_find
  3930                              <1> 
  3931 00006977 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3932 0000697D BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  3933 00006982 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3934 00006984 E83E0F0000          <1> 	call	change_current_directory
  3935 00006989 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 0000698F BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3943                              <1> 
  3944 00006994 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3945 00006998 E834F3FFFF          <1> 	call	find_first_file
  3946 0000699D 0F8256F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3947                              <1> 
  3948                              <1> loc_rename_sf_ambgfn_check:
  3949 000069A3 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 000069A6 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 000069AC F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  3965 000069AF 0F854EF7FFFF        <1> 	jnz	loc_permission_denied
  3966                              <1> 	
  3967 000069B5 BE[22DD0000]        <1>         mov     esi, FindFile_Drv
  3968 000069BA BF[64DE0000]        <1>         mov     edi, SourceFile_Drv
  3969 000069BF B920000000          <1> 	mov	ecx, 32
  3970 000069C4 F3A5                <1> 	rep	movsd
  3971                              <1> 
  3972                              <1> loc_rename_df_parse_path_name:
  3973 000069C6 8B35[60DE0000]      <1> 	mov	esi, [DestinationFilePath]
  3974 000069CC BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  3975 000069D1 E805150000          <1> 	call	parse_path_name
  3976 000069D6 7219                <1> 	jc	short loc_rename_df_cmd_failed
  3977                              <1> 
  3978                              <1> 	;mov	dh, [RUN_CDRV]
  3979 000069D8 8A35[7ED30000]      <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 000069DE 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  3985 000069E4 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  3986 000069E6 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  3987                              <1> 
  3988                              <1> rename_df_check_dirname_exists:
  3989 000069E8 803D[23DD0000]00    <1> 	cmp	byte [FindFile_Directory], 0
  3990 000069EF 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 000069F1 B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  3996 000069F6 F9                  <1> 	stc
  3997 000069F7 E9FDF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3998                              <1> 	  
  3999                              <1> rename_df_check_filename_exists:
  4000 000069FC BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  4001 00006A01 E883F6FFFF          <1> 	call	check_filename
  4002 00006A06 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 00006A0C 0FB6F6              <1> 	movzx	esi, dh
  4012                              <1> 	;movzx	esi, byte [Current_Drv]
  4013 00006A0F 81C600010900        <1> 	add	esi, Logical_DOSDisks
  4014                              <1> 
  4015 00006A15 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  4016 00006A17 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  4017                              <1> 
  4018 00006A1A 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  4019 00006A1D 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  4020                              <1> 
  4021 00006A1F B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected
  4022 00006A24 8B1D[60DE0000]      <1> 	mov	ebx, [DestinationFilePath] 
  4023 00006A2A E9CAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4024                              <1> 
  4025                              <1> rename_df_compare_sf_df_name:
  4026 00006A2F BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  4027 00006A34 BF[A6DE0000]        <1> 	mov	edi, SourceFile_Name
  4028 00006A39 B90C000000          <1> 	mov	ecx, 12
  4029                              <1> rename_df_compare_sf_df_name_next: 
  4030 00006A3E AC                  <1> 	lodsb
  4031 00006A3F AE                  <1> 	scasb
  4032 00006A40 7506                <1> 	jne	short loc_rename_df_find
  4033 00006A42 08C0                <1> 	or	al, al
  4034 00006A44 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  4035 00006A46 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 00006A48 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  4040                              <1> 
  4041 00006A4D 6631C0              <1> 	xor	ax, ax ; Any
  4042 00006A50 E87CF2FFFF          <1> 	call	find_first_file
  4043 00006A55 739A                <1> 	jnc	short loc_rename_df_found
  4044                              <1> 
  4045                              <1> loc_rename_df_check_error_code:
  4046                              <1> 	;cmp	eax, 2
  4047 00006A57 3C02                <1> 	cmp	al, 2 ; Not found error
  4048 00006A59 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  4049 00006A5B F9                  <1> 	stc
  4050 00006A5C 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 00006A61 BE[22DD0000]        <1>         mov     esi, FindFile_Drv
  4059 00006A66 BF[E4DE0000]        <1>         mov     edi, DestinationFile_Drv
  4060 00006A6B B920000000          <1> 	mov	ecx, 32
  4061 00006A70 F3A5                <1> 	rep	movsd
  4062                              <1> 
  4063                              <1> loc_rename_df_process_q_sf:
  4064                              <1> 	;mov	ecx, 12
  4065 00006A72 B10C                <1> 	mov	cl, 12
  4066 00006A74 BE[A6DE0000]        <1>  	mov	esi, SourceFile_Name
  4067 00006A79 BF[6FC70000]        <1> 	mov	edi, Rename_OldName
  4068                              <1> rename_df_process_q_nml_1_sf:
  4069 00006A7E AC                  <1> 	lodsb
  4070 00006A7F 3C20                <1>         cmp	al, 20h
  4071 00006A81 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4072 00006A83 AA                  <1> 	stosb
  4073 00006A84 E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4074                              <1> 
  4075                              <1> rename_df_process_q_nml_2_sf:
  4076 00006A86 C60700              <1> 	mov	byte [edi], 0
  4077                              <1> 
  4078                              <1> loc_rename_df_process_q_df:
  4079                              <1> 	;mov	ecx, 12
  4080 00006A89 B10C                <1> 	mov	cl, 12
  4081 00006A8B BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  4082 00006A90 BF[80C70000]        <1> 	mov	edi, Rename_NewName
  4083                              <1> rename_df_process_q_nml_1_df:
  4084 00006A95 AC                  <1> 	lodsb
  4085 00006A96 3C20                <1> 	cmp	al, 20h
  4086 00006A98 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4087 00006A9A AA                  <1> 	stosb
  4088 00006A9B E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4089                              <1> 
  4090                              <1> loc_rename_df_process_q_nml_2_df:
  4091 00006A9D C60700              <1> 	mov	byte [edi], 0
  4092                              <1> 
  4093                              <1> loc_rename_confirmation_question:
  4094 00006AA0 BE[47C70000]        <1> 	mov	esi, Msg_DoYouWantRename
  4095 00006AA5 E886D5FFFF          <1> 	call	print_msg
  4096                              <1> 
  4097 00006AAA A0[C1DE0000]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4098 00006AAF 2410                <1> 	and	al, 10h
  4099 00006AB1 750C                <1> 	jnz	short rename_confirmation_question_dir
  4100                              <1> 
  4101                              <1> rename_confirmation_question_file:
  4102 00006AB3 BE[5EC70000]        <1> 	mov	esi, Rename_File
  4103 00006AB8 E873D5FFFF          <1> 	call	print_msg 
  4104 00006ABD EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4105                              <1> 
  4106                              <1> rename_confirmation_question_dir:
  4107 00006ABF BE[64C70000]        <1> 	mov	esi, Rename_Directory
  4108 00006AC4 E867D5FFFF          <1> 	call	print_msg
  4109                              <1> 
  4110                              <1> rename_confirmation_question_as:
  4111 00006AC9 BE[6FC70000]        <1> 	mov	esi, Rename_OldName
  4112 00006ACE E85DD5FFFF          <1> 	call	print_msg
  4113 00006AD3 BE[7CC70000]        <1> 	mov	esi, Msg_File_rename_as
  4114 00006AD8 E853D5FFFF          <1> 	call	print_msg
  4115 00006ADD BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  4116 00006AE2 E849D5FFFF          <1> 	call	print_msg
  4117                              <1> 
  4118                              <1> loc_rename_ask_again:
  4119 00006AE7 30E4                <1> 	xor	ah, ah
  4120 00006AE9 E8C89FFFFF          <1> 	call	int16h
  4121 00006AEE 3C1B                <1> 	cmp	al, 1Bh
  4122 00006AF0 740F                <1> 	je	short loc_do_not_rename_file
  4123 00006AF2 24DF                <1> 	and	al, 0DFh
  4124 00006AF4 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  4125 00006AF9 3C59                <1> 	cmp	al, 'Y'
  4126 00006AFB 7404                <1> 	je	short loc_yes_rename_file
  4127 00006AFD 3C4E                <1> 	cmp	al, 'N'
  4128 00006AFF 75E6                <1> 	jne	short loc_rename_ask_again
  4129                              <1> 
  4130                              <1> loc_do_not_rename_file:
  4131                              <1> loc_yes_rename_file:
  4132 00006B01 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  4133 00006B06 6650                <1> 	push	ax
  4134 00006B08 BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  4135 00006B0D E81ED5FFFF          <1> 	call	print_msg
  4136 00006B12 6658                <1> 	pop	ax
  4137                              <1> 	;cmp	al, 'Y' ; 'yes'
  4138                              <1> 	;cmc
  4139                              <1>         ;jnc	loc_file_rw_restore_retn
  4140 00006B14 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4141 00006B16 0F84DDF5FFFF        <1>         je	loc_file_rw_restore_retn  
  4142                              <1> 
  4143 00006B1C BE[80C70000]        <1> 	mov	esi, Rename_NewName
  4144 00006B21 668B0D[DEDE0000]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4145 00006B28 66A1[CADE0000]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4146 00006B2E 66C1E010            <1> 	shl	ax, 16
  4147 00006B32 66A1[D0DE0000]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4148                              <1> 
  4149 00006B38 0FB61D[B3DE0000]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4150 00006B3F E8E11B0000          <1>    	call	rename_directory_entry
  4151 00006B44 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 00006B49 803E20              <1> 	cmp	byte [esi], 20h
  4168 00006B4C 7614                <1>         jna	short loc_move_nofilename_retn
  4169                              <1> 
  4170 00006B4E 8935[5CDE0000]      <1> 	mov	[SourceFilePath], esi
  4171                              <1> 
  4172                              <1> move_scan_source_file:
  4173 00006B54 46                  <1> 	inc	esi
  4174 00006B55 803E20              <1> 	cmp	byte [esi], 20h
  4175 00006B58 7409                <1>         je      short move_scan_destination_1
  4176                              <1> 	;jb	short loc_move_nofilename_retn
  4177 00006B5A 0F826FECFFFF        <1> 	jb	loc_cmd_failed
  4178 00006B60 EBF2                <1> 	jmp	short move_scan_source_file
  4179                              <1> 
  4180                              <1> loc_move_nofilename_retn:
  4181 00006B62 C3                  <1> 	retn
  4182                              <1> 
  4183                              <1> move_scan_destination_1:
  4184 00006B63 C60600              <1> 	mov	byte [esi], 0
  4185                              <1> 
  4186                              <1> move_scan_destination_2:
  4187 00006B66 46                  <1> 	inc	esi  
  4188 00006B67 803E20              <1> 	cmp	byte [esi], 20h
  4189 00006B6A 74FA                <1> 	je	short move_scan_destination_2
  4190                              <1> 	;jb	short loc_move_nofilename_retn
  4191 00006B6C 0F825DECFFFF        <1> 	jb	loc_cmd_failed
  4192                              <1> 
  4193 00006B72 8935[60DE0000]      <1> 	mov	[DestinationFilePath], esi
  4194                              <1> 
  4195                              <1> move_scan_destination_3:
  4196 00006B78 46                  <1> 	inc	esi  
  4197 00006B79 803E20              <1> 	cmp	byte [esi], 20h
  4198 00006B7C 77FA                <1> 	ja	short move_scan_destination_3
  4199 00006B7E C60600              <1> 	mov	byte [esi], 0
  4200                              <1> 
  4201                              <1> loc_move_scan_destination_OK:
  4202 00006B81 8B35[5CDE0000]      <1> 	mov	esi, [SourceFilePath]
  4203 00006B87 8B3D[60DE0000]      <1> 	mov	edi, [DestinationFilePath]
  4204                              <1> 
  4205 00006B8D B001                <1> 	mov	al, 1  ; move procedure Phase 1
  4206 00006B8F E80E1C0000          <1> 	call	move_source_file_to_destination_file
  4207 00006B94 7328                <1> 	jnc	short move_source_file_to_destination_question
  4208                              <1> 
  4209                              <1> loc_move_cmd_failed_1:
  4210 00006B96 08C0                <1> 	or	al, al
  4211 00006B98 0F8431ECFFFF        <1> 	jz	loc_cmd_failed 
  4212 00006B9E 3C11                <1> 	cmp	al, 11h
  4213 00006BA0 740D                <1> 	je	short loc_msg_not_same_device   
  4214 00006BA2 3C05                <1> 	cmp	al, 05h
  4215 00006BA4 0F8550ECFFFF        <1> 	jne	loc_run_cmd_failed
  4216                              <1> 
  4217 00006BAA 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 00006BAF BE[8DC70000]        <1> 	mov	esi, msg_not_same_drv 
  4225 00006BB4 E877D4FFFF          <1> 	call	print_msg
  4226 00006BB9 E93BF5FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4227                              <1> 
  4228                              <1> move_source_file_to_destination_question:
  4229 00006BBE A0[64DE0000]        <1>         mov     al, [SourceFile_Drv]
  4230 00006BC3 0441                <1> 	add	al, 'A'
  4231 00006BC5 A2[EFC70000]        <1> 	mov	[msg_source_file_drv], al
  4232 00006BCA A0[E4DE0000]        <1>         mov     al, [DestinationFile_Drv]
  4233 00006BCF 0441                <1> 	add	al, 'A'
  4234 00006BD1 A2[0EC80000]        <1> 	mov	[msg_destination_file_drv], al
  4235                              <1> 
  4236 00006BD6 57                  <1> 	push	edi ; *
  4237                              <1> 
  4238 00006BD7 BE[D3C70000]        <1> 	mov	esi, msg_source_file
  4239 00006BDC E84FD4FFFF          <1> 	call	print_msg
  4240 00006BE1 BE[65DE0000]        <1> 	mov	esi, SourceFile_Directory
  4241 00006BE6 803E20              <1> 	cmp	byte [esi], 20h
  4242 00006BE9 7605                <1> 	jna	short msftdfq_sfn
  4243 00006BEB E840D4FFFF          <1> 	call	print_msg
  4244                              <1> msftdfq_sfn:
  4245 00006BF0 BE[A6DE0000]        <1> 	mov	esi, SourceFile_Name
  4246 00006BF5 E836D4FFFF          <1> 	call	print_msg
  4247 00006BFA BE[F2C70000]        <1> 	mov	esi, msg_destination_file
  4248 00006BFF E82CD4FFFF          <1> 	call	print_msg
  4249 00006C04 BE[E5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  4250 00006C09 803E20              <1> 	cmp	byte [esi], 20h
  4251 00006C0C 7605                <1> 	jna	short msftdfq_dfn
  4252 00006C0E E81DD4FFFF          <1> 	call	print_msg
  4253                              <1> msftdfq_dfn:
  4254 00006C13 BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  4255 00006C18 E813D4FFFF          <1> 	call	print_msg
  4256 00006C1D BE[11C80000]        <1> 	mov	esi, msg_copy_nextline
  4257 00006C22 E809D4FFFF          <1> 	call	print_msg
  4258 00006C27 BE[11C80000]        <1> 	mov	esi, msg_copy_nextline
  4259 00006C2C E8FFD3FFFF          <1> 	call	print_msg
  4260                              <1> 
  4261                              <1> loc_move_ask_for_new_file_yes_no:
  4262 00006C31 BE[9FC70000]        <1> 	mov	esi, Msg_DoYouWantMoveFile
  4263 00006C36 E8F5D3FFFF          <1> 	call	print_msg
  4264 00006C3B BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  4265 00006C40 E8EBD3FFFF          <1> 	call	print_msg
  4266                              <1> loc_move_ask_for_new_file_again:
  4267 00006C45 30E4                <1> 	xor	ah, ah
  4268 00006C47 E86A9EFFFF          <1> 	call	int16h
  4269 00006C4C 3C1B                <1> 	cmp	al, 1Bh
  4270                              <1> 	;je	short loc_do_not_move_file
  4271 00006C4E 744F                <1> 	je	short loc_move_y_n_escape
  4272 00006C50 24DF                <1> 	and	al, 0DFh
  4273 00006C52 A2[ADC60000]        <1>         mov     [Y_N_nextline], al
  4274 00006C57 3C59                <1> 	cmp	al, 'Y'
  4275 00006C59 7404                <1> 	je	short loc_yes_move_file
  4276 00006C5B 3C4E                <1> 	cmp	al, 'N'
  4277 00006C5D 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 00006C5F A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  4282 00006C64 6650                <1> 	push	ax
  4283 00006C66 BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  4284 00006C6B E8C0D3FFFF          <1> 	call	print_msg
  4285 00006C70 6658                <1> 	pop	ax
  4286 00006C72 5F                  <1> 	pop	edi ; *
  4287                              <1> 	;cmp	al, 'Y' ; 'yes'
  4288                              <1> 	;cmc
  4289                              <1>         ;jnc	loc_file_rw_restore_retn
  4290 00006C73 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4291 00006C75 0F847EF4FFFF        <1>         je	loc_file_rw_restore_retn
  4292                              <1> 
  4293                              <1> loc_move_yes_move_file:
  4294 00006C7B B002                <1> 	mov	al, 2 ; move procedure Phase 2
  4295 00006C7D E8201B0000          <1> 	call	move_source_file_to_destination_file
  4296                              <1> 	;jc	short loc_move_cmd_failed_2
  4297 00006C82 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 00006C88 3C27                <1> 	cmp	al, 27h
  4306 00006C8A 0F856AEBFFFF        <1> 	jne	loc_run_cmd_failed
  4307                              <1> 
  4308 00006C90 BE[B8C70000]        <1> 	mov	esi, msg_insufficient_disk_space
  4309 00006C95 E896D3FFFF          <1> 	call	print_msg
  4310                              <1> 
  4311 00006C9A E95AF4FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4312                              <1> 
  4313                              <1> loc_move_y_n_escape:
  4314 00006C9F B04E                <1> 	mov	al, 'N' ; 'no'
  4315 00006CA1 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 00006CA3 803E20              <1> 	cmp	byte [esi], 20h
  4327 00006CA6 7614                <1>         jna     short loc_copy_nofilename_retn
  4328                              <1> 
  4329 00006CA8 8935[5CDE0000]      <1> 	mov	[SourceFilePath], esi
  4330                              <1> 
  4331                              <1> copy_scan_source_file:
  4332 00006CAE 46                  <1> 	inc	esi  
  4333 00006CAF 803E20              <1> 	cmp	byte [esi], 20h
  4334 00006CB2 7409                <1> 	je	short copy_scan_destination_1
  4335                              <1> 	;jb	short loc_copy_nofilename_retn
  4336 00006CB4 0F8215EBFFFF        <1> 	jb	loc_cmd_failed
  4337 00006CBA EBF2                <1> 	jmp	short copy_scan_source_file
  4338                              <1> 
  4339                              <1> loc_copy_nofilename_retn:
  4340 00006CBC C3                  <1> 	retn
  4341                              <1> 
  4342                              <1> copy_scan_destination_1:
  4343 00006CBD C60600              <1> 	mov	byte [esi], 0
  4344                              <1> 
  4345                              <1> copy_scan_destination_2:
  4346 00006CC0 46                  <1> 	inc	esi  
  4347 00006CC1 803E20              <1> 	cmp	byte [esi], 20h
  4348 00006CC4 74FA                <1> 	je	short copy_scan_destination_2
  4349                              <1> 	;jb	short loc_copy_nofilename_retn
  4350 00006CC6 0F8203EBFFFF        <1> 	jb	loc_cmd_failed
  4351                              <1> 
  4352 00006CCC 8935[60DE0000]      <1> 	mov	[DestinationFilePath], esi
  4353                              <1> 
  4354                              <1> copy_scan_destination_3:
  4355 00006CD2 46                  <1> 	inc	esi  
  4356 00006CD3 803E20              <1> 	cmp	byte [esi], 20h
  4357 00006CD6 77FA                <1> 	ja	short copy_scan_destination_3
  4358 00006CD8 C60600              <1> 	mov	byte [esi], 0
  4359                              <1> 
  4360                              <1> loc_copy_save_current_drive:
  4361 00006CDB 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  4362 00006CE1 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  4363                              <1> 
  4364                              <1> copy_source_file_to_destination_phase_1:
  4365 00006CE7 8B35[5CDE0000]      <1> 	mov	esi, [SourceFilePath]
  4366 00006CED 8B3D[60DE0000]      <1> 	mov	edi, [DestinationFilePath]
  4367                              <1> 
  4368 00006CF3 B001                <1> 	mov	al, 1  ; copy procedure Phase 1
  4369 00006CF5 E8331D0000          <1> 	call	copy_source_file_to_destination_file
  4370 00006CFA 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 00006CFC 08C0                <1> 	or	al, al
  4375 00006CFE 7507                <1> 	jnz	short loc_copy_cmd_failed_2
  4376                              <1> 
  4377 00006D00 FEC0                <1>         inc     al ; mov al, 1 ; Bad command or file name !
  4378 00006D02 E9F3EAFFFF          <1> 	jmp	loc_run_cmd_failed
  4379                              <1> 
  4380                              <1> loc_copy_cmd_failed_2:
  4381 00006D07 3C27                <1> 	cmp	al, 27h ; Insufficient disk space 
  4382 00006D09 740D                <1> 	je	short loc_file_write_insuff_disk_space_msg
  4383                              <1>  
  4384 00006D0B 3C05                <1> 	cmp	al, 05h
  4385 00006D0D 0F85E7EAFFFF        <1> 	jne	loc_run_cmd_failed
  4386                              <1> 	
  4387 00006D13 E9EBF3FFFF          <1> 	jmp	loc_permission_denied
  4388                              <1> 
  4389                              <1> loc_file_write_insuff_disk_space_msg:
  4390 00006D18 BE[B8C70000]        <1> 	mov	esi, msg_insufficient_disk_space
  4391 00006D1D E80ED3FFFF          <1> 	call	print_msg
  4392 00006D22 E9D2F3FFFF          <1>         jmp     loc_file_rw_restore_retn 
  4393                              <1> 
  4394                              <1> copy_source_file_to_destination_question:
  4395 00006D27 57                  <1> 	push	edi ; *
  4396                              <1> 
  4397                              <1> 	; dh = source file attributes
  4398                              <1> 	; dl > 0 -> destination file found
  4399 00006D28 20D2                <1> 	and	dl, dl            
  4400 00006D2A 7449                <1> 	jz	short copy_source_file_to_destination_pass_owrq
  4401                              <1> 
  4402                              <1> loc_copy_ask_for_owr_yes_no:
  4403 00006D2C BE[14C80000]        <1> 	mov	esi, Msg_DoYouWantOverWriteFile
  4404 00006D31 E8FAD2FFFF          <1> 	call	print_msg
  4405 00006D36 BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  4406 00006D3B E8F0D2FFFF          <1> 	call	print_msg
  4407 00006D40 BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  4408 00006D45 E8E6D2FFFF          <1> 	call	print_msg
  4409                              <1> 
  4410                              <1> loc_copy_ask_for_owr_again:
  4411 00006D4A 30E4                <1> 	xor	ah, ah
  4412 00006D4C E8659DFFFF          <1> 	call	int16h
  4413 00006D51 3C1B                <1> 	cmp	al, 1Bh
  4414                              <1>         ;je     loc_do_not_copy_file
  4415 00006D53 7419                <1>         je      short loc_copy_y_n_escape
  4416 00006D55 24DF                <1> 	and	al, 0DFh
  4417 00006D57 A2[ADC60000]        <1>         mov     [Y_N_nextline], al
  4418 00006D5C 3C59                <1> 	cmp	al, 'Y'
  4419 00006D5E 0F84B1000000        <1>         je      loc_yes_copy_file
  4420 00006D64 3C4E                <1> 	cmp	al, 'N'
  4421 00006D66 0F84A9000000        <1>         je      loc_do_not_copy_file
  4422 00006D6C EBDC                <1> 	jmp	short loc_copy_ask_for_owr_again
  4423                              <1> 
  4424                              <1> loc_copy_y_n_escape:
  4425 00006D6E B04E                <1> 	mov	al, 'N' ; 'no'
  4426 00006D70 E9A0000000          <1>         jmp     loc_do_not_copy_file
  4427                              <1> 
  4428                              <1> copy_source_file_to_destination_pass_owrq:
  4429 00006D75 A0[64DE0000]        <1> 	mov     al, [SourceFile_Drv]
  4430 00006D7A 0441                <1> 	add	al, 'A'
  4431 00006D7C A2[EFC70000]        <1> 	mov	[msg_source_file_drv], al
  4432 00006D81 A0[E4DE0000]        <1>         mov     al, [DestinationFile_Drv]
  4433 00006D86 0441                <1> 	add	al, 'A'
  4434 00006D88 A2[0EC80000]        <1> 	mov	[msg_destination_file_drv], al
  4435                              <1> 
  4436 00006D8D BE[D3C70000]        <1> 	mov	esi, msg_source_file
  4437 00006D92 E899D2FFFF          <1> 	call	print_msg
  4438 00006D97 BE[65DE0000]        <1> 	mov	esi, SourceFile_Directory
  4439 00006D9C 803E20              <1> 	cmp	byte [esi], 20h
  4440 00006D9F 7605                <1> 	jna	short csftdfq_sfn
  4441 00006DA1 E88AD2FFFF          <1> 	call	print_msg
  4442                              <1> csftdfq_sfn:
  4443 00006DA6 BE[A6DE0000]        <1> 	mov	esi, SourceFile_Name
  4444 00006DAB E880D2FFFF          <1> 	call	print_msg
  4445 00006DB0 BE[F2C70000]        <1> 	mov	esi, msg_destination_file
  4446 00006DB5 E876D2FFFF          <1> 	call	print_msg
  4447 00006DBA BE[E5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  4448 00006DBF 803E20              <1> 	cmp	byte [esi], 20h
  4449 00006DC2 7605                <1> 	jna	short csftdfq_dfn
  4450 00006DC4 E867D2FFFF          <1> 	call	print_msg
  4451                              <1> csftdfq_dfn:
  4452 00006DC9 BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  4453 00006DCE E85DD2FFFF          <1> 	call	print_msg
  4454 00006DD3 BE[11C80000]        <1> 	mov	esi, msg_copy_nextline
  4455 00006DD8 E853D2FFFF          <1> 	call	print_msg
  4456 00006DDD BE[11C80000]        <1> 	mov	esi, msg_copy_nextline
  4457 00006DE2 E849D2FFFF          <1> 	call	print_msg
  4458                              <1> 
  4459                              <1> loc_copy_ask_for_new_file_yes_no:
  4460 00006DE7 BE[33C80000]        <1> 	mov	esi, Msg_DoYouWantCopyFile
  4461 00006DEC E83FD2FFFF          <1> 	call	print_msg
  4462 00006DF1 BE[A3C60000]        <1> 	mov	esi, Msg_YesNo
  4463 00006DF6 E835D2FFFF          <1> 	call	print_msg
  4464                              <1> 
  4465                              <1> loc_copy_ask_for_new_file_again:
  4466 00006DFB 30E4                <1> 	xor	ah, ah
  4467 00006DFD E8B49CFFFF          <1> 	call	int16h
  4468 00006E02 3C1B                <1> 	cmp	al, 1Bh
  4469 00006E04 740F                <1> 	je	short loc_do_not_copy_file
  4470 00006E06 24DF                <1> 	and	al, 0DFh
  4471 00006E08 A2[ADC60000]        <1>         mov     [Y_N_nextline], al
  4472 00006E0D 3C59                <1> 	cmp	al, 'Y'
  4473 00006E0F 7404                <1> 	je	short loc_yes_copy_file
  4474 00006E11 3C4E                <1> 	cmp	al, 'N'
  4475 00006E13 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 00006E15 A2[ADC60000]        <1> 	mov	[Y_N_nextline], al
  4480 00006E1A 6650                <1> 	push	ax
  4481 00006E1C BE[ADC60000]        <1> 	mov	esi, Y_N_nextline
  4482 00006E21 E80AD2FFFF          <1> 	call	print_msg
  4483 00006E26 6658                <1> 	pop	ax
  4484 00006E28 5F                  <1> 	pop	edi ; *
  4485                              <1> 	;cmp	al, 'Y' ; 'yes'
  4486                              <1> 	;cmc
  4487                              <1>         ;jnc	loc_file_rw_restore_retn
  4488 00006E29 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4489 00006E2B 0F84C8F2FFFF        <1>         je	loc_file_rw_restore_retn
  4490                              <1> 
  4491                              <1> copy_source_file_to_destination_pass_q:
  4492 00006E31 B002                <1> 	mov	al, 2  ; copy procedure Phase 2
  4493 00006E33 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 00006E38 6651                <1> 	push	cx
  4498 00006E3A BE[11C80000]        <1> 	mov	esi, msg_copy_nextline
  4499 00006E3F E8ECD1FFFF          <1> 	call	print_msg
  4500                              <1> 	;pop	cx
  4501 00006E44 6658                <1> 	pop	ax
  4502                              <1> 
  4503                              <1> 	;or	cl, cl
  4504 00006E46 08C0                <1> 	or	al, al
  4505 00006E48 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 00006E4A 3C1D                <1> 	cmp	al, 1Dh
  4510 00006E4C 7506                <1> 	jne	short copy_source_file_to_destination_not_OK
  4511                              <1> 	;
  4512                              <1> 	;mov	al, cl ; error number (write fault!)
  4513 00006E4E F9                  <1> 	stc
  4514 00006E4F E9A5F2FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4515                              <1> 
  4516                              <1> copy_source_file_to_destination_not_OK:
  4517 00006E54 BE[4CC80000]        <1> 	mov	esi, Msg_read_file_error_before_EOF
  4518 00006E59 E8D2D1FFFF          <1> 	call	print_msg
  4519 00006E5E E996F2FFFF          <1> 	jmp	loc_file_rw_restore_retn	      
  4520                              <1>  
  4521                              <1> copy_source_file_to_destination_OK:
  4522 00006E63 BE[B1C60000]        <1> 	mov	esi, Msg_OK
  4523 00006E68 E8C3D1FFFF          <1> 	call	print_msg
  4524                              <1> 
  4525 00006E6D 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 00006E72 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 00006E73 8A06                <1> 	mov	al, [esi]
  4553 00006E75 3C20                <1> 	cmp	al, 20h
  4554 00006E77 771E                <1> 	ja	short loc_find_env
  4555                              <1> 
  4556 00006E79 BE00300900          <1> 	mov	esi, Env_Page
  4557                              <1> loc_print_setline:
  4558 00006E7E 803E00              <1> 	cmp	byte [esi], 0
  4559 00006E81 7613                <1> 	jna	short loc_setenv_retn
  4560 00006E83 E8A8D1FFFF          <1> 	call	print_msg
  4561 00006E88 56                  <1> 	push	esi
  4562 00006E89 BE[52CF0000]        <1> 	mov	esi, nextline
  4563 00006E8E E89DD1FFFF          <1> 	call	print_msg 
  4564 00006E93 5E                  <1> 	pop	esi
  4565 00006E94 EBE8                <1> 	jmp	short loc_print_setline   
  4566                              <1> 
  4567                              <1> loc_setenv_retn: 
  4568 00006E96 C3                  <1> 	retn
  4569                              <1> 
  4570                              <1> loc_find_env:
  4571 00006E97 3C3D                <1> 	cmp	al, '='
  4572 00006E99 0F8430E9FFFF        <1> 	je	loc_cmd_failed
  4573                              <1> 
  4574 00006E9F 56                  <1> 	push	esi
  4575                              <1> loc_repeat_env_equal_check:
  4576 00006EA0 46                  <1> 	inc	esi
  4577 00006EA1 803E3D              <1> 	cmp	byte [esi], '='
  4578 00006EA4 7431                <1> 	je	short pass_env_equal_check
  4579 00006EA6 803E20              <1> 	cmp	byte [esi], 20h
  4580 00006EA9 73F5                <1> 	jnb	short loc_repeat_env_equal_check
  4581 00006EAB C60600              <1> 	mov	byte [esi], 0 
  4582 00006EAE 5E                  <1> 	pop	esi
  4583 00006EAF BF[7ED40000]        <1> 	mov	edi, TextBuffer ; out buffer
  4584 00006EB4 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4585 00006EB9 30C0                <1> 	xor	al, al ; 0 -> use [ESI]
  4586 00006EBB E89E000000          <1> 	call	get_environment_string
  4587 00006EC0 72D4                <1> 	jc	short loc_setenv_retn
  4588                              <1> 
  4589 00006EC2 BE[7ED40000]        <1> 	mov	esi, TextBuffer
  4590 00006EC7 E864D1FFFF          <1> 	call	print_msg
  4591 00006ECC BE[52CF0000]        <1> 	mov	esi, nextline
  4592 00006ED1 E85AD1FFFF          <1> 	call	print_msg
  4593                              <1> 
  4594 00006ED6 C3                  <1> 	retn 
  4595                              <1>               
  4596                              <1> pass_env_equal_check:
  4597 00006ED7 46                  <1> 	inc	esi
  4598 00006ED8 803E20              <1> 	cmp	byte [esi], 20h
  4599 00006EDB 73FA                <1> 	jnb	short pass_env_equal_check
  4600 00006EDD C60600              <1> 	mov	byte [esi], 0	
  4601                              <1> 
  4602                              <1> loc_call_set_env_string:
  4603 00006EE0 5E                  <1> 	pop	esi
  4604 00006EE1 E83B010000          <1> 	call	set_environment_string
  4605 00006EE6 73AE                <1> 	jnc	short loc_setenv_retn
  4606                              <1> 
  4607                              <1> loc_set_cmd_failed:
  4608 00006EE8 3C08                <1> 	cmp	al, 08h
  4609 00006EEA 0F85DFE8FFFF        <1> 	jne	loc_cmd_failed
  4610                              <1> 
  4611 00006EF0 BE[8CC80000]        <1> 	mov	esi, Msg_No_Set_Space
  4612 00006EF5 E836D1FFFF          <1> 	call	print_msg
  4613                              <1> 
  4614 00006EFA 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 00006EFB 803E20              <1> 	cmp	byte [esi], 20h
  4623 00006EFE 7737                <1> 	ja	short loc_set_path
  4624                              <1> 
  4625 00006F00 BE00300900          <1> 	mov	esi, Env_Page
  4626                              <1> loc_print_path:
  4627 00006F05 803E00              <1> 	cmp	byte [esi], 0
  4628 00006F08 762C                <1> 	jna	short loc_path_retn
  4629                              <1> 
  4630 00006F0A BE[E5C20000]        <1> 	mov	esi, Cmd_Path ; 'PATH' address
  4631 00006F0F BF[7ED40000]        <1> 	mov	edi, TextBuffer ; oout buffer
  4632 00006F14 30C0                <1> 	xor	al, al  ; use [ESI]
  4633 00006F16 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4634 00006F1B E83E000000          <1> 	call	get_environment_string
  4635 00006F20 7214                <1> 	jc	short loc_path_retn
  4636                              <1> 
  4637 00006F22 BE[7ED40000]        <1> 	mov	esi, TextBuffer
  4638 00006F27 E804D1FFFF          <1> 	call	print_msg
  4639 00006F2C BE[52CF0000]        <1> 	mov	esi, nextline
  4640 00006F31 E8FAD0FFFF          <1> 	call	print_msg   
  4641                              <1> 
  4642                              <1> loc_path_retn: 
  4643 00006F36 C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> loc_set_path:
  4646 00006F37 56                  <1> 	push	esi 
  4647                              <1> loc_set_path_find_end:
  4648 00006F38 46                  <1> 	inc	esi
  4649 00006F39 803E20              <1> 	cmp	byte [esi], 20h
  4650 00006F3C 73FA                <1> 	jnb	short loc_set_path_find_end
  4651 00006F3E C60600              <1> 	mov	byte [esi], 0 
  4652                              <1> loc_set_path_header: 
  4653 00006F41 5E                  <1> 	pop	esi	  
  4654 00006F42 4E                  <1> 	dec	esi
  4655 00006F43 C6063D              <1> 	mov	byte [esi], '='
  4656 00006F46 4E                  <1> 	dec	esi
  4657 00006F47 C60648              <1> 	mov	byte [esi], 'H'
  4658 00006F4A 4E                  <1> 	dec	esi
  4659 00006F4B C60654              <1> 	mov	byte [esi], 'T'
  4660 00006F4E 4E                  <1> 	dec	esi
  4661 00006F4F C60641              <1> 	mov	byte [esi], 'A'
  4662 00006F52 4E                  <1> 	dec	esi
  4663 00006F53 C60650              <1> 	mov	byte [esi], 'P'   
  4664                              <1> 
  4665                              <1> loc_path_call_set_env_string:
  4666 00006F56 E8C6000000          <1> 	call	set_environment_string
  4667 00006F5B 728B                <1>         jc	short loc_set_cmd_failed
  4668                              <1> 
  4669 00006F5D 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 00006F5E BA00300900          <1> 	mov	edx, Env_Page
  4694 00006F63 803A00              <1> 	cmp	byte [edx], 0
  4695 00006F66 7474                <1> 	jz	short get_env_string_with_word_stc_retn
  4696                              <1> 
  4697 00006F68 66890D[E8DF0000]    <1> 	mov	[env_var_length], cx
  4698                              <1> 
  4699 00006F6F 51                  <1> 	push	ecx ; *
  4700 00006F70 56                  <1> 	push	esi ; **
  4701                              <1> 
  4702 00006F71 08C0                <1> 	or	al, al
  4703 00006F73 7449                <1> 	jz	short get_env_string_with_word
  4704                              <1> 
  4705                              <1> get_env_string_with_seq_number:
  4706 00006F75 B101                <1> 	mov	cl, 1
  4707 00006F77 88C5                <1> 	mov	ch, al
  4708 00006F79 31C0                <1> 	xor	eax, eax
  4709 00006F7B 89D6                <1> 	mov	esi, edx ; Env_Page
  4710                              <1> 
  4711                              <1> get_env_string_seq_number_check:
  4712 00006F7D 38CD                <1> 	cmp	ch, cl
  4713 00006F7F 7726                <1> 	ja	short get_env_string_seq_number_next
  4714                              <1> 
  4715                              <1> get_env_string_move_to_buff:
  4716 00006F81 57                  <1> 	push	edi ; ***
  4717                              <1> 
  4718 00006F82 29D2                <1> 	sub	edx, edx
  4719                              <1> 
  4720                              <1> get_env_string_seq_number_repeat1:
  4721 00006F84 42                  <1> 	inc	edx
  4722 00006F85 AC                  <1> 	lodsb
  4723 00006F86 AA                  <1> 	stosb
  4724                              <1> 
  4725 00006F87 66FF0D[E8DF0000]    <1> 	dec	word [env_var_length]
  4726 00006F8E 7508                <1> 	jnz	short get_env_string_seq_number_repeat3
  4727                              <1> 
  4728                              <1> get_env_string_seq_number_repeat2:
  4729 00006F90 20C0                <1> 	and	al, al
  4730 00006F92 7408                <1> 	jz	short get_env_string_seq_number_ok
  4731 00006F94 42                  <1> 	inc	edx
  4732 00006F95 AC                  <1> 	lodsb
  4733 00006F96 EBF8                <1> 	jmp	short get_env_string_seq_number_repeat2
  4734                              <1> 
  4735                              <1> get_env_string_seq_number_repeat3:
  4736 00006F98 08C0                <1> 	or	al, al
  4737 00006F9A 75E8                <1> 	jnz	short get_env_string_seq_number_repeat1
  4738                              <1> 
  4739                              <1> get_env_string_seq_number_ok:
  4740 00006F9C 5F                  <1> 	pop	edi ; ***
  4741 00006F9D 89D0                <1> 	mov	eax, edx ; Length of the environment string
  4742                              <1> 			 ; (ASCIIZ, includes ZERO tail)
  4743 00006F9F BA00300900          <1> 	mov	edx, Env_Page
  4744                              <1> 
  4745                              <1> get_env_string_stc_retn:
  4746 00006FA4 5E                  <1> 	pop	esi ; **
  4747 00006FA5 59                  <1> 	pop	ecx ; *
  4748 00006FA6 C3                  <1> 	retn   
  4749                              <1> 	
  4750                              <1> get_env_string_seq_number_next:
  4751 00006FA7 AC                  <1> 	lodsb
  4752 00006FA8 08C0                <1> 	or	al, al
  4753 00006FAA 75FB                <1> 	jnz	short get_env_string_seq_number_next
  4754                              <1> 
  4755 00006FAC 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; +512 (+4096)
  4756 00006FB2 F5                  <1> 	cmc
  4757 00006FB3 72EF                <1> 	jc	short get_env_string_stc_retn
  4758                              <1> 
  4759 00006FB5 AC                  <1> 	lodsb
  4760 00006FB6 3C01                <1> 	cmp	al, 1
  4761 00006FB8 72EA                <1> 	jb	short get_env_string_stc_retn
  4762 00006FBA FEC1                <1> 	inc	cl
  4763 00006FBC EBBF                <1> 	jmp	short get_env_string_seq_number_check
  4764                              <1> 
  4765                              <1> get_env_string_with_word:
  4766 00006FBE 31C9                <1> 	xor	ecx, ecx
  4767                              <1> 
  4768                              <1> get_env_string_calc_word_length:
  4769 00006FC0 AC                  <1> 	lodsb 
  4770 00006FC1 3C20                <1> 	cmp	al, 20h
  4771 00006FC3 7211                <1> 	jb	short get_env_string_calc_word_length_ok
  4772                              <1> 	;inc	cx
  4773 00006FC5 FEC1                <1> 	inc	cl
  4774                              <1> 
  4775 00006FC7 3C61                <1> 	cmp	al, 'a'
  4776 00006FC9 72F5                <1> 	jb	short get_env_string_calc_word_length
  4777 00006FCB 3C7A                <1> 	cmp	al, 'z'
  4778 00006FCD 77F1                <1> 	ja	short get_env_string_calc_word_length
  4779 00006FCF 24DF                <1> 	and	al, 0DFh
  4780 00006FD1 8846FF              <1> 	mov	[esi-1], al
  4781 00006FD4 EBEA                <1> 	jmp	short get_env_string_calc_word_length
  4782                              <1> 	
  4783                              <1> get_env_string_calc_word_length_ok:
  4784 00006FD6 08C9                <1> 	or	cl, cl
  4785 00006FD8 7506                <1> 	jnz	short get_env_string_calc_word_length_save
  4786                              <1>      
  4787 00006FDA 5E                  <1> 	pop	esi ; **
  4788                              <1> 
  4789                              <1> get_env_string_stc_retn1:
  4790 00006FDB 59                  <1> 	pop	ecx ; *
  4791                              <1>         
  4792                              <1> get_env_string_with_word_stc_retn:
  4793 00006FDC 31C0                <1> 	xor	eax, eax  
  4794 00006FDE F9                  <1> 	stc
  4795 00006FDF C3                  <1> 	retn
  4796                              <1>   
  4797                              <1> get_env_string_calc_word_length_save:
  4798 00006FE0 871C24              <1> 	xchg	ebx, [esp] ; **
  4799 00006FE3 89DE                <1> 	mov	esi, ebx 
  4800                              <1> 		; Start of the env string (to be searched)
  4801                              <1> 
  4802 00006FE5 57                  <1> 	push	edi ; ***
  4803 00006FE6 89D7                <1> 	mov	edi, edx ; Env_Page
  4804                              <1> 
  4805                              <1> get_env_string_compare:
  4806 00006FE8 57                  <1> 	push	edi ; ****
  4807 00006FE9 51                  <1> 	push	ecx ; ***** ; Variable name length
  4808                              <1> 
  4809                              <1> get_env_string_compare_rep:
  4810 00006FEA AC                  <1> 	lodsb
  4811 00006FEB AE                  <1> 	scasb
  4812 00006FEC 7511                <1> 	jne	short get_env_string_compare_next1
  4813 00006FEE E2FA                <1> 	loop	get_env_string_compare_rep
  4814                              <1> 	
  4815 00006FF0 803F3D              <1> 	cmp	byte [edi], '='
  4816 00006FF3 750A                <1> 	jne	short get_env_string_compare_next1
  4817                              <1>  
  4818 00006FF5 59                  <1> 	pop	ecx ; *****
  4819 00006FF6 5F                  <1> 	pop	edi ; ****
  4820 00006FF7 89FE                <1> 	mov	esi, edi
  4821 00006FF9 5F                  <1> 	pop	edi ; ***
  4822 00006FFA 871C24              <1> 	xchg	ebx, [esp] ; **
  4823 00006FFD EB82                <1> 	jmp	short get_env_string_move_to_buff
  4824                              <1> 
  4825                              <1> get_env_string_compare_next1:
  4826 00006FFF 89FE                <1> 	mov	esi, edi
  4827 00007001 59                  <1> 	pop	ecx ; *****
  4828 00007002 5F                  <1> 	pop	edi ; ****
  4829                              <1> get_env_string_compare_next2:
  4830 00007003 81FEFF310900        <1> 	cmp	esi, Env_Page + Env_Page_Size - 1 ; +511 (+4095)
  4831 00007009 7310                <1> 	jnb	short get_env_string_compare_not_ok
  4832 0000700B 20C0                <1> 	and	al, al
  4833 0000700D AC                  <1> 	lodsb
  4834 0000700E 75F3                <1> 	jnz	short get_env_string_compare_next2
  4835 00007010 08C0                <1> 	or	al, al
  4836 00007012 7407                <1> 	jz	short get_env_string_compare_not_ok
  4837 00007014 4E                  <1> 	dec	esi ; 12/04/2016
  4838 00007015 89F7                <1> 	mov	edi, esi
  4839 00007017 89DE                <1> 	mov	esi, ebx
  4840 00007019 EBCD                <1> 	jmp	short get_env_string_compare
  4841                              <1> 
  4842                              <1> get_env_string_compare_not_ok:
  4843 0000701B 5F                  <1> 	pop	edi ; ***
  4844 0000701C 89DE                <1> 	mov	esi, ebx
  4845 0000701E 5B                  <1> 	pop	ebx ; **
  4846 0000701F 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 00007021 56                  <1> 	push 	esi ; *
  4870                              <1> 
  4871 00007022 31C0                <1> 	xor	eax, eax
  4872                              <1> 
  4873                              <1> set_env_chk_validation1:
  4874 00007024 FEC4                <1> 	inc	ah ; variable (string) length
  4875 00007026 AC                  <1> 	lodsb
  4876 00007027 3C3D                <1> 	cmp	al, '='
  4877 00007029 7415                <1> 	je	short set_env_chk_validation2
  4878 0000702B 3C20                <1> 	cmp	al, 20h
  4879 0000702D 720F                <1> 	jb	short set_env_string_stc
  4880                              <1> 
  4881                              <1> 	; 06/04/2016
  4882 0000702F 3C61                <1> 	cmp	al, 'a'
  4883 00007031 72F1                <1> 	jb	short set_env_chk_validation1
  4884 00007033 3C7A                <1> 	cmp	al, 'z'
  4885 00007035 77ED                <1> 	ja	short set_env_chk_validation1
  4886 00007037 2C20                <1> 	sub	al, 'a'-'A'
  4887 00007039 8846FF              <1> 	mov	[esi-1], al
  4888 0000703C EBE6                <1> 	jmp	short set_env_chk_validation1
  4889                              <1> 
  4890                              <1> set_env_string_stc:
  4891 0000703E 5E                  <1> 	pop	esi ; *
  4892                              <1> 	;stc
  4893 0000703F C3                  <1> 	retn 
  4894                              <1> 	   
  4895                              <1> set_env_chk_validation2:
  4896 00007040 51                  <1> 	push	ecx ; **
  4897 00007041 53                  <1> 	push	ebx ; *** 
  4898 00007042 57                  <1> 	push	edi ; ****
  4899                              <1> 
  4900                              <1> 	; 12/04/2016
  4901 00007043 8B5C240C            <1> 	mov	ebx, [esp+12]
  4902                              <1> 
  4903                              <1> set_env_chk_validation2w:
  4904 00007047 89F7                <1> 	mov	edi, esi
  4905 00007049 4F                  <1> 	dec	edi
  4906                              <1> 
  4907 0000704A 807FFF20            <1> 	cmp	byte [edi-1], 20h
  4908 0000704E 771A                <1> 	ja	short set_env_chk_validation2z
  4909                              <1> 	
  4910 00007050 56                  <1> 	push	esi
  4911 00007051 89FE                <1> 	mov	esi, edi
  4912 00007053 4E                  <1> 	dec	esi
  4913                              <1> 
  4914                              <1> set_env_chk_validation2x:
  4915 00007054 4E                  <1> 	dec	esi
  4916                              <1> 
  4917 00007055 39DE                <1> 	cmp	esi, ebx
  4918 00007057 7207                <1> 	jb	short set_env_chk_validation2y
  4919                              <1> 
  4920 00007059 4F                  <1> 	dec	edi
  4921                              <1> 
  4922 0000705A 8A06                <1> 	mov	al, [esi]
  4923 0000705C 8807                <1> 	mov	[edi], al
  4924                              <1> 
  4925 0000705E EBF4                <1> 	jmp	short set_env_chk_validation2x
  4926                              <1> 
  4927                              <1> set_env_chk_validation2y:
  4928 00007060 5E                  <1> 	pop	esi
  4929                              <1> 
  4930                              <1> 	;mov	byte [ebx], 20h
  4931                              <1> 	
  4932 00007061 43                  <1> 	inc 	ebx
  4933 00007062 895C240C            <1> 	mov	[esp+12], ebx
  4934                              <1> 
  4935 00007066 FECC                <1> 	dec 	ah ; 13/04/2016
  4936                              <1> 
  4937 00007068 EBDD                <1> 	jmp	short set_env_chk_validation2w
  4938                              <1> 	
  4939                              <1> set_env_chk_validation2z:	
  4940 0000706A BA00300900          <1> 	mov	edx, Env_Page
  4941 0000706F 89D7                <1> 	mov	edi, edx
  4942                              <1> 
  4943                              <1> set_env_chk_validation3:
  4944 00007071 AC                  <1> 	lodsb
  4945 00007072 3C20                <1> 	cmp	al, 20h
  4946 00007074 74FB                <1> 	je	short set_env_chk_validation3
  4947                              <1> 
  4948 00007076 9C                  <1> 	pushf
  4949                              <1> 
  4950                              <1> 	; 12/04/2016
  4951                              <1> set_env_chk_validation3n:
  4952 00007077 3C61                <1> 	cmp	al, 'a'
  4953 00007079 720C                <1> 	jb	short set_env_chk_validation3c
  4954 0000707B 3C7A                <1> 	cmp	al, 'z'
  4955 0000707D 7705                <1> 	ja	short set_env_chk_validation3x
  4956 0000707F 2C20                <1> 	sub	al, 'a'-'A'
  4957 00007081 8846FF              <1> 	mov	[esi-1], al
  4958                              <1> 
  4959                              <1> set_env_chk_validation3x:
  4960 00007084 AC                  <1> 	lodsb
  4961 00007085 EBF0                <1> 	jmp	short set_env_chk_validation3n
  4962                              <1> 
  4963                              <1> set_env_chk_validation3c:
  4964 00007087 3C20                <1> 	cmp	al, 20h
  4965 00007089 73F9                <1> 	jnb	short set_env_chk_validation3x
  4966                              <1> 		
  4967 0000708B 803F00              <1> 	cmp	byte [edi], 0
  4968 0000708E 7731                <1> 	ja	short set_env_chk_validation4
  4969                              <1> 
  4970 00007090 9D                  <1> 	popf
  4971 00007091 7228                <1> 	jb	short set_env_string_nothing
  4972                              <1> 
  4973 00007093 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)
  4974                              <1> 
  4975 00007098 89DE                <1> 	mov	esi, ebx ; 12/04/2016
  4976                              <1> 
  4977                              <1> set_env_string_copy_to_envb:
  4978 0000709A AC                  <1> 	lodsb
  4979 0000709B 3C20                <1> 	cmp	al, 20h
  4980 0000709D 720A                <1> 	jb	short set_env_string_copy_to_envb_z
  4981 0000709F AA                  <1> 	stosb
  4982 000070A0 E2F8                <1> 	loop	set_env_string_copy_to_envb
  4983                              <1> 
  4984                              <1> 	; 11/04/2016
  4985 000070A2 89D7                <1> 	mov	edi, edx ; Env_Page
  4986 000070A4 B900020000          <1> 	mov	ecx, Env_Page_Size 
  4987                              <1> 
  4988                              <1> set_env_string_copy_to_envb_z:
  4989 000070A9 52                  <1> 	push	edx  ; Start address of the variable
  4990 000070AA BA00020000          <1> 	mov	edx, Env_Page_Size
  4991 000070AF 29CA                <1> 	sub	edx, ecx ; variable (string) length
  4992                              <1> 
  4993 000070B1 28C0                <1> 	sub	al, al ; 0
  4994 000070B3 F3AA                <1>  	rep	stosb ; clear remain bytes of the env page
  4995                              <1> 
  4996 000070B5 58                  <1> 	pop	eax  ; Start address of the variable
  4997                              <1> 
  4998                              <1> set_env_string_allocate_envb_retn:  ; stc or clc return
  4999 000070B6 5F                  <1> 	pop	edi ; ****
  5000 000070B7 5B                  <1> 	pop	ebx ; ***
  5001 000070B8 59                  <1> 	pop	ecx ; **
  5002 000070B9 5E                  <1> 	pop	esi ; *	
  5003 000070BA C3                  <1> 	retn
  5004                              <1> 
  5005                              <1> set_env_string_nothing:
  5006 000070BB 31C0                <1> 	xor	eax, eax
  5007 000070BD 31D2                <1> 	xor	edx, edx ; 11/04/2016
  5008 000070BF EBF5                <1> 	jmp	short set_env_string_allocate_envb_retn
  5009                              <1> 
  5010                              <1> set_env_chk_validation4:
  5011                              <1> 	; 11/04/2016
  5012 000070C1 9D                  <1> 	popf
  5013                              <1> 
  5014 000070C2 89D6                <1> 	mov	esi, edx  ; Env_Page
  5015                              <1> 
  5016                              <1> set_env_chk_validation5:	
  5017 000070C4 89DF                <1> 	mov	edi, ebx  ; ASCIIZ environment string address	
  5018 000070C6 0FB6CC              <1> 	movzx	ecx, ah ; Variable (string) length (with '=')
  5019                              <1> 
  5020                              <1> set_env_chk_validation5_loop:
  5021 000070C9 AC                  <1> 	lodsb
  5022 000070CA AE                  <1> 	scasb
  5023 000070CB 750A                <1> 	jne	short set_env_chk_validation6
  5024 000070CD E2FA                <1> 	loop	set_env_chk_validation5_loop
  5025                              <1> 
  5026 000070CF 3C3D                <1> 	cmp	al, '='
  5027 000070D1 0F8483000000        <1>         je      set_env_change_variable
  5028                              <1> 
  5029                              <1> set_env_chk_validation6:
  5030 000070D7 08C0                <1> 	or	al, al ; 0
  5031 000070D9 7403                <1> 	jz	short set_env_chk_validation7
  5032                              <1> 
  5033 000070DB AC                  <1> 	lodsb
  5034 000070DC EBF9                <1> 	jmp	short set_env_chk_validation6
  5035                              <1> 
  5036                              <1> set_env_chk_validation7:
  5037 000070DE 88E1                <1> 	mov	cl, ah
  5038 000070E0 01F1                <1> 	add	ecx, esi
  5039 000070E2 81F9FF310900        <1> 	cmp	ecx, Env_Page + Env_Page_Size - 1 
  5040                              <1> 		; 511 (4095) 
  5041                              <1> 		; strlen + '=' + 0
  5042 000070E8 72DA                <1> 	jb	short set_env_chk_validation5
  5043                              <1> 
  5044                              <1> set_env_chk_validation8: ; variable not found
  5045 000070EA 0FB6F4              <1> 	movzx	esi, ah  ; variable name length (with '=') 
  5046 000070ED 01DE                <1> 	add	esi, ebx ; position just after of the '='
  5047                              <1> 
  5048                              <1> set_env_chk_validation8_loop:
  5049 000070EF AC                  <1> 	lodsb
  5050 000070F0 3C20                <1> 	cmp	al, 20h
  5051 000070F2 74FB                <1> 	je	short set_env_chk_validation8_loop	
  5052 000070F4 72C5                <1> 	jb	short set_env_string_nothing
  5053                              <1> 
  5054                              <1> set_env_chk_validation9:
  5055 000070F6 AC                  <1> 	lodsb
  5056 000070F7 3C20                <1> 	cmp	al, 20h
  5057 000070F9 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 000070FB 29DE                <1> 	sub	esi, ebx ; variable+definition length
  5063                              <1> 	
  5064 000070FD 56                  <1> 	push	esi ; *****
  5065                              <1> 
  5066 000070FE 89D6                <1> 	mov	esi, edx ; Environment page address
  5067                              <1> 
  5068 00007100 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)	
  5069                              <1> 
  5070                              <1> set_env_add_variable_loop:
  5071 00007105 AC                  <1> 	lodsb
  5072 00007106 20C0                <1> 	and	al, al		
  5073 00007108 7406                <1> 	jz	short set_env_add_variable_chk1 ; 0
  5074 0000710A E2F9                <1> 	loop	set_env_add_variable_loop
  5075                              <1> 
  5076                              <1> 	; 11/04/2016
  5077 0000710C 884EFF              <1> 	mov	[esi-1], cl ; 0
  5078 0000710F 41                  <1> 	inc	ecx
  5079                              <1> 	
  5080                              <1> set_env_add_variable_chk1: 
  5081 00007110 49                  <1> 	dec	ecx
  5082 00007111 7408                <1> 	jz	short set_env_add_variable_nspc
  5083 00007113 AC                  <1> 	lodsb
  5084 00007114 08C0                <1> 	or 	al, al
  5085 00007116 740C                <1> 	jz	short set_env_add_variable_chk2 ; 00
  5086 00007118 49                  <1> 	dec	ecx
  5087 00007119 75EA                <1> 	jnz	short set_env_add_variable_loop
  5088                              <1> 
  5089                              <1> set_env_add_variable_nspc: ; no space on environment page
  5090 0000711B 58                  <1> 	pop	eax ; *****
  5091 0000711C B808000000          <1> 	mov	eax, 08h ; No space for new environment string
  5092 00007121 F9                  <1> 	stc
  5093 00007122 EB92                <1>         jmp     short set_env_string_allocate_envb_retn
  5094                              <1> 
  5095                              <1> set_env_add_variable_chk2:
  5096 00007124 8B0C24              <1> 	mov	ecx, [esp] ; *****
  5097 00007127 4E                  <1> 	dec	esi ; beginning address of the new variable
  5098 00007128 89F0                <1> 	mov	eax, esi
  5099 0000712A 01C8                <1> 	add	eax, ecx ; string length (with CR)
  5100 0000712C 81C200020000        <1> 	add	edx, Env_Page_Size ; 512 (4096)
  5101 00007132 39D0                <1> 	cmp	eax, edx 
  5102 00007134 77E5                <1> 	ja	short set_env_add_variable_nspc
  5103 00007136 49                  <1> 	dec	ecx ; except CR at the end
  5104 00007137 89CA                <1> 	mov	edx, ecx ; 12/04/2016
  5105 00007139 89F7                <1> 	mov	edi, esi
  5106 0000713B 893C24              <1> 	mov	[esp], edi ; ***** ; Start address of new variable
  5107 0000713E 89DE                <1> 	mov	esi, ebx ; ASCIIZ environment string address
  5108 00007140 F3A4                <1> 	rep	movsb
  5109 00007142 28C0                <1> 	sub	al, al
  5110 00007144 AA                  <1> 	stosb
  5111 00007145 58                  <1> 	pop	eax ; ***** ; Beginning address of new variable			
  5112 00007146 81FF00320900        <1>         cmp     edi, Env_Page + Env_Page_Size ; 12/04/2016
  5113 0000714C 0F8364FFFFFF        <1>         jnb     set_env_string_allocate_envb_retn ; OK !
  5114 00007152 880F                <1> 	mov	[edi], cl ; 0
  5115 00007154 F8                  <1> 	clc	; 13/04/2016
  5116 00007155 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 0000715A 8825[E8DF0000]      <1> 	mov	[env_var_length], ah
  5125                              <1> 
  5126 00007160 28C9                <1> 	sub	cl, cl ; ecx = 0
  5127                              <1> 
  5128 00007162 57                  <1> 	push	edi ; *****
  5129                              <1> 
  5130 00007163 89F7                <1> 	mov	edi, esi ; 11/04/2016
  5131                              <1> 
  5132                              <1> set_env_change_variable_calc1:
  5133 00007165 AC                  <1> 	lodsb
  5134 00007166 08C0                <1> 	or	al, al
  5135 00007168 7403                <1> 	jz	short set_env_change_variable_calc2
  5136                              <1> 
  5137 0000716A 41                  <1> 	inc	ecx ; length of environment string (after the '=')
  5138                              <1> 
  5139 0000716B EBF8                <1> 	jmp	short set_env_change_variable_calc1	
  5140                              <1> 
  5141                              <1> set_env_change_variable_calc2:
  5142 0000716D 8B3424              <1> 	mov	esi, [esp] ; ASCIIZ environment string address
  5143                              <1> 	
  5144 00007170 29D2                <1> 	sub	edx, edx
  5145                              <1> 
  5146                              <1> set_env_change_variable_calc3:
  5147 00007172 AC                  <1> 	lodsb
  5148 00007173 3C20                <1> 	cmp	al, 20h
  5149 00007175 7203                <1> 	jb	short set_env_change_variable_calc4
  5150                              <1> 
  5151 00007177 42                  <1> 	inc	edx ; length of ASCIIZ string (after the '=')
  5152                              <1> 	
  5153 00007178 EBF8                <1> 	jmp	short set_env_change_variable_calc3
  5154                              <1> 	
  5155                              <1> set_env_change_variable_calc4:
  5156 0000717A C646FF00            <1> 	mov	byte [esi-1], 0  ; put ZERO instead of CR
  5157                              <1> 	
  5158 0000717E 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 0000717F 39CA                <1> 	cmp	edx, ecx
  5164 00007181 7717                <1> 	ja	short set_env_change_variable_calc5 ; longer
  5165 00007183 0F828F000000        <1>         jb      set_env_change_variable_calc9 ; shorter
  5166                              <1> 	
  5167                              <1> 	;same length (simple copy)
  5168 00007189 0FB6C4              <1> 	movzx	eax, ah
  5169 0000718C 01C2                <1> 	add	edx, eax
  5170 0000718E F7D8                <1> 	neg	eax
  5171 00007190 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 00007192 F3A4                <1> 	rep	movsb
  5176 00007194 F8                  <1> 	clc	; 13/04/2016
  5177 00007195 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 0000719A 52                  <1> 	push	edx ; *****
  5182 0000719B 29CA                <1> 	sub	edx, ecx ; difference ; (the new string is longer)
  5183 0000719D 89F3                <1> 	mov 	ebx, esi
  5184 0000719F 89FE                <1> 	mov	esi, edi
  5185                              <1> 
  5186                              <1> set_env_change_variable_calc6:
  5187 000071A1 AC                  <1> 	lodsb 
  5188 000071A2 20C0                <1> 	and	al, al
  5189 000071A4 75FB                <1> 	jnz	short set_env_change_variable_calc6
  5190                              <1> 
  5191 000071A6 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5192 000071AC 0F8369FFFFFF        <1>         jnb     set_env_add_variable_nspc
  5193                              <1> 
  5194 000071B2 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5195 000071B4 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5196                              <1> 
  5197 000071B6 AC                  <1> 	lodsb
  5198 000071B7 08C0                <1> 	or	al, al
  5199 000071B9 7416                <1> 	jz	short set_env_change_variable_calc8 ; 00
  5200                              <1> 
  5201                              <1> set_env_change_variable_calc7:
  5202 000071BB AC                  <1> 	lodsb
  5203 000071BC 20C0                <1> 	and	al, al
  5204 000071BE 75FB                <1> 	jnz	short set_env_change_variable_calc7
  5205                              <1> 
  5206 000071C0 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5207 000071C6 0F834FFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5208                              <1> 
  5209 000071CC AC                  <1> 	lodsb
  5210 000071CD 08C0                <1> 	or	al, al
  5211 000071CF 75EA                <1> 	jnz	short set_env_change_variable_calc7
  5212                              <1> 
  5213                              <1> set_env_change_variable_calc8:
  5214 000071D1 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5215                              <1> 
  5216 000071D2 01F2                <1> 	add	edx, esi ; final position of the last 0
  5217                              <1> 
  5218 000071D4 81FA00320900        <1> 	cmp	edx, Env_Page + Env_Page_Size ; 512 (4096)
  5219 000071DA 0F833BFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5220                              <1> 
  5221 000071E0 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5222                              <1> 
  5223 000071E2 89F1                <1> 	mov	ecx, esi 
  5224 000071E4 29F9                <1> 	sub	ecx, edi ; count of bytes to move forward
  5225                              <1> 
  5226                              <1> 	; 13/04/2016
  5227 000071E6 C60200              <1> 	mov	byte [edx], 0
  5228 000071E9 89D7                <1> 	mov	edi, edx
  5229 000071EB 29F2                <1> 	sub	edx, esi ; difference (additional byte count)
  5230 000071ED 4F                  <1> 	dec	edi ; the last zero address (first byte of the 00)
  5231 000071EE 89FE                <1> 	mov	esi, edi
  5232 000071F0 29D6                <1> 	sub	esi, edx ; - displacement
  5233                              <1> 	
  5234 000071F2 FA                  <1> 	cli	; disable interrupts
  5235 000071F3 FD                  <1> 	std	; backward
  5236                              <1> 
  5237 000071F4 F3A4                <1> 	rep	movsb ; move ECX bytes from DS:ESI to ES:EDI
  5238                              <1> 
  5239 000071F6 FC                  <1> 	cld	; forward (default)
  5240 000071F7 FB                  <1> 	sti	; enable interrupts
  5241                              <1> 	
  5242 000071F8 89C7                <1> 	mov	edi, eax
  5243 000071FA 59                  <1> 	pop	ecx ; ***** ; byte count (after '=')
  5244 000071FB 89CA                <1> 	mov	edx, ecx
  5245 000071FD 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5246 000071FF 89FB                <1> 	mov	ebx, edi
  5247                              <1> 
  5248 00007201 F3A4                <1> 	rep	movsb
  5249                              <1> 
  5250 00007203 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5251                              <1> 
  5252 00007205 0FB605[E8DF0000]    <1> 	movzx	eax, byte [env_var_length]
  5253 0000720C 01C2                <1> 	add	edx, eax ; variable length (total)
  5254 0000720E F7D8                <1> 	neg	eax
  5255 00007210 01D8                <1> 	add	eax, ebx ; start address of the variable
  5256 00007212 F8                  <1> 	clc	; 13/04/2016
  5257 00007213 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 00007218 21D2                <1> 	and	edx, edx ; is empty ?
  5262 0000721A 753B                <1> 	jnz	short set_env_change_variable_calc15
  5263                              <1> 	
  5264 0000721C 0FB6DC              <1> 	movzx	ebx, ah
  5265 0000721F F7DB                <1> 	neg	ebx
  5266 00007221 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 00007223 89FE                <1> 	mov	esi, edi
  5272                              <1> 
  5273                              <1> set_env_change_variable_calc10:
  5274 00007225 AC                  <1> 	lodsb
  5275 00007226 08C0                <1> 	or	al, al
  5276 00007228 75FB                <1> 	jnz	short set_env_change_variable_calc10
  5277                              <1> 
  5278 0000722A B9FF310900          <1> 	mov	ecx, Env_Page + Env_Page_Size - 1
  5279                              <1> 
  5280 0000722F 39CE                <1> 	cmp	esi, ecx ; +511 (+4095)
  5281 00007231 7604                <1> 	jna	short set_env_change_variable_calc11
  5282                              <1> 
  5283 00007233 89CE                <1> 	mov	esi, ecx
  5284 00007235 8806                <1> 	mov	[esi], al ; 0
  5285                              <1> 
  5286                              <1> set_env_change_variable_calc11:
  5287 00007237 89DF                <1> 	mov	edi, ebx ; old variable's start address
  5288                              <1> 
  5289                              <1> set_env_change_variable_calc12:
  5290 00007239 AC                  <1> 	lodsb
  5291 0000723A AA                  <1> 	stosb
  5292 0000723B 20C0                <1> 	and	al, al
  5293 0000723D 75FA                <1> 	jnz	short set_env_change_variable_calc12
  5294 0000723F 39CE                <1> 	cmp	esi, ecx
  5295 00007241 7706                <1> 	ja	short set_env_change_variable_calc13
  5296 00007243 AC                  <1> 	lodsb
  5297 00007244 AA                  <1> 	stosb
  5298 00007245 20C0                <1> 	and	al, al
  5299 00007247 75F0                <1> 	jnz	short set_env_change_variable_calc12	
  5300                              <1> 
  5301                              <1> set_env_change_variable_calc13:
  5302 00007249 29F9                <1> 	sub	ecx, edi
  5303 0000724B 7203                <1> 	jb	short set_env_change_variable_calc14
  5304 0000724D 41                  <1> 	inc	ecx ; 1-512 (1-4096)
  5305 0000724E F3AA                <1> 	rep	stosb ; al = 0	
  5306                              <1> 
  5307                              <1> set_env_change_variable_calc14:
  5308 00007250 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 00007252 E95FFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5313                              <1> 	    
  5314                              <1> set_env_change_variable_calc15:	
  5315 00007257 52                  <1> 	push	edx ; *****
  5316 00007258 F7DA                <1> 	neg	edx
  5317 0000725A 01CA                <1> 	add	edx, ecx ; difference (the old string is longer)
  5318 0000725C 89F3                <1> 	mov 	ebx, esi
  5319 0000725E 89FE                <1> 	mov	esi, edi
  5320                              <1> 
  5321                              <1> set_env_change_variable_calc16:
  5322 00007260 AC                  <1> 	lodsb 
  5323 00007261 20C0                <1> 	and	al, al
  5324 00007263 75FB                <1> 	jnz	short set_env_change_variable_calc16
  5325                              <1> 
  5326 00007265 B900320900          <1> 	mov	ecx, Env_Page + Env_Page_Size
  5327                              <1> 
  5328 0000726A 39CE                <1> 	cmp	esi, ecx ; +512 (+4096)
  5329 0000726C 7605                <1> 	jna	short set_env_change_variable_calc17
  5330                              <1> 
  5331 0000726E 89CE                <1> 	mov	esi, ecx
  5332 00007270 8846FF              <1> 	mov	[esi-1], al ; 0
  5333                              <1> 
  5334                              <1> set_env_change_variable_calc17:
  5335 00007273 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5336 00007275 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5337                              <1> 
  5338 00007277 AC                  <1> 	lodsb
  5339 00007278 08C0                <1> 	or	al, al
  5340 0000727A 741D                <1> 	jz	short set_env_change_variable_calc20
  5341                              <1> 
  5342                              <1> set_env_change_variable_calc18:
  5343 0000727C AC                  <1> 	lodsb
  5344 0000727D 20C0                <1> 	and	al, al
  5345 0000727F 75FB                <1> 	jnz	short set_env_change_variable_calc18
  5346                              <1> 
  5347 00007281 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size
  5348 00007287 720B                <1> 	jb	short set_env_change_variable_calc19
  5349 00007289 740E                <1> 	je	short set_env_change_variable_calc20
  5350                              <1> 
  5351 0000728B BEFF310900          <1> 	mov	esi, Env_Page + Env_Page_Size - 1
  5352 00007290 8806                <1> 	mov	[esi], al ; 0
  5353 00007292 EB06                <1> 	jmp	short set_env_change_variable_calc21
  5354                              <1> 
  5355                              <1> set_env_change_variable_calc19:
  5356 00007294 AC                  <1> 	lodsb
  5357 00007295 08C0                <1> 	or	al, al
  5358 00007297 75E3                <1> 	jnz	short set_env_change_variable_calc18
  5359                              <1> 
  5360                              <1> set_env_change_variable_calc20:
  5361 00007299 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 0000729A 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5367                              <1> 
  5368 0000729C 89F1                <1> 	mov	ecx, esi 
  5369 0000729E 29F9                <1> 	sub	ecx, edi ; count of bytes to move backward
  5370                              <1> 
  5371 000072A0 89FE                <1> 	mov	esi, edi ; next variable's address
  5372 000072A2 29D7                <1> 	sub	edi, edx ; (displacement)
  5373                              <1> 	
  5374 000072A4 F3A4                <1> 	rep	movsb
  5375                              <1> 
  5376 000072A6 880F                <1> 	mov	[edi], cl ; 0 ; 00 ; end of environment variables
  5377                              <1> 
  5378 000072A8 89C7                <1> 	mov	edi, eax
  5379 000072AA 5A                  <1> 	pop	edx ; ***** ; byte count (after '=')
  5380 000072AB 89D1                <1> 	mov	ecx, edx
  5381 000072AD 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5382 000072AF 89FB                <1> 	mov	ebx, edi
  5383                              <1> 	
  5384 000072B1 F3A4                <1> 	rep	movsb
  5385                              <1> 
  5386 000072B3 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5387                              <1> 
  5388 000072B5 0FB605[E8DF0000]    <1> 	movzx	eax, byte [env_var_length]
  5389 000072BC 01C2                <1> 	add	edx, eax ; variable length (total)
  5390 000072BE F7D8                <1> 	neg	eax
  5391 000072C0 01D8                <1> 	add	eax, ebx ; start address of the variable
  5392 000072C2 F8                  <1> 	clc	; 13/04/2016
  5393 000072C3 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 000072C8 BE[5FC20000]        <1> 	mov	esi, MainProgCfgFile
  5402 000072CD 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5403 000072D1 E8FBE9FFFF          <1> 	call	find_first_file
  5404 000072D6 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 000072D8 A3[6CD30000]        <1> 	mov	[MainProgCfg_FileSize], eax
  5414                              <1> 
  5415 000072DD 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  5416 000072E1 C1E210              <1> 	shl	edx, 16
  5417 000072E4 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  5418 000072E8 8915[9CDF0000]      <1> 	mov	[csftdf_sf_cluster], edx
  5419                              <1> 
  5420 000072EE 89C1                <1> 	mov	ecx, eax
  5421 000072F0 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 000072F2 E80AC7FFFF          <1> 	call	allocate_memory_block
  5430 000072F7 7235                <1> 	jc	short loc_load_mainprog_cfg_exit
  5431                              <1> 
  5432 000072F9 A3[94DF0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  5433 000072FE 890D[98DF0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  5434                              <1> 
  5435 00007304 31DB                <1> 	xor	ebx, ebx
  5436                              <1> 	;mov	[csftdf_sf_rbytes], ebx ; 0, reset
  5437                              <1> 
  5438 00007306 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv] ; [FindFile_Drv]
  5439 0000730C BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5440 00007311 01DE                <1> 	add	esi, ebx
  5441                              <1> 
  5442 00007313 8B1D[94DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  5443                              <1> 
  5444 00007319 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5445 0000731D 7710                <1>         ja	short loc_mcfg_load_fat_file
  5446                              <1> 
  5447 0000731F C705[A4DF0000]0000- <1> 	mov	dword [csftdf_r_size], 65536
  5447 00007327 0100                <1>
  5448 00007329 E992010000          <1>         jmp     loc_mcfg_load_fs_file
  5449                              <1> 
  5450                              <1> loc_load_mainprog_cfg_exit:
  5451 0000732E C3                  <1> 	retn 
  5452                              <1> 
  5453                              <1> loc_mcfg_load_fat_file:
  5454 0000732F 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  5455 00007333 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  5456 00007337 F7E1                <1> 	mul	ecx
  5457 00007339 A3[A4DF0000]        <1> 	mov	[csftdf_r_size], eax
  5458                              <1> 
  5459                              <1> loc_mcfg_load_fat_file_next:
  5460 0000733E E813010000          <1> 	call	mcfg_read_fat_file_sectors
  5461 00007343 0F82F7000000        <1>         jc      mcfg_deallocate_mem
  5462                              <1> 
  5463 00007349 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  5464 0000734B 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 0000734D C705[2CE00000]-     <1> 	mov	dword [mainprog_return_addr], loc_mcfg_ci_return_addr 
  5468 00007353 [01740000]          <1>
  5469                              <1> 	;
  5470 00007357 8B35[94DF0000]      <1> 	mov	esi, [csftdf_sf_mem_addr]
  5471 0000735D 8935[70D30000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5472                              <1> 	
  5473 00007363 A1[6CD30000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5474 00007368 89C2                <1> 	mov	edx, eax
  5475 0000736A 01F2                <1> 	add	edx, esi
  5476                              <1> 
  5477                              <1> loc_mcfg_process_next_line_check:
  5478 0000736C 89C1                <1> 	mov	ecx, eax
  5479                              <1> 
  5480 0000736E 803E2A              <1> 	cmp	byte [esi], "*" ; Remark sign
  5481 00007371 7503                <1> 	jne	short loc_mcfg_process_next_line
  5482 00007373 46                  <1> 	inc	esi
  5483 00007374 EB17                <1> 	jmp	short loc_move_mainprog_cfg_nl1
  5484                              <1> 
  5485                              <1> loc_mcfg_process_next_line:
  5486 00007376 83F94F              <1> 	cmp	ecx, 79
  5487 00007379 7605                <1> 	jna	short loc_start_mainprog_cfg_process
  5488                              <1> 	
  5489 0000737B B94F000000          <1> 	mov	ecx, 79 
  5490                              <1> 
  5491                              <1> loc_start_mainprog_cfg_process:
  5492 00007380 BF[2ED40000]        <1> 	mov	edi, CommandBuffer
  5493                              <1> 
  5494                              <1> loc_move_mainprog_cfg_line:
  5495 00007385 AC                  <1> 	lodsb
  5496 00007386 3C20                <1> 	cmp	al, 20h
  5497 00007388 720C                <1> 	jb	short loc_move_mainprog_cfg_nl2
  5498 0000738A AA                  <1> 	stosb
  5499 0000738B E2F8                <1> 	loop	loc_move_mainprog_cfg_line
  5500                              <1> 
  5501                              <1> loc_move_mainprog_cfg_nl1:
  5502 0000738D 39D6                <1> 	cmp	esi, edx ; + configuration file size
  5503 0000738F 7312                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5504 00007391 AC                  <1> 	lodsb
  5505 00007392 3C20                <1> 	cmp	al, 20h
  5506 00007394 73F7                <1> 	jnb	short loc_move_mainprog_cfg_nl1
  5507                              <1> 
  5508                              <1> loc_move_mainprog_cfg_nl2:
  5509 00007396 39D6                <1> 	cmp	esi, edx
  5510 00007398 7309                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5511 0000739A 8A06                <1> 	mov	al, [esi]
  5512 0000739C 3C20                <1> 	cmp	al, 20h
  5513 0000739E 7703                <1>  	ja	short loc_end_of_mainprog_cfg_line
  5514 000073A0 46                  <1> 	inc	esi
  5515 000073A1 EBF3                <1> 	jmp	short loc_move_mainprog_cfg_nl2	               
  5516                              <1> 
  5517                              <1> loc_end_of_mainprog_cfg_line:
  5518 000073A3 C60700              <1> 	mov	byte [edi], 0
  5519                              <1> 
  5520 000073A6 8935[70D30000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5521                              <1> 	
  5522                              <1> loc_move_mainprog_cfg_command:
  5523 000073AC BE[2ED40000]        <1> 	mov	esi, CommandBuffer
  5524 000073B1 89F7                <1> 	mov	edi, esi
  5525 000073B3 31DB                <1> 	xor	ebx, ebx
  5526                              <1> 	;xor	ecx, ecx
  5527 000073B5 30C9                <1> 	xor	cl, cl
  5528                              <1> 
  5529                              <1> loc_move_mcfg_first_cmd_char:
  5530 000073B7 8A041E              <1> 	mov	al, [esi+ebx]
  5531 000073BA FEC3                <1> 	inc	bl 
  5532 000073BC 3C20                <1> 	cmp	al, 20h
  5533 000073BE 7712                <1> 	ja	short loc_move_mcfg_cmd_capitalizing
  5534 000073C0 7237                <1> 	jb	short loc_move_mcfg_cmd_arguments_ok
  5535 000073C2 80FB4F              <1> 	cmp	bl, 79
  5536 000073C5 72F0                <1> 	jb	short loc_move_mcfg_first_cmd_char
  5537 000073C7 EB30                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5538                              <1> 
  5539                              <1> loc_move_mcfg_next_cmd_char:
  5540 000073C9 8A041E              <1> 	mov	al, [esi+ebx]
  5541 000073CC FEC3                <1> 	inc	bl
  5542 000073CE 3C20                <1> 	cmp	al, 20h
  5543 000073D0 7614                <1> 	jna	short loc_move_mcfg_cmd_ok
  5544                              <1> 
  5545                              <1> loc_move_mcfg_cmd_capitalizing:
  5546 000073D2 3C61                <1> 	cmp	al, 61h ; 'a'
  5547 000073D4 7206                <1> 	jb	short loc_move_mcfg_cmd_caps_ok
  5548 000073D6 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  5549 000073D8 7702                <1> 	ja	short loc_move_mcfg_cmd_caps_ok
  5550 000073DA 24DF                <1> 	and	al, 0DFh ; sub	al, 'a'-'A'
  5551                              <1> 
  5552                              <1> loc_move_mcfg_cmd_caps_ok:
  5553 000073DC AA                  <1> 	stosb 
  5554 000073DD FEC1                <1> 	inc	cl
  5555 000073DF 80FB4F              <1> 	cmp	bl, 79
  5556 000073E2 72E5                <1> 	jb	short loc_move_mcfg_next_cmd_char
  5557 000073E4 EB13                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5558                              <1> 
  5559                              <1> loc_move_mcfg_cmd_ok:
  5560 000073E6 30C0                <1> 	xor	al, al ; 0
  5561                              <1> 
  5562                              <1> loc_move_mcfg_cmd_arguments:
  5563 000073E8 8807                <1> 	mov	[edi], al
  5564 000073EA 47                  <1> 	inc	edi
  5565 000073EB 80FB4F              <1> 	cmp	bl, 79
  5566 000073EE 7309                <1> 	jnb	short loc_move_mcfg_cmd_arguments_ok
  5567 000073F0 8A041E              <1> 	mov	al, [esi+ebx]
  5568 000073F3 FEC3                <1> 	inc	bl
  5569 000073F5 3C20                <1> 	cmp	al, 20h
  5570 000073F7 73EF                <1> 	jnb	short loc_move_mcfg_cmd_arguments
  5571                              <1> 	
  5572                              <1> loc_move_mcfg_cmd_arguments_ok:
  5573 000073F9 C60700              <1> 	mov	byte [edi], 0
  5574                              <1>        
  5575                              <1> loc_mcfg_process_cmd_interpreter:
  5576 000073FC E8F8DFFFFF          <1> 	call    command_interpreter
  5577                              <1> 
  5578                              <1> loc_mcfg_ci_return_addr: 
  5579 00007401 A1[6CD30000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5580 00007406 89C2                <1> 	mov	edx, eax
  5581 00007408 8B35[70D30000]      <1> 	mov	esi, [MainProgCfg_LineOffset]
  5582 0000740E 01F2                <1> 	add	edx, esi
  5583 00007410 0305[94DF0000]      <1> 	add	eax, [csftdf_sf_mem_addr]
  5584 00007416 29F0                <1> 	sub	eax, esi
  5585 00007418 0F874EFFFFFF        <1>         ja      loc_mcfg_process_next_line_check
  5586                              <1> 
  5587 0000741E E81D000000          <1> 	call	mcfg_deallocate_mem
  5588                              <1>  
  5589 00007423 B94F000000          <1>  	mov	ecx, 79 ; 80 ?
  5590 00007428 BF[2ED40000]        <1> 	mov	edi, CommandBuffer
  5591 0000742D 30C0                <1> 	xor	al, al
  5592 0000742F F3AA                <1> 	rep	stosb
  5593                              <1> 
  5594                              <1> 	; 06/05/2016
  5595 00007431 BE[52CF0000]        <1> 	mov	esi, nextline
  5596 00007436 E8F5CBFFFF          <1> 	call	print_msg
  5597 0000743B E931D6FFFF          <1> 	jmp	dos_prompt
  5598                              <1> 
  5599                              <1> mcfg_deallocate_mem:
  5600 00007440 A1[94DF0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  5601 00007445 8B0D[98DF0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  5602                              <1> 	;call	deallocate_memory_block
  5603                              <1> 	;retn
  5604 0000744B E9B2C7FFFF          <1> 	jmp	deallocate_memory_block
  5605                              <1> 
  5606                              <1> mcfg_read_file_sectors:
  5607                              <1> 	; 14/04/2016
  5608 00007450 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5609 00007454 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 00007456 8B15[6CD30000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5619 0000745C 2B15[ACDF0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  5620 00007462 3B15[A4DF0000]      <1> 	cmp	edx, [csftdf_r_size]	
  5621 00007468 7306                <1> 	jnb	short mcfg_read_fat_file_secs_1
  5622 0000746A 8915[A4DF0000]      <1> 	mov	[csftdf_r_size], edx
  5623                              <1> 		
  5624                              <1> mcfg_read_fat_file_secs_1:
  5625 00007470 A1[A4DF0000]        <1> 	mov	eax, [csftdf_r_size]
  5626 00007475 29D2                <1> 	sub	edx, edx
  5627 00007477 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  5628 0000747B 01C8                <1> 	add	eax, ecx
  5629 0000747D 48                  <1> 	dec	eax
  5630 0000747E F7F1                <1> 	div	ecx
  5631 00007480 89C1                <1> 	mov	ecx, eax ; sector count
  5632 00007482 A1[9CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5633                              <1> 
  5634                              <1> 	; EBX = memory block address (current)
  5635                              <1> 	
  5636 00007487 E874230000          <1> 	call	read_fat_file_sectors
  5637 0000748C 7230                <1> 	jc	short mcfg_read_fat_file_secs_3
  5638                              <1> 
  5639                              <1> 	; EBX = next memory address
  5640                              <1> 
  5641 0000748E A1[ACDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  5642 00007493 0305[A4DF0000]      <1> 	add	eax, [csftdf_r_size]
  5643 00007499 8B15[6CD30000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5644 0000749F 39D0                <1> 	cmp	eax, edx
  5645 000074A1 731B                <1> 	jnb	short mcfg_read_fat_file_secs_3 ; edx > 0
  5646 000074A3 A3[ACDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  5647                              <1> 
  5648 000074A8 53                  <1> 	push	ebx ; *
  5649                              <1> 	; get next cluster (csftdf_r_size! bytes)
  5650 000074A9 A1[9CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5651 000074AE E81F210000          <1> 	call	get_next_cluster
  5652 000074B3 5B                  <1> 	pop	ebx ; *
  5653 000074B4 7301                <1> 	jnc	short mcfg_read_fat_file_secs_2
  5654                              <1> 
  5655                              <1> 	;mov	eax, 15h ; Read error !
  5656 000074B6 C3                  <1> 	retn
  5657                              <1> 
  5658                              <1> mcfg_read_fat_file_secs_2:
  5659 000074B7 29D2                <1> 	sub	edx, edx ; 0
  5660 000074B9 A3[9CDF0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  5661                              <1> 
  5662                              <1> mcfg_read_fat_file_secs_3:
  5663 000074BE C3                  <1> 	retn
  5664                              <1> 
  5665                              <1> mcfg_read_fs_file_sectors:
  5666 000074BF C3                  <1> 	retn
  5667                              <1> 
  5668                              <1> loc_mcfg_load_fs_file:
  5669 000074C0 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 000074C1 803E20              <1> 	cmp	byte [esi], 20h
  5692 000074C4 0F8205E3FFFF        <1> 	jb	loc_cmd_failed
  5693 000074CA 7703                <1> 	ja	short loc_run_check_filename_ok
  5694 000074CC 46                  <1> 	inc	esi
  5695 000074CD EBF2                <1> 	jmp	short loc_run_check_filename
  5696                              <1> 
  5697                              <1> loc_run_check_filename_ok:
  5698 000074CF C605[DFD30000]00    <1> 	mov	byte [CmdArgStart], 0 ; reset
  5699 000074D6 56                  <1> 	push	esi ; *
  5700                              <1> loc_run_get_first_arg_pos:
  5701 000074D7 46                  <1> 	inc	esi
  5702 000074D8 8A06                <1> 	mov	al, [esi]
  5703 000074DA 3C20                <1> 	cmp	al, 20h
  5704 000074DC 77F9                <1> 	ja	short loc_run_get_first_arg_pos
  5705 000074DE C60600              <1> 	mov	byte [esi], 0
  5706                              <1> loc_run_get_external_arg_pos:
  5707                              <1> 	; 11/05/2016
  5708 000074E1 46                  <1> 	inc	esi
  5709 000074E2 8A06                <1> 	mov	al, [esi]
  5710 000074E4 3C20                <1> 	cmp	al, 20h
  5711 000074E6 760C                <1> 	jna	short loc_run_parse_path_name
  5712 000074E8 89F0                <1> 	mov	eax, esi
  5713 000074EA 2D[2ED40000]        <1> 	sub	eax, CommandBuffer
  5714 000074EF A2[DFD30000]        <1> 	mov	byte [CmdArgStart], al
  5715                              <1> loc_run_parse_path_name:
  5716 000074F4 5E                  <1> 	pop	esi ; *
  5717 000074F5 BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  5718 000074FA E8DC090000          <1> 	call	parse_path_name
  5719 000074FF 0F82CAE2FFFF        <1> 	jc	loc_cmd_failed
  5720                              <1> 
  5721                              <1> loc_run_check_filename_exists:
  5722 00007505 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5723 0000750A 803E20              <1> 	cmp	byte [esi], 20h
  5724 0000750D 0F86BCE2FFFF        <1> 	jna	loc_cmd_failed
  5725                              <1> 
  5726                              <1> loc_run_check_exe_filename_ext:
  5727 00007513 E897020000          <1> 	call	check_prg_filename_ext
  5728 00007518 0F82B1E2FFFF        <1> 	jc	loc_cmd_failed
  5729                              <1> 	
  5730                              <1> loc_run_check_exe_filename_ext_ok:
  5731 0000751E 66A3[2AE00000]      <1> 	mov	word [EXE_ID], ax
  5732                              <1> 
  5733                              <1> loc_run_drv:
  5734 00007524 C605[29E00000]00    <1> 	mov	byte [Run_Manual_Path], 0
  5735 0000752B A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5736 00007530 A3[24E00000]        <1>         mov     [Run_CDirFC], eax
  5737                              <1> 	;
  5738 00007535 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  5739 0000753B 8835[DEDB0000]      <1> 	mov	[RUN_CDRV], dh
  5740                              <1> 
  5741 00007541 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  5742 00007547 38F2                <1> 	cmp	dl, dh
  5743 00007549 7412                <1> 	je	short loc_run_change_directory
  5744                              <1>                
  5745 0000754B 8005[29E00000]02    <1> 	add	byte [Run_Manual_Path], 2
  5746                              <1> 
  5747 00007552 E8DED3FFFF          <1> 	call	change_current_drive
  5748 00007557 0F829DE2FFFF        <1> 	jc	loc_run_cmd_failed
  5749                              <1> 
  5750                              <1> loc_run_change_directory:
  5751 0000755D 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5752 00007564 7623                <1> 	jna	short loc_run_find_executable_file
  5753                              <1> 
  5754 00007566 FE05[29E00000]      <1> 	inc	byte [Run_Manual_Path]
  5755                              <1>      
  5756 0000756C FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  5757                              <1> 
  5758 00007572 BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  5759 00007577 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5760 00007579 E849030000          <1> 	call	change_current_directory
  5761 0000757E 0F8276E2FFFF        <1> 	jc	loc_run_cmd_failed
  5762                              <1> 
  5763                              <1> loc_run_change_prompt_dir_string:
  5764 00007584 E85E020000          <1> 	call	change_prompt_dir_string
  5765                              <1> 
  5766                              <1> loc_run_find_executable_file:
  5767 00007589 66C705[28E00000]00- <1> 	mov	word [Run_Auto_Path], 0
  5767 00007591 00                  <1>
  5768                              <1> 
  5769                              <1> loc_run_find_executable_file_next:
  5770 00007592 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5771                              <1> loc_run_find_program_file_next:
  5772 00007597 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5773 0000759B 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 000075A0 0F835C010000        <1> 	jnc	loc_load_and_run_file
  5778                              <1> 	 
  5779 000075A6 3C02                <1> 	cmp	al, 2 ; file not found
  5780 000075A8 0F854CE2FFFF        <1> 	jne	loc_run_cmd_failed
  5781                              <1> 
  5782 000075AE 66A1[2AE00000]      <1> 	mov	ax, word [EXE_ID]
  5783 000075B4 80FC2E              <1> 	cmp	ah, '.' ; File name has extension sign
  5784 000075B7 7424                <1> 	je	short loc_run_check_auto_path
  5785                              <1> 
  5786 000075B9 08C0                <1> 	or	al, al
  5787 000075BB 7520                <1> 	jnz	short loc_run_check_auto_path
  5788                              <1> 
  5789 000075BD 80FC08              <1> 	cmp	ah, 8 ; count of file name chars
  5790 000075C0 771B                <1> 	ja	short loc_run_check_auto_path
  5791                              <1> 
  5792                              <1> loc_run_change_file_ext_to_prg:
  5793 000075C2 0FB6DC              <1> 	movzx	ebx, ah ; count of file name chars
  5794 000075C5 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5795 000075CA 01F3                <1> 	add	ebx, esi	
  5796                              <1> 	; 07/05/2016
  5797 000075CC C7032E505247        <1> 	mov	dword [ebx],  '.PRG'
  5798 000075D2 66C705[2AE00000]50- <1> 	mov	word [EXE_ID], 'P.'
  5798 000075DA 2E                  <1>
  5799 000075DB 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 000075DD A0[29E00000]        <1> 	mov	al, [Run_Manual_Path]
  5810 000075E2 08C0                <1> 	or	al, al
  5811 000075E4 0F85E5E1FFFF        <1> 	jnz	loc_cmd_failed
  5812                              <1> 
  5813                              <1> loc_run_check_auto_path_again:
  5814 000075EA 66833D[28E00000]FF  <1> 	cmp	word [Run_Auto_Path], 0FFFFh		 
  5815                              <1> 		; 0FFFFh = Not a valid run path (in ENV block) 
  5816 000075F2 0F83D7E1FFFF        <1> 	jnb	loc_cmd_failed
  5817                              <1> 	; xor	al, al 
  5818 000075F8 BE[E5C20000]        <1> 	mov	esi, Cmd_Path ; 'PATH'
  5819 000075FD BF[7ED40000]        <1> 	mov	edi, TextBuffer
  5820 00007602 E857F9FFFF          <1> 	call	get_environment_string
  5821 00007607 730E                <1> 	jnc	short loc_run_chk_filename_ext_again
  5822 00007609 66C705[28E00000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; invalid
  5822 00007611 FF                  <1>
  5823 00007612 E9B8E1FFFF          <1> 	jmp	loc_cmd_failed
  5824                              <1> 
  5825                              <1> loc_run_chk_filename_ext_again:
  5826 00007617 89C1                <1> 	mov	ecx, eax ; string length (with zero tail)
  5827 00007619 49                  <1> 	dec	ecx ; without zero tail
  5828 0000761A 66A1[2AE00000]      <1> 	mov	ax, [EXE_ID]
  5829 00007620 80FC2E              <1> 	cmp	ah, '.'
  5830 00007623 740E                <1> 	je	short loc_run_chk_auto_path_pos
  5831                              <1> 	 
  5832                              <1> loc_run_change_file_ext_to_noext_again:
  5833 00007625 0FB6DC              <1> 	movzx	ebx, ah
  5834 00007628 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5835 0000762D 01F3                <1> 	add 	ebx, esi
  5836 0000762F 29C0                <1> 	sub	eax, eax
  5837 00007631 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 00007633 66A1[28E00000]      <1> 	mov	ax, [Run_Auto_Path]
  5842 00007639 39C8                <1> 	cmp	eax, ecx ; ecx = string length (except zero tail)
  5843 0000763B 0F838EE1FFFF        <1> 	jnb	loc_cmd_failed
  5844                              <1> 	;or	eax, eax
  5845 00007641 6609C0              <1> 	or	ax, ax
  5846 00007644 7502                <1> 	jnz	short loc_run_auto_path_pos_move
  5847 00007646 B005                <1> 	mov	al, 5
  5848                              <1> 
  5849                              <1> loc_run_auto_path_pos_move:
  5850 00007648 89FE                <1> 	mov	esi, edi ; offset TextBuffer
  5851 0000764A 01C6                <1> 	add	esi, eax
  5852                              <1> 
  5853                              <1> loc_run_auto_path_pos_space_loop:
  5854 0000764C AC                  <1> 	lodsb
  5855 0000764D 3C20                <1> 	cmp	al, 20h 
  5856 0000764F 74FB                <1> 	je	short loc_run_auto_path_pos_space_loop
  5857 00007651 0F8278E1FFFF        <1> 	jb	loc_cmd_failed 
  5858 00007657 AA                  <1> 	stosb
  5859                              <1> loc_run_auto_path_pos_move_next: 
  5860 00007658 AC                  <1> 	lodsb
  5861 00007659 3C3B                <1> 	cmp	al, ';'
  5862 0000765B 7414                <1> 	je	short loc_run_auto_path_pos_move_last_byte
  5863 0000765D 3C20                <1> 	cmp	al, 20h
  5864 0000765F 74F7                <1> 	je	short loc_run_auto_path_pos_move_next
  5865 00007661 7203                <1> 	jb	short loc_byte_ptr_end_of_path
  5866 00007663 AA                  <1> 	stosb
  5867 00007664 EBF2                <1> 	jmp	short loc_run_auto_path_pos_move_next 
  5868                              <1> 
  5869                              <1> loc_byte_ptr_end_of_path: 
  5870 00007666 66C705[28E00000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; end of path
  5870 0000766E FF                  <1>
  5871 0000766F EB0D                <1> 	jmp	short loc_run_auto_path_move_ok 
  5872                              <1> 
  5873                              <1> loc_run_auto_path_pos_move_last_byte:
  5874 00007671 89F0                <1> 	mov	eax, esi
  5875 00007673 2D[7ED40000]        <1> 	sub	eax, TextBuffer 
  5876 00007678 66A3[28E00000]      <1> 	mov	[Run_Auto_Path], ax ; next path position
  5877                              <1> 
  5878                              <1> loc_run_auto_path_move_ok:
  5879 0000767E 4F                  <1> 	dec	edi
  5880 0000767F B02F                <1> 	mov	al, '/'
  5881 00007681 3807                <1> 	cmp	[edi], al
  5882 00007683 7403                <1> 	je	short loc_run_auto_path_move_file_name
  5883 00007685 47                  <1> 	inc	edi
  5884 00007686 8807                <1> 	mov	[edi], al
  5885                              <1> 
  5886                              <1> loc_run_auto_path_move_file_name:
  5887 00007688 47                  <1> 	inc	edi   
  5888 00007689 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5889                              <1> 
  5890                              <1> loc_run_auto_path_move_fn_loop:
  5891 0000768E AC                  <1> 	lodsb
  5892 0000768F AA                  <1> 	stosb
  5893 00007690 08C0                <1> 	or	al, al
  5894 00007692 75FA                <1> 	jnz	short loc_run_auto_path_move_fn_loop
  5895                              <1> 
  5896 00007694 BE[7ED40000]        <1> 	mov	esi, TextBuffer
  5897 00007699 BF[22DD0000]        <1> 	mov	edi, FindFile_Drv
  5898 0000769E E838080000          <1> 	call	parse_path_name
  5899 000076A3 0F8226E1FFFF        <1> 	jc	loc_cmd_failed
  5900                              <1> 
  5901 000076A9 8A35[7ED30000]      <1> 	mov	dh, [Current_Drv]
  5902 000076AF 8A15[22DD0000]      <1> 	mov	dl, [FindFile_Drv]
  5903 000076B5 38F2                <1> 	cmp	dl, dh
  5904 000076B7 740B                <1> 	je	short loc_run_change_directory_again
  5905                              <1>                
  5906 000076B9 E877D2FFFF          <1> 	call	change_current_drive
  5907 000076BE 0F8236E1FFFF        <1> 	jc	loc_run_cmd_failed
  5908                              <1> 
  5909                              <1> loc_run_change_directory_again:
  5910 000076C4 803D[23DD0000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5911 000076CB 761D                <1> 	jna	short loc_load_executable_cdir_chk_again
  5912                              <1> 
  5913 000076CD FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  5914 000076D3 BE[23DD0000]        <1> 	mov	esi, FindFile_Directory
  5915 000076D8 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5916 000076DA E8E8010000          <1> 	call	change_current_directory
  5917 000076DF 0F8215E1FFFF        <1> 	jc	loc_run_cmd_failed
  5918                              <1> 
  5919                              <1> loc_run_chg_prompt_dir_str_again:
  5920 000076E5 E8FD000000          <1> 	call	change_prompt_dir_string
  5921                              <1> 
  5922                              <1> loc_load_executable_cdir_chk_again:
  5923 000076EA A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5924 000076EF 3B05[24E00000]      <1> 	cmp	eax, [Run_CDirFC]
  5925 000076F5 0F8597FEFFFF        <1> 	jne	loc_run_find_executable_file_next
  5926 000076FB 30C0                <1> 	xor	al, al ; 0
  5927 000076FD E9E8FEFFFF          <1> 	jmp	loc_run_check_auto_path_again
  5928                              <1> 
  5929                              <1> loc_load_and_run_file:
  5930                              <1> 	; 23/04/2016
  5931 00007702 BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  5932 00007707 BF[7ED40000]        <1> 	mov	edi, TextBuffer
  5933                              <1> 
  5934                              <1>  	; 24/04/2016
  5935 0000770C 31D2                <1> 	xor	edx, edx
  5936 0000770E 668915[FEE30000]    <1> 	mov	word [argc], dx ; 0
  5937 00007715 8915[A8E30000]      <1> 	mov	dword [u.nread], edx ; 0
  5938                              <1> 
  5939                              <1> loc_load_and_run_file_1:
  5940 0000771B AC                  <1> 	lodsb	
  5941 0000771C AA                  <1> 	stosb
  5942 0000771D FF05[A8E30000]      <1> 	inc	dword [u.nread]
  5943 00007723 20C0                <1> 	and	al, al
  5944 00007725 75F4                <1> 	jnz 	short loc_load_and_run_file_1
  5945                              <1> 	
  5946 00007727 A0[DFD30000]        <1> 	mov	al, [CmdArgStart]
  5947 0000772C 20C0                <1> 	and	al, al
  5948 0000772E 7445                <1> 	jz	short loc_load_and_run_file_7
  5949                              <1> 
  5950 00007730 0FB6F0              <1> 	movzx	esi, al ; 11/05/2016
  5951 00007733 B950000000          <1> 	mov	ecx, 80
  5952 00007738 29F1                <1> 	sub	ecx, esi
  5953 0000773A 81C6[2ED40000]      <1> 	add	esi, CommandBuffer
  5954                              <1> 
  5955 00007740 66FF05[FEE30000]    <1> 	inc	word [argc] ; 11/05/2016
  5956                              <1> 
  5957                              <1> loc_load_and_run_file_2:
  5958 00007747 AC                  <1> 	lodsb
  5959 00007748 3C20                <1> 	cmp	al, 20h
  5960 0000774A 7717                <1> 	ja	short loc_load_and_run_file_5	
  5961 0000774C 721E                <1> 	jb	short loc_load_and_run_file_6
  5962                              <1> 
  5963                              <1> loc_load_and_run_file_3:
  5964 0000774E 803E20              <1> 	cmp	byte [esi], 20h
  5965 00007751 7707                <1> 	ja	short loc_load_and_run_file_4
  5966 00007753 7217                <1> 	jb	short loc_load_and_run_file_6
  5967 00007755 46                  <1> 	inc	esi
  5968 00007756 E2F6                <1> 	loop	loc_load_and_run_file_3
  5969 00007758 EB12                <1> 	jmp	short loc_load_and_run_file_6
  5970                              <1> 
  5971                              <1> loc_load_and_run_file_4:
  5972 0000775A 28C0                <1> 	sub	al, al ; 0
  5973 0000775C 66FF05[FEE30000]    <1> 	inc	word [argc]
  5974                              <1> loc_load_and_run_file_5:
  5975 00007763 AA                  <1> 	stosb
  5976 00007764 FF05[A8E30000]      <1> 	inc	dword [u.nread]
  5977 0000776A E2DB                <1> 	loop	loc_load_and_run_file_2
  5978                              <1> 			
  5979                              <1> loc_load_and_run_file_6:
  5980 0000776C 30C0                <1> 	xor	al, al ; 0
  5981 0000776E AA                  <1> 	stosb
  5982 0000776F FF05[A8E30000]      <1> 	inc	dword [u.nread]
  5983                              <1> loc_load_and_run_file_7:
  5984 00007775 8807                <1> 	mov 	[edi], al ; 0
  5985 00007777 66FF05[FEE30000]    <1> 	inc	word [argc] ; 24/04/2016
  5986 0000777E FF05[A8E30000]      <1> 	inc	dword [u.nread] ; 24/04/2016
  5987 00007784 BE[7ED40000]        <1> 	mov	esi, TextBuffer
  5988 00007789 8B15[90DD0000]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  5989 0000778F 66A1[88DD0000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  5990 00007795 66C1E010            <1> 	shl	ax, 16
  5991 00007799 66A1[8EDD0000]      <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 0000779F E8F63D0000          <1> 	call	load_and_run_file ; trdosk6.s
  5998 000077A4 0F8250E0FFFF        <1>         jc      loc_run_cmd_failed
  5999                              <1> loc_load_and_run_file_8: ; 06/05/2016
  6000 000077AA 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 000077AF 30E4                <1> 	xor	ah, ah
  6020                              <1> loc_run_check_filename_ext:	
  6021 000077B1 AC                  <1> 	lodsb
  6022 000077B2 3C21                <1> 	cmp	al, 21h
  6023 000077B4 7229                <1> 	jb	short loc_check_exe_fn_retn 
  6024 000077B6 FEC4                <1> 	inc	ah
  6025 000077B8 3C2E                <1> 	cmp	al, '.'
  6026 000077BA 75F5                <1> 	jne	short loc_run_check_filename_ext	
  6027                              <1> 		 
  6028                              <1> loc_run_check_filename_ext_dot:
  6029 000077BC 80FC02              <1> 	cmp	ah, 2 ; .??? is not valid
  6030 000077BF 88C4                <1> 	mov	ah, al ; '.' 
  6031 000077C1 7219                <1> 	jb	short loc_check_prg_fn_retn
  6032                              <1> 
  6033                              <1> loc_run_check_filename_ext_dot_ok:
  6034 000077C3 AC                  <1> 	lodsb
  6035 000077C4 24DF                <1> 	and	al, 0DFh 
  6036                              <1> 
  6037                              <1> loc_run_check_filename_ext_prg:
  6038 000077C6 3C50                <1> 	cmp	al, 'P'
  6039 000077C8 7212                <1> 	jb	short loc_check_prg_fn_retn
  6040 000077CA 7711                <1> 	ja	short loc_check_prg_fn_stc
  6041 000077CC AC                  <1> 	lodsb
  6042 000077CD 24DF                <1> 	and	al, 0DFh 
  6043 000077CF 3C52                <1> 	cmp	al, 'R'
  6044 000077D1 750A                <1> 	jne	short loc_check_prg_fn_stc
  6045 000077D3 AC                  <1> 	lodsb
  6046 000077D4 24DF                <1> 	and	al, 0DFh
  6047 000077D6 3C47                <1> 	cmp	al, 'G'
  6048 000077D8 7503                <1> 	jne	short loc_check_prg_fn_stc
  6049                              <1> 
  6050 000077DA B050                <1> 	mov	al, 'P'
  6051                              <1> loc_check_prg_fn_retn:
  6052 000077DC C3                  <1> 	retn
  6053                              <1> 
  6054                              <1> loc_check_prg_fn_stc:
  6055 000077DD F9                  <1> 	stc
  6056 000077DE C3                  <1> 	retn
  6057                              <1>  
  6058                              <1> loc_check_exe_fn_retn:
  6059 000077DF 28C0                <1> 	sub	al, al ; 0
  6060 000077E1 C3                  <1> 	retn
  6061                              <1>               
  6062                              <1> find_and_list_files:
  6063 000077E2 C3                  <1> 	retn
  6064                              <1> set_exec_arguments:
  6065 000077E3 C3                  <1> 	retn
  6066                              <1> delete_fs_directory:
  6067 000077E4 31C0                <1> 	xor eax, eax
  6068 000077E6 C3                  <1> 	retn
  1906                                  %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 000077E7 BF[82D30000]        <1> 	mov	edi, Current_Directory
    27 000077EC 8A25[7CD30000]      <1> 	mov	ah, [Current_Dir_Level]
    28 000077F2 BE[DFDB0000]        <1> 	mov	esi, PATH_Array
    29 000077F7 E807000000          <1> 	call	set_current_directory_string
    30 000077FC 880D[DDD30000]      <1> 	mov	[Current_Dir_StrLen], cl
    31                              <1> 
    32 00007802 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 00007803 57                  <1> 	push    edi
    47 00007804 80FC00              <1> 	cmp     ah, 0
    48 00007807 7652                <1> 	jna	short pass_write_path
    49 00007809 83C610              <1> 	add	esi, 16
    50 0000780C 89F3                <1> 	mov	ebx, esi
    51                              <1> loc_write_path:
    52 0000780E B908000000          <1> 	mov	ecx, 8
    53                              <1> path_write_dirname1:
    54 00007813 AC                  <1> 	lodsb
    55 00007814 3C20                <1> 	cmp	al, 20h
    56 00007816 7612                <1> 	jna	short pass_write_dirname1
    57 00007818 AA                  <1> 	stosb
    58 00007819 81FF[DCD30000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    59 0000781F 733A                <1> 	jnb	short pass_write_path
    60 00007821 E2F0                <1> 	loop	path_write_dirname1
    61 00007823 803E20              <1> 	cmp	byte [esi], 20h
    62 00007826 7624                <1> 	jna	short pass_write_dirname2
    63 00007828 EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    64                              <1> pass_write_dirname1:
    65 0000782A 89DE                <1> 	mov	esi, ebx
    66 0000782C 83C608              <1> 	add	esi, 8
    67 0000782F 803E20              <1> 	cmp	byte [esi], 20h
    68 00007832 7618                <1> 	jna	short pass_write_dirname2
    69                              <1> loc_put_dot_cont_ext:
    70 00007834 C6072E              <1> 	mov	byte [edi], "."
    71                              <1> 	;mov	ecx, 3
    72 00007837 B103                <1> 	mov	cl, 3
    73                              <1> loc_check_dir_name_ext:
    74 00007839 AC                  <1> 	lodsb
    75 0000783A 47                  <1> 	inc	edi
    76 0000783B 3C20                <1> 	cmp	al, 20h
    77 0000783D 760D                <1> 	jna	short pass_write_dirname2
    78 0000783F 8807                <1> 	mov	[edi], al
    79 00007841 81FF[DCD30000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    80 00007847 7312                <1> 	jnb	short pass_write_path
    81 00007849 E2EE                <1> 	loop    loc_check_dir_name_ext
    82 0000784B 47                  <1> 	inc	edi
    83                              <1> pass_write_dirname2:
    84 0000784C FECC                <1> 	dec	ah
    85 0000784E 740B                <1> 	jz      short pass_write_path
    86 00007850 83C310              <1> 	add	ebx, 16
    87 00007853 89DE                <1> 	mov	esi, ebx
    88 00007855 C6072F              <1> 	mov	byte [edi],"/"
    89 00007858 47                  <1> 	inc	edi
    90 00007859 EBB3                <1> 	jmp	short loc_write_path
    91                              <1> pass_write_path:
    92 0000785B C60700              <1> 	mov	byte [edi], 0
    93 0000785E 47                  <1> 	inc	edi
    94 0000785F 89F9                <1> 	mov	ecx, edi
    95 00007861 5F                  <1> 	pop	edi
    96 00007862 29F9                <1> 	sub	ecx, edi
    97                              <1> 	; ECX = Current Directory String Length
    98 00007864 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 00007865 80FA00              <1> 	cmp	dl, 0
   122 00007868 7708                <1> 	ja	short loc_get_current_drive_1
   123 0000786A 8A15[7ED30000]      <1> 	mov	dl, [Current_Drv]
   124 00007870 EB17                <1> 	jmp	short loc_get_current_drive_2
   125                              <1> loc_get_current_drive_1:
   126 00007872 FECA                <1> 	dec 	dl
   127 00007874 3A15[18C20000]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   128 0000787A 760D                <1> 	jna	short loc_get_current_drive_2
   129 0000787C B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
   130 00007881 F5                  <1> 	cmc 	; stc
   131 00007882 C3                  <1> 	retn
   132                              <1> 
   133                              <1> loc_get_current_drive_not_ready_retn:
   134 00007883 5E                  <1> 	pop	esi
   135                              <1> 	;mov	eax, 15h
   136 00007884 66B81500            <1> 	mov	ax, 15h ; Drive not ready
   137 00007888 C3                  <1> 	retn  
   138                              <1>  
   139                              <1> loc_get_current_drive_2:
   140 00007889 31C0                <1> 	xor	eax, eax
   141 0000788B 88D4                <1> 	mov	ah, dl
   142 0000788D 56                  <1> 	push	esi
   143 0000788E BE00010900          <1> 	mov	esi, Logical_DOSDisks
   144 00007893 01C6                <1> 	add	esi, eax
   145 00007895 8A06                <1> 	mov	al, [esi+LD_Name] 
   146 00007897 3C41                <1> 	cmp	al, 'A'
   147 00007899 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   148                              <1> 
   149 0000789B 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   150 0000789E 08E4                <1> 	or	ah, ah
   151 000078A0 7506                <1> 	jnz	short loc_get_current_drive_3
   152                              <1> 
   153                              <1> 	;xor	ah, ah ; mov ah, 0
   154 000078A2 8826                <1> 	mov	[esi], ah
   155 000078A4 31C9                <1> 	xor	ecx, ecx
   156 000078A6 EB1C                <1> 	jmp	short loc_get_current_drive_4
   157                              <1> 
   158                              <1> loc_get_current_drive_3:
   159 000078A8 BF[DFDB0000]        <1>         mov     edi, PATH_Array
   160 000078AD 57                  <1> 	push	edi
   161 000078AE 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   162 000078B4 B920000000          <1> 	mov	ecx, 32
   163 000078B9 F3A5                <1> 	rep	movsd
   164 000078BB 5E                  <1> 	pop	esi ; Path Array Address
   165 000078BC 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   166                              <1> 	;
   167 000078BD E841FFFFFF          <1> 	call	set_current_directory_string
   168 000078C2 89FE                <1> 	mov	esi, edi
   169                              <1> 
   170                              <1> loc_get_current_drive_4:
   171 000078C4 30C0                <1> 	xor	al, al
   172 000078C6 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 000078C7 8825[6DDC0000]      <1> 	mov	[CD_COMMAND], ah
   197 000078CD 803E2F              <1> 	cmp	byte [esi], '/'
   198 000078D0 7505                <1> 	jne	short loc_ccd_cdir_level
   199 000078D2 46                  <1> 	inc	esi
   200 000078D3 30C0                <1> 	xor	al, al
   201 000078D5 EB05                <1> 	jmp	short loc_ccd_parse_path_name
   202                              <1> loc_ccd_cdir_level:
   203 000078D7 A0[7CD30000]        <1> 	mov	al, [Current_Dir_Level]
   204                              <1> loc_ccd_parse_path_name:
   205 000078DC 88C4                <1> 	mov	ah, al
   206 000078DE BF[DFDB0000]        <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 000078E3 0FB6C8              <1> 	movzx	ecx, al
   218 000078E6 FEC1                <1> 	inc	cl
   219 000078E8 C0E104              <1> 	shl	cl, 4
   220 000078EB 01CF                <1> 	add	edi, ecx
   221 000078ED B107                <1> 	mov	cl, 7
   222 000078EF 28C1                <1> 	sub	cl, al
   223 000078F1 C0E102              <1> 	shl	cl, 2
   224 000078F4 89C3                <1> 	mov	ebx, eax
   225 000078F6 31C0                <1> 	xor	eax, eax ; 0
   226 000078F8 F3AB                <1> 	rep	stosd
   227 000078FA 89D8                <1> 	mov	eax, ebx
   228                              <1> 
   229 000078FC BF[DFDB0000]        <1> 	mov	edi, PATH_Array
   230                              <1> 
   231 00007901 803E20              <1> 	cmp	byte [esi], 20h
   232 00007904 F5                  <1> 	cmc
   233 00007905 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   234                              <1> 
   235                              <1> 		; ESI = Path name
   236                              <1> 		; AL = CCD_Level
   237 00007907 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 0000790C 9C                  <1> 	pushf
   244                              <1> 
   245                              <1> 	;mov	[CCD_Level], al
   246                              <1>         ;mov	[Last_Dir_Level], ah
   247 0000790D 66A3[63DC0000]      <1> 	mov	[CCD_Level], ax
   248                              <1> 
   249 00007913 31DB                <1> 	xor	ebx, ebx
   250 00007915 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
   251 0000791B BE00010900          <1> 	mov	esi, Logical_DOSDisks
   252 00007920 01DE                <1> 	add	esi, ebx
   253                              <1> 
   254 00007922 9D                  <1> 	popf 
   255 00007923 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   256                              <1> 
   257 00007925 8935[5FDC0000]      <1> 	mov	[CCD_DriveDT], esi
   258                              <1> 
   259 0000792B 3C07                <1> 	cmp	al, 7
   260 0000792D 7209                <1> 	jb	short loc_ccd_load_child_dir
   261                              <1> 
   262                              <1> loc_ccd_bad_path_name_retn:
   263 0000792F 87F7                <1> 	xchg	esi, edi
   264                              <1> 	; DOS Error Code 
   265 00007931 B818000000          <1> 	mov	eax, 18h ; Bad request structure length 
   266 00007936 F9                  <1> 	stc
   267                              <1> loc_ccd_retn_p:
   268 00007937 C3                  <1> 	retn
   269                              <1> 
   270                              <1> loc_ccd_load_child_dir:
   271                              <1> 	; AL = CCD_Level
   272 00007938 08C0                <1> 	or	al, al
   273 0000793A 7468                <1> 	jz	short loc_ccd_load_root_dir
   274                              <1> 
   275 0000793C 6689C1              <1> 	mov	cx, ax
   276 0000793F C0E004              <1> 	shl	al, 4
   277 00007942 0FB6F0              <1> 	movzx	esi, al
   278 00007945 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   279                              <1> 
   280 00007947 8B460C              <1> 	mov	eax, [esi+12]
   281 0000794A 38E9                <1> 	cmp	cl, ch
   282 0000794C 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   283 00007952 A3[78D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   284                              <1> 
   285                              <1> loc_ccd_load_child_dir_next:
   286 00007957 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   287                              <1> 
   288                              <1>  	; Directory attribute : 10h
   289 0000795A B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   290                              <1> 	;mov	ah, 11001000b ; C8h
   291                              <1> 	; Volume name attribute: 8h
   292 0000795C B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   293                              <1> 
   294 0000795E 6631C9              <1> 	xor	cx, cx  
   295 00007961 E8B5010000          <1> 	call	locate_current_dir_file
   296 00007966 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   297                              <1> 
   298                              <1> 	 ; 19/02/2016
   299                              <1> 	;mov	edi, [CCD_DriveDT]
   300 00007968 8A25[63DC0000]      <1> 	mov	ah, [CCD_Level]
   301 0000796E 803D[6DDC0000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   302 00007975 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 00007977 88E1                <1> 	mov	cl, ah
   308 00007979 50                  <1> 	push	eax
   309 0000797A E8E3000000          <1> 	call	loc_ccd_save_current_dir
   310 0000797F 58                  <1> 	pop	eax
   311                              <1> loc_ccd_load_child_dir_err:            
   312 00007980 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   313 00007982 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   314 00007984 F9                  <1> 	stc
   315 00007985 C3                  <1> 	retn
   316                              <1> 
   317                              <1> loc_ccd_path_not_found_retn:
   318 00007986 B003                <1> 	mov	al, 3	; Path not found
   319 00007988 C3                  <1> 	retn
   320                              <1> 
   321                              <1> loc_ccd_load_FAT_root_dir:
   322 00007989 803D[7DD30000]02    <1> 	cmp	byte [Current_FATType], 2
   323 00007990 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   324                              <1> 
   325                              <1> 	;mov	esi, [CCD_DriveDT]
   326                              <1> 	;push	esi
   327 00007992 E8961D0000          <1> 	call	load_FAT_root_directory
   328                              <1> 	;pop	edi ; Dos Drv Description Table
   329                              <1> 
   330 00007997 89F7                <1> 	mov	edi, esi
   331 00007999 BE[DFDB0000]        <1> 	mov	esi, PATH_Array
   332 0000799E 7297                <1> 	jc	short loc_ccd_retn_p
   333                              <1> 
   334 000079A0 31C0                <1> 	xor	eax, eax
   335 000079A2 EB78                <1>         jmp	short loc_ccd_set_cdfc
   336                              <1> 
   337                              <1> loc_ccd_load_root_dir:
   338 000079A4 803D[7DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   339 000079AB 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   340                              <1> 
   341                              <1> loc_ccd_load_FS_root_dir:
   342 000079AD E8421E0000          <1> 	call	load_FS_root_directory
   343 000079B2 EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   344                              <1> 
   345                              <1> loc_ccd_load_FS_sub_directory_next:
   346 000079B4 E83C1E0000          <1> 	call	load_FS_sub_directory
   347 000079B9 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 000079BB 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   352 000079BF C1E010              <1> 	shl	eax, 16
   353 000079C2 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   354                              <1> 
   355 000079C6 8B35[5FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   356 000079CC 803D[7DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   357 000079D3 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   358                              <1> 	;push	esi
   359 000079D5 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 000079DA BE[DFDB0000]        <1> 	mov	esi, PATH_Array
   365 000079DF 7264                <1> 	jc	short loc_ccd_retn_c
   366                              <1> 
   367 000079E1 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   368                              <1> 
   369 000079E6 FE05[63DC0000]      <1> 	inc	byte [CCD_Level]
   370 000079EC 0FB61D[63DC0000]    <1> 	movzx	ebx, byte [CCD_Level]
   371 000079F3 C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   372 000079F6 01DE                <1> 	add	esi, ebx ; 19/02/2016
   373 000079F8 89460C              <1> 	mov	[esi+12], eax
   374 000079FB EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   375                              <1> 
   376                              <1> loc_ccd_load_FAT32_root_dir:
   377 000079FD BE[DFDB0000]        <1> 	mov	esi, PATH_Array
   378 00007A02 8B460C              <1> 	mov	eax, [esi+12]
   379 00007A05 8B35[5FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   380                              <1>  
   381                              <1> loc_ccd_load_FAT_sub_directory:
   382                              <1> 	;push	esi
   383 00007A0B 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 00007A10 BE[DFDB0000]        <1> 	mov	esi, PATH_Array
   389 00007A15 722E                <1> 	jc	short loc_ccd_retn_c
   390                              <1> 
   391 00007A17 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   392                              <1> 
   393                              <1> loc_ccd_set_cdfc:
   394 00007A1C 8A0D[63DC0000]      <1> 	mov	cl, [CCD_Level]
   395 00007A22 880D[7CD30000]      <1> 	mov	[Current_Dir_Level], cl
   396 00007A28 A3[78D30000]        <1> 	mov	[Current_Dir_FCluster], eax
   397                              <1> 
   398 00007A2D 8A2D[64DC0000]      <1> 	mov	ch, [Last_Dir_Level]
   399 00007A33 38E9                <1> 	cmp	cl, ch 
   400 00007A35 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   401                              <1> 	
   402 00007A3B 803D[6DDC0000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   403 00007A42 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 00007A44 F8                  <1> 	clc
   409                              <1> 
   410                              <1> loc_ccd_retn_c:
   411 00007A45 8B3D[5FDC0000]      <1> 	mov	edi, [CCD_DriveDT]
   412 00007A4B C3                  <1> 	retn
   413                              <1> 
   414                              <1> loc_ccd_load_sub_directory:
   415 00007A4C 8B35[5FDC0000]      <1> 	mov	esi, [CCD_DriveDT]
   416 00007A52 803D[7DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   417 00007A59 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   418 00007A5B E8951D0000          <1> 	call	load_FS_sub_directory
   419 00007A60 EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   420                              <1> 
   421                              <1> loc_ccd_save_current_dir:
   422 00007A62 BE[DFDB0000]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   423 00007A67 8B3D[5FDC0000]      <1> 	mov	edi, [CCD_DriveDT]
   424 00007A6D 57                  <1> 	push	edi
   425 00007A6E 83C77F              <1>         add     edi, LD_CDirLevel
   426 00007A71 880F                <1> 	mov	[edi], cl
   427 00007A73 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   428 00007A74 56                  <1> 	push	esi
   429                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   430 00007A75 66B92000            <1> 	mov	cx, 32
   431 00007A79 F3A5                <1> 	rep	movsd
   432                              <1> 	; Current directory has been saved to 
   433                              <1> 	; the DOS drive description table, cdir area !
   434 00007A7B 5E                  <1> 	pop	esi  ; PATH_Array
   435 00007A7C 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   436                              <1> 
   437 00007A7D 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 00007A7E 88C4                <1> 	mov	ah, al
   460 00007A80 66A3[04DD0000]      <1> 	mov	[PATH_CDLevel], ax
   461                              <1> repeat_ppdn_check_slash:
   462 00007A86 AC                  <1> 	lodsb
   463 00007A87 3C2F                <1> 	cmp	al, '/'
   464 00007A89 74FB                <1> 	je	short repeat_ppdn_check_slash
   465 00007A8B 3C21                <1> 	cmp	al, 21h
   466 00007A8D 7219                <1> 	jb	short loc_ppdn_retn
   467 00007A8F 57                  <1> 	push	edi
   468                              <1> loc_ppdn_get_dir_name:
   469 00007A90 B90C000000          <1> 	mov	ecx, 12
   470 00007A95 BF[06DD0000]        <1> 	mov	edi, Dir_File_Name
   471                              <1> repeat_ppdn_get_dir_name:
   472 00007A9A AA                  <1> 	stosb
   473 00007A9B AC                  <1> 	lodsb
   474 00007A9C 3C2F                <1> 	cmp	al, '/'
   475 00007A9E 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   476 00007AA0 3C20                <1> 	cmp	al, 20h
   477 00007AA2 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   478 00007AA4 E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   479 00007AA6 5F                  <1> 	pop	edi
   480 00007AA7 F9                  <1> 	stc
   481                              <1> loc_ppdn_retn:
   482 00007AA8 C3                  <1> 	retn
   483                              <1> 
   484                              <1> loc_ppdn_end_of_path_scan:
   485 00007AA9 4E                  <1> 	dec	esi
   486                              <1> loc_check_level_dot_conv_dir_name:
   487 00007AAA 31C0                <1> 	xor	eax, eax
   488 00007AAC AA                  <1> 	stosb
   489 00007AAD 89F3                <1> 	mov	ebx, esi
   490 00007AAF BE[06DD0000]        <1> 	mov	esi, Dir_File_Name
   491 00007AB4 AC                  <1> 	lodsb
   492                              <1> repeat_ppdn_name_check_dot:
   493 00007AB5 3C2E                <1> 	cmp	al, '.'
   494 00007AB7 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   495                              <1> repeat_ppdn_name_dot_dot:
   496 00007AB9 AC                  <1> 	lodsb
   497 00007ABA 3C2E                <1> 	cmp	al, '.'
   498 00007ABC 743E                <1> 	je	short loc_ppdn_dot_dot
   499 00007ABE 3C21                <1> 	cmp	al, 21h
   500 00007AC0 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   501                              <1> loc_ppdn_convert_sub_dir_name:
   502 00007AC2 8A25[05DD0000]      <1> 	mov	ah, [PATH_Level]
   503 00007AC8 80FC07              <1> 	cmp	ah, 7
   504 00007ACB 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   505 00007ACD FEC4                <1> 	inc	ah  
   506 00007ACF 8825[05DD0000]      <1> 	mov	[PATH_Level], ah
   507 00007AD5 BE[06DD0000]        <1> 	mov	esi, Dir_File_Name
   508                              <1> 	;mov	edi, [PATH_Array_Ptr]
   509 00007ADA B010                <1> 	mov	al, 16
   510 00007ADC F6E4                <1> 	mul	ah
   511 00007ADE 8B3C24              <1> 	mov	edi, [esp]
   512                              <1> 	;push	edi 
   513 00007AE1 01C7                <1> 	add	edi, eax
   514 00007AE3 E828030000          <1> 	call	convert_file_name
   515                              <1> 	;pop	edi
   516                              <1> pass_ppdn_convert_sub_dir_name:
   517 00007AE8 89DE                <1> 	mov	esi, ebx
   518                              <1> repeat_ppdn_check_last_slash:
   519 00007AEA AC                  <1> 	lodsb
   520 00007AEB 3C2F                <1> 	cmp	al, '/'
   521 00007AED 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   522 00007AEF 3C21                <1> 	cmp	al, 21h
   523 00007AF1 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   524                              <1> end_of_parse_dir_name:
   525 00007AF3 5F                  <1> 	pop	edi
   526 00007AF4 F5                  <1> 	cmc  
   527                              <1> 	;mov	al, [PATH_CDLevel]
   528                              <1> 	;mov	ah, [PATH_Level]
   529 00007AF5 66A1[04DD0000]      <1> 	mov	ax, [PATH_CDLevel]
   530 00007AFB C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_ppdn_dot_dot:
   533 00007AFC AC                  <1> 	lodsb
   534 00007AFD 3C21                <1> 	cmp	al, 21h
   535 00007AFF 73F2                <1> 	jnb	short end_of_parse_dir_name 
   536                              <1> loc_ppdn_dot_dot_prev_level:
   537 00007B01 66A1[04DD0000]      <1> 	mov	ax, [PATH_CDLevel]
   538 00007B07 80EC01              <1> 	sub	ah, 1
   539 00007B0A 80D400              <1> 	adc	ah, 0
   540 00007B0D 38E0                <1> 	cmp	al, ah
   541 00007B0F 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   542 00007B11 88E0                <1> 	mov	al, ah
   543                              <1> pass_ppdn_set_al_to_ah:
   544 00007B13 66A3[04DD0000]      <1> 	mov	[PATH_CDLevel], ax
   545 00007B19 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 00007B1B 8935[67DC0000]      <1> 	mov	[CDLF_FNAddress], esi
   590 00007B21 66A3[65DC0000]      <1> 	mov	[CDLF_AttributesMask], ax
   591 00007B27 66890D[6BDC0000]    <1> 	mov	[CDLF_DEType], cx
   592                              <1> 
   593 00007B2E 31DB                <1> 	xor	ebx, ebx
   594 00007B30 881D[7CDC0000]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   595                              <1> 
   596 00007B36 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
   597 00007B3C 381D[A8DB0000]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   598 00007B42 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   599 00007B44 8A1D[A6DB0000]      <1>         mov     bl, [DirBuff_DRV]
   600 00007B4A 80EB41              <1> 	sub	bl, 'A'
   601 00007B4D 38DF                <1> 	cmp	bh, bl
   602 00007B4F 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   603 00007B51 8B15[ADDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
   604 00007B57 3B15[78D30000]      <1> 	cmp	edx, [Current_Dir_FCluster]
   605 00007B5D 7412                <1> 	je	short loc_cdir_locatefile_search
   606                              <1> 
   607                              <1> loc_lcdf_reload_current_dir1:
   608 00007B5F 30DB                <1> 	xor	bl, bl
   609                              <1> loc_lcdf_reload_current_dir2:
   610 00007B61 89DE                <1> 	mov	esi, ebx
   611 00007B63 81C600010900        <1>         add     esi, Logical_DOSDisks
   612 00007B69 E872000000          <1> 	call	reload_current_directory 
   613 00007B6E 735B                <1> 	jnc	short loc_locatefile_search_again 
   614 00007B70 C3                  <1> 	retn  
   615                              <1> 
   616                              <1> loc_cdir_locatefile_search:
   617 00007B71 31DB                <1> 	xor	ebx, ebx
   618 00007B73 E8A5000000          <1> 	call	find_directory_entry
   619 00007B78 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   620                              <1> 
   621                              <1> loc_locatefile_check_stc_reason:
   622 00007B7A 08ED                <1> 	or	ch, ch
   623 00007B7C 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   624                              <1> 
   625                              <1> loc_locatefile_check_next_entryblock:
   626 00007B7E 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
   627 00007B84 28DB                <1> 	sub	bl, bl
   628 00007B86 0FB7F3              <1> 	movzx	esi, bx
   629 00007B89 81C600010900        <1>         add     esi, Logical_DOSDisks
   630                              <1> 
   631 00007B8F 803D[7CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
   632 00007B96 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   633                              <1>             
   634 00007B98 803D[7DD30000]01    <1> 	cmp	byte [Current_FATType], 1
   635 00007B9F 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   636 00007BA1 C3                  <1> 	retn  
   637                              <1> 
   638                              <1> loc_locatefile_check_FAT_type:
   639 00007BA2 803D[7DD30000]03    <1> 	cmp	byte [Current_FATType], 3
   640 00007BA9 7218                <1> 	jb	short loc_cdir_locate_file_retn
   641                              <1> 
   642                              <1> loc_locatefile_load_subdir_cluster:
   643 00007BAB A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   644 00007BB0 E81D1A0000          <1> 	call	get_next_cluster
   645 00007BB5 730D                <1> 	jnc	short loc_locatefile_next_cluster
   646 00007BB7 09C0                <1> 	or	eax, eax
   647 00007BB9 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   648 00007BBB F9                  <1> 	stc
   649                              <1> loc_locatefile_file_notfound:
   650 00007BBC B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   651 00007BC1 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 00007BC2 F5                  <1> 	cmc ;stc
   657                              <1> loc_cdir_locate_file_retn:
   658 00007BC3 C3                  <1> 	retn
   659                              <1> 
   660                              <1> loc_locatefile_next_cluster:
   661 00007BC4 E8EF1B0000          <1> 	call	load_FAT_sub_directory
   662                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   663 00007BC9 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   664                              <1> 
   665                              <1> loc_locatefile_search_again:
   666 00007BCB 8B35[67DC0000]      <1> 	mov	esi, [CDLF_FNAddress] 
   667 00007BD1 66A1[65DC0000]      <1> 	mov	ax, [CDLF_AttributesMask]
   668 00007BD7 668B0D[6BDC0000]    <1> 	mov	cx, [CDLF_DEType] 
   669 00007BDE 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 00007BE0 A0[7DD30000]        <1> 	mov	al, [Current_FATType]
   681 00007BE5 3C02                <1> 	cmp	al, 2
   682 00007BE7 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   683 00007BE9 8A25[7CD30000]      <1> 	mov	ah, [Current_Dir_Level]
   684 00007BEF 08C0                <1> 	or	al, al
   685 00007BF1 740A                <1> 	jz	short loc_reload_FS_directory
   686 00007BF3 08E4                <1> 	or	ah, ah
   687 00007BF5 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   688                              <1> loc_reload_FAT_12_16_root_directory:
   689 00007BF7 E8311B0000          <1> 	call	load_FAT_root_directory
   690 00007BFC C3                  <1> 	retn
   691                              <1> loc_reload_FS_directory:
   692 00007BFD 20E4                <1> 	and	ah, ah
   693 00007BFF 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   694                              <1> loc_reload_FS_root_directory: 
   695 00007C01 E8EE1B0000          <1> 	call	load_FS_root_directory
   696 00007C06 C3                  <1> 	retn
   697                              <1> loc_reload_FS_sub_directory:
   698 00007C07 A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
   699 00007C0C E8E41B0000          <1> 	call	load_FS_sub_directory
   700 00007C11 C3                  <1> 	retn 
   701                              <1> loc_reload_FAT_sub_directory:
   702 00007C12 A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
   703 00007C17 E89C1B0000          <1> 	call	load_FAT_sub_directory
   704 00007C1C 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 00007C1D 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   750 00007C24 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   751                              <1> 
   752                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   753                              <1> 
   754 00007C2A BF00000800          <1>   	mov	edi, Directory_Buffer
   755 00007C2F 66A3[78DC0000]      <1> 	mov	[FDE_AttrMask], ax
   756                              <1> 
   757 00007C35 29C0                <1> 	sub	eax, eax
   758                              <1>             
   759                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   760 00007C37 66A3[7ADC0000]      <1> 	mov	[AmbiguousFileName], ax ; 0
   761                              <1> 
   762 00007C3D 6689D8              <1> 	mov	ax, bx
   763 00007C40 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   764 00007C44 01C7                <1> 	add     edi, eax
   765                              <1> 
   766 00007C46 08ED                <1> 	or	ch, ch
   767 00007C48 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   768                              <1> 
   769 00007C4E 08C9                <1> 	or      cl, cl
   770 00007C50 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   771                              <1>  
   772                              <1> check_find_dir_entry:
   773 00007C56 66A1[78DC0000]      <1> 	mov	ax, [FDE_AttrMask]
   774 00007C5C 8A2F                <1> 	mov	ch, [edi]
   775 00007C5E 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   776 00007C61 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   777 00007C67 56                  <1> 	push	esi
   778 00007C68 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   779 00007C6B 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   780 00007C6E 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   781                              <1> 
   782 00007C70 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   783 00007C73 7505                <1> 	jne     short loc_check_attributes_mask
   784 00007C75 E8ED010000          <1> 	call	save_longname_sub_component
   785                              <1> 
   786                              <1> loc_check_attributes_mask:
   787 00007C7A 88C6                <1> 	mov	dh, al
   788 00007C7C 20D6                <1> 	and	dh, dl    
   789 00007C7E 38F0                <1> 	cmp	al, dh
   790 00007C80 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   791 00007C86 20D4                <1> 	and	ah, dl
   792 00007C88 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   793 00007C8E 80FA0F              <1> 	cmp	dl, 0Fh
   794 00007C91 751A                <1> 	jne	short pass_direntry_attr_check
   795                              <1> 
   796 00007C93 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   797 00007C95 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   798                              <1> 
   799 00007C9B 5E                  <1> 	pop	esi
   800 00007C9C 6631C0              <1> 	xor	ax, ax
   801 00007C9F 8A35[7CDC0000]      <1> 	mov	dh, [PreviousAttr]
   802 00007CA5 66891D[A9DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   803 00007CAC C3                  <1> 	retn
   804                              <1> 
   805                              <1> pass_direntry_attr_check:
   806 00007CAD 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   807 00007CAF B908000000          <1> 	mov	ecx, 8
   808                              <1> loc_lodsb_find_dir:
   809 00007CB4 AC                  <1> 	lodsb
   810 00007CB5 3C2A                <1> 	cmp	al, '*'
   811 00007CB7 7508                <1> 	jne	short pass_fde_ambiguous1_check
   812 00007CB9 FE05[7BDC0000]      <1>         inc     byte [AmbiguousFileName+1]
   813 00007CBF EB28                <1> 	jmp	short loc_check_direntry_extension
   814                              <1> 
   815                              <1> pass_fde_ambiguous1_check:
   816 00007CC1 3C3F                <1> 	cmp	al, '?'
   817 00007CC3 750D                <1> 	jne	short pass_fde_ambiguous2_check
   818 00007CC5 FE05[7ADC0000]      <1> 	inc	byte [AmbiguousFileName]
   819 00007CCB 803F20              <1> 	cmp	byte [edi], 20h
   820 00007CCE 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   821 00007CD0 EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   822                              <1> 
   823                              <1> pass_fde_ambiguous2_check:
   824 00007CD2 3C20                <1> 	cmp	al, 20h
   825 00007CD4 750C                <1> 	jne	short loc_scasb_find_dir
   826 00007CD6 803F20              <1> 	cmp	byte [edi], 20h
   827 00007CD9 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   828 00007CDB EB0C                <1> 	jmp	short loc_check_direntry_extension
   829                              <1> 
   830                              <1> loc_find_dir_next_entry_prevdeleted:
   831 00007CDD 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   832 00007CE0 EB5E                <1> 	jmp	short loc_find_dir_next_entry
   833                              <1> 
   834                              <1> loc_scasb_find_dir:
   835 00007CE2 3A07                <1> 	cmp	al, [edi]
   836 00007CE4 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   837                              <1> loc_scasb_find_dir_inc_di:
   838 00007CE6 47                  <1> 	inc	edi
   839 00007CE7 E2CB                <1> 	loop	loc_lodsb_find_dir
   840                              <1> 
   841                              <1> loc_check_direntry_extension:
   842 00007CE9 BE08000000          <1> 	mov	esi, 8
   843 00007CEE 89F7                <1> 	mov	edi, esi ; 8
   844 00007CF0 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   845 00007CF3 01EF                <1> 	add	edi, ebp
   846 00007CF5 B103                <1> 	mov	cl, 3
   847                              <1> loc_lodsb_find_dir_ext:
   848 00007CF7 AC                  <1> 	lodsb
   849 00007CF8 3C2A                <1> 	cmp	al, '*'
   850 00007CFA 7508                <1> 	jne	short pass_fde_ambiguous3_check
   851 00007CFC FE05[7BDC0000]      <1> 	inc	byte [AmbiguousFileName+1]
   852 00007D02 EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   853                              <1> 
   854                              <1> pass_fde_ambiguous3_check:
   855 00007D04 3C3F                <1> 	cmp	al, '?'
   856 00007D06 750D                <1> 	jne	short pass_fde_ambiguous4_check
   857 00007D08 FE05[7ADC0000]      <1> 	inc	byte [AmbiguousFileName]
   858 00007D0E 803F20              <1> 	cmp	byte [edi], 20h
   859 00007D11 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   860 00007D13 EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   861                              <1> 
   862                              <1> pass_fde_ambiguous4_check:
   863 00007D15 3C20                <1> 	cmp	al, 20h
   864 00007D17 7541                <1> 	jne	short loc_scasb_find_dir_ext
   865 00007D19 803F20              <1> 	cmp	byte [edi], 20h
   866 00007D1C 7404                <1> 	je	short loc_find_dir_proper_direntry
   867                              <1> 
   868                              <1> loc_find_dir_next_entry_ebp:
   869 00007D1E 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   870 00007D20 EB1E                <1> 	jmp	short loc_find_dir_next_entry
   871                              <1> 
   872                              <1> loc_find_dir_proper_direntry:
   873 00007D22 30C9                <1> 	xor	cl, cl
   874                              <1> loc_find_dir_proper_direntry_1:
   875 00007D24 5E                  <1> 	pop	esi
   876 00007D25 89EF                <1>         mov     edi, ebp
   877 00007D27 8A2F                <1> 	mov	ch, [edi]
   878 00007D29 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   879 00007D2C 66A1[7ADC0000]      <1> 	mov	ax, [AmbiguousFileName]
   880                              <1> loc_find_dir_proper_direntry_2:
   881 00007D32 8A35[7CDC0000]      <1> 	mov     dh, [PreviousAttr]
   882 00007D38 66891D[A9DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   883 00007D3F C3                  <1> 	retn
   884                              <1> 
   885                              <1> loc_find_dir_next_entry:
   886 00007D40 8815[7CDC0000]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   887                              <1> loc_find_dir_next_entry_1:
   888 00007D46 5E                  <1> 	pop	esi
   889 00007D47 83C720              <1> 	add	edi, 32
   890                              <1> 	;inc	word [DirBuff_EntryCounter]
   891 00007D4A 6643                <1> 	inc	bx
   892 00007D4C 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   893 00007D53 770E                <1> 	ja	short loc_ffde_stc_retn_255
   894 00007D55 E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   895                              <1> 
   896                              <1> loc_scasb_find_dir_ext:
   897 00007D5A 3A07                <1> 	cmp	al, [edi]
   898 00007D5C 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   899                              <1> loc_scasb_find_dir_ext_inc_di:
   900 00007D5E 47                  <1> 	inc	edi
   901 00007D5F E296                <1> 	loop    loc_lodsb_find_dir_ext
   902 00007D61 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 00007D63 31C9                <1> 	xor	ecx, ecx
   907 00007D65 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 00007D66 B802000000          <1> 	mov	eax, 2 ; File Not Found
   913 00007D6B 8A35[7CDC0000]      <1> 	mov	dh, [PreviousAttr]
   914 00007D71 66891D[A9DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   915 00007D78 F9                  <1> 	stc
   916 00007D79 C3                  <1> 	retn
   917                              <1> 
   918                              <1> loc_find_free_deleted_entry_0:
   919 00007D7A 66A1[78DC0000]      <1> 	mov	ax, [FDE_AttrMask]
   920 00007D80 8A2F                <1> 	mov	ch, [edi]
   921 00007D82 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   922 00007D85 08C9                <1> 	or	cl, cl 
   923 00007D87 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 00007D89 80F9FF              <1> 	cmp	cl, 0FFh
   927 00007D8C 7432                <1> 	je	short loc_find_free_deleted_entry_1
   928 00007D8E EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   929                              <1> 
   930                              <1> loc_check_ffde_0_repeat:
   931 00007D90 08ED                <1> 	or	ch, ch
   932 00007D92 7511                <1> 	jnz	short loc_check_ffde_0_next
   933                              <1> 
   934                              <1> loc_check_ffde_retn_2:
   935 00007D94 6629C0              <1> 	sub	ax, ax
   936 00007D97 8A35[7CDC0000]      <1> 	mov	dh, [PreviousAttr]
   937 00007D9D 66891D[A9DB0000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   938 00007DA4 C3                  <1> 	retn
   939                              <1>  
   940                              <1> loc_check_ffde_0_next:
   941 00007DA5 6643                <1> 	inc	bx
   942 00007DA7 83C720              <1> 	add	edi, 32
   943                              <1> 	;inc	word [DirBuff_EntryCounter]
   944                              <1> 	 
   945 00007DAA 663B1D[ABDB0000]    <1>         cmp	bx, [DirBuff_LastEntry]
   946 00007DB1 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   947 00007DB3 8815[7CDC0000]      <1> 	mov	[PreviousAttr], dl
   948 00007DB9 8A2F                <1> 	mov	ch, [edi]
   949 00007DBB 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   950 00007DBE EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   951                              <1> 
   952                              <1> loc_find_free_deleted_entry_1:
   953 00007DC0 28D2                <1> 	sub	dl, dl      
   954                              <1> loc_find_free_deleted_entry_2:
   955 00007DC2 20ED                <1> 	and	ch, ch  
   956 00007DC4 74CE                <1> 	jz	short loc_check_ffde_retn_2
   957 00007DC6 80FDE5              <1> 	cmp	ch, 0E5h
   958 00007DC9 74C9                <1> 	je	short loc_check_ffde_retn_2
   959 00007DCB 6643                <1> 	inc	bx
   960 00007DCD 83C720              <1> 	add	edi, 32
   961 00007DD0 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   962 00007DD7 778A                <1> 	ja	short loc_ffde_stc_retn_255
   963 00007DD9 8A2F                <1> 	mov	ch, [edi]
   964 00007DDB EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   965                              <1> 
   966                              <1> pass_loc_check_ffde_0_err:
   967 00007DDD 38CD                <1> 	cmp	ch, cl
   968 00007DDF 741F                <1> 	je	short loc_check_ffde_attrib 
   969                              <1> 
   970 00007DE1 6643                <1> 	inc	bx
   971 00007DE3 83C720              <1> 	add	edi, 32
   972 00007DE6 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   973 00007DED 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   974 00007DF3 8815[7CDC0000]      <1> 	mov	[PreviousAttr], dl
   975 00007DF9 8A2F                <1> 	mov	ch, [edi]
   976 00007DFB 8A570B              <1> 	mov	dl, [edi+0Bh]
   977 00007DFE EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   978                              <1> 
   979                              <1> loc_check_ffde_attrib:
   980 00007E00 88C6                <1> 	mov	dh, al
   981 00007E02 20D6                <1> 	and	dh, dl    
   982 00007E04 38F0                <1> 	cmp	al, dh
   983 00007E06 759D                <1> 	jne	short loc_check_ffde_0_next
   984 00007E08 20D4                <1> 	and	ah, dl
   985 00007E0A 7599                <1> 	jnz	short loc_check_ffde_0_next
   986 00007E0C 30C9                <1> 	xor	cl, cl 
   987 00007E0E 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 00007E10 56                  <1> 	push	esi  
  1006 00007E11 57                  <1> 	push	edi
  1007                              <1> 
  1008 00007E12 B90B000000          <1> 	mov	ecx, 11
  1009 00007E17 B020                <1> 	mov	al, 20h
  1010 00007E19 F3AA                <1> 	rep	stosb
  1011                              <1> 
  1012 00007E1B 8B3C24              <1> 	mov	edi, [esp]
  1013                              <1> 
  1014 00007E1E 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 00007E20 B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1024                              <1> loc_check_first_dot:
  1025 00007E22 8A06                <1> 	mov	al, [esi]
  1026 00007E24 3C2E                <1> 	cmp	al, 2Eh
  1027 00007E26 750C                <1> 	jne	short pass_check_first_dot
  1028 00007E28 8807                <1> 	mov	[edi], al
  1029 00007E2A 47                  <1> 	inc	edi
  1030 00007E2B 46                  <1> 	inc	esi
  1031 00007E2C FEC9                <1> 	dec	cl
  1032 00007E2E 75F2                <1> 	jnz	short loc_check_first_dot
  1033                              <1> 	;;(ecx <= 12)
  1034                              <1> 	;;loop	loc_check_first_dot 
  1035 00007E30 EB30                <1> 	jmp	short stop_convert_file
  1036                              <1> 
  1037                              <1> loc_get_fchar:
  1038 00007E32 8A06                <1> 	mov	al, [esi]
  1039                              <1> pass_check_first_dot:
  1040 00007E34 3C61                <1> 	cmp	al, 61h ; 'a'
  1041 00007E36 7208                <1> 	jb	short pass_name_capitalize
  1042 00007E38 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1043 00007E3A 7704                <1> 	ja	short pass_name_capitalize
  1044 00007E3C 24DF                <1> 	and	al, 0DFh
  1045 00007E3E 8806                <1> 	mov	[esi], al
  1046                              <1> pass_name_capitalize:
  1047 00007E40 3C21                <1> 	cmp	al, 21h
  1048 00007E42 721E                <1> 	jb	short stop_convert_file
  1049 00007E44 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1050 00007E46 750C                <1> 	jne	short pass_dot_space
  1051                              <1> add_dot_space: 
  1052 00007E48 80F904              <1> 	cmp	cl, 4
  1053 00007E4B 760E                <1> 	jna	short inc_and_loop
  1054 00007E4D 47                  <1> 	inc	edi
  1055 00007E4E FECD                <1> 	dec	ch ; 06/03/2016
  1056 00007E50 FEC9                <1> 	dec	cl
  1057 00007E52 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 00007E54 8807                <1> 	mov	[edi], al
  1069                              <1> loc_after_double_dot:
  1070                              <1> 	; 06/03/2016
  1071 00007E56 FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1072 00007E58 740A                <1> 	jz	short stop_convert_file_x
  1073 00007E5A 47                  <1> 	inc	edi
  1074                              <1> inc_and_loop:
  1075 00007E5B FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1076 00007E5D 7403                <1> 	jz	short stop_convert_file	
  1077 00007E5F 46                  <1> 	inc	esi
  1078                              <1> 	;;(ecx <= 12)
  1079                              <1> 	;;loop	loc_get_fchar
  1080 00007E60 EBD0                <1> 	jmp	short loc_get_fchar
  1081                              <1> 
  1082                              <1> stop_convert_file:
  1083                              <1> 	; 06/03/2016
  1084 00007E62 30ED                <1> 	xor	ch, ch
  1085                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1086                              <1> stop_convert_file_x:
  1087 00007E64 5F                  <1> 	pop	edi
  1088 00007E65 5E                  <1> 	pop	esi
  1089 00007E66 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 00007E67 57                  <1> 	push	edi
  1109 00007E68 56                  <1> 	push	esi
  1110                              <1> 	;push	ebx
  1111                              <1> 	;push	ecx
  1112                              <1> 	;push	edx
  1113 00007E69 50                  <1> 	push	eax
  1114                              <1>            
  1115 00007E6A 29C9                <1> 	sub	ecx, ecx
  1116                              <1> 	;sub	eax, eax
  1117 00007E6C B11A                <1> 	mov	cl, 26
  1118                              <1> 
  1119 00007E6E 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1120 00007E71 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1121 00007E73 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1122                              <1> 
  1123 00007E75 88C4                <1> 	mov	ah, al
  1124 00007E77 80EC40              <1> 	sub	ah, 40h
  1125 00007E7A 8825[7EDC0000]      <1> 	mov	[LFN_EntryLength], ah
  1126                              <1> 	
  1127 00007E80 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 00007E82 7753                <1> 	ja	short loc_pslnsc_retn
  1131                              <1> 
  1132 00007E84 2407                <1> 	and	al, 07h ; 0Fh
  1133 00007E86 A2[7DDC0000]        <1> 	mov	[LongNameFound], al
  1134                              <1> 
  1135 00007E8B FEC8                <1> 	dec	al
  1136                              <1> 	;mov	cl, 26
  1137 00007E8D F6E1                <1> 	mul	cl
  1138                              <1> 
  1139 00007E8F 89C6                <1> 	mov	esi, eax
  1140 00007E91 01CE                <1> 	add	esi, ecx
  1141                              <1> 		; to make is an ASCIZZ string
  1142                              <1> 		; with ax+26 bytes length
  1143 00007E93 81C6[80DC0000]      <1> 	add	esi, LongFileName
  1144 00007E99 66C7060000          <1> 	mov	word [esi], 0   
  1145 00007E9E EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1146                              <1> 
  1147                              <1> pass_pslnsc_last_long_entry:
  1148 00007EA0 3C04                <1> 	cmp	al, 04h
  1149 00007EA2 7733                <1> 	ja	short loc_pslnsc_retn
  1150 00007EA4 FE0D[7DDC0000]      <1> 	dec	byte [LongNameFound]
  1151 00007EAA 3A05[7DDC0000]      <1> 	cmp	al, [LongNameFound]
  1152 00007EB0 7525                <1> 	jne	short loc_pslnsc_retn
  1153                              <1> 
  1154                              <1> loc_pslsc_move_ldir_name1:
  1155 00007EB2 FEC8                <1> 	dec	al
  1156                              <1> 	;mov	cl, 26
  1157 00007EB4 F6E1                <1> 	mul	cl
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name2:
  1160 00007EB6 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1161 00007EB9 880D[7FDC0000]      <1> 	mov	[LFN_CheckSum], cl 
  1162 00007EBF 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1163 00007EC1 BF[80DC0000]        <1> 	mov	edi, LongFileName
  1164 00007EC6 01C7                <1> 	add	edi, eax
  1165 00007EC8 46                  <1> 	inc	esi
  1166 00007EC9 B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1167 00007ECB F366A5              <1> 	rep	movsw
  1168 00007ECE 83C603              <1> 	add	esi, 3
  1169 00007ED1 A5                  <1> 	movsd	; char 6 & 7 
  1170 00007ED2 A5                  <1> 	movsd	; char 8 & 9
  1171 00007ED3 A5                  <1> 	movsd	; char 10 & 11
  1172 00007ED4 46                  <1> 	inc	esi
  1173 00007ED5 46                  <1> 	inc	esi 
  1174 00007ED6 A5                  <1> 	movsd   ; char 12 & 13 
  1175                              <1> 
  1176                              <1> loc_pslnsc_retn:
  1177 00007ED7 58                  <1>  	pop	eax
  1178                              <1> 	;pop	edx
  1179                              <1> 	;pop	ecx
  1180                              <1> 	;pop	ebx
  1181 00007ED8 5E                  <1> 	pop	esi  
  1182 00007ED9 5F                  <1> 	pop	edi
  1183                              <1>  
  1184 00007EDA 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 00007EDB 57                  <1> 	push	edi
  1205 00007EDC B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1206 00007EE1 31C0                <1> 	xor	eax, eax
  1207 00007EE3 F3AB                <1> 	rep	stosd 
  1208 00007EE5 5F                  <1> 	pop	edi
  1209                              <1> 
  1210 00007EE6 668B06              <1> 	mov	ax, [esi]
  1211 00007EE9 80FC3A              <1> 	cmp	ah, ':'
  1212 00007EEC 741C                <1> 	je	short loc_ppn_change_drive
  1213 00007EEE A0[7ED30000]        <1> 	mov	al, [Current_Drv]
  1214 00007EF3 EB33                <1> 	jmp	short pass_ppn_change_drive
  1215                              <1> 
  1216                              <1> pass_ppn_cdir:
  1217 00007EF5 8B35[A2DD0000]      <1> 	mov	esi, [First_Path_Pos]
  1218 00007EFB AC                  <1> 	lodsb
  1219                              <1> loc_ppn_get_filename:
  1220 00007EFC 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 00007EFF B10C                <1> 	mov	cl, 12
  1224                              <1> loc_ppn_get_fnchar_next:
  1225 00007F01 AA                  <1> 	stosb
  1226 00007F02 AC                  <1> 	lodsb
  1227 00007F03 3C21                <1> 	cmp	al, 21h
  1228 00007F05 7274                <1> 	jb	short loc_ppn_clc_return 
  1229 00007F07 E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1230                              <1> loc_ppn_return:
  1231 00007F09 C3                  <1> 	retn
  1232                              <1> 
  1233                              <1> loc_ppn_change_drive:
  1234 00007F0A 24DF                <1> 	and	al, 0DFh
  1235 00007F0C 2C41                <1> 	sub	al, 'A'; A:
  1236 00007F0E 726F                <1> 	jc	short loc_ppn_invalid_drive
  1237 00007F10 3805[18C20000]      <1> 	cmp	[Last_DOS_DiskNo], al
  1238 00007F16 7267                <1> 	jb	short loc_ppn_invalid_drive
  1239                              <1> 
  1240 00007F18 46                  <1> 	inc	esi
  1241 00007F19 46                  <1> 	inc	esi
  1242 00007F1A 8A26                <1> 	mov	ah, [esi]
  1243 00007F1C 80FC21              <1> 	cmp	ah, 21h
  1244 00007F1F 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 00007F21 8807                <1> 	mov	[edi], al ; Drv 
  1249 00007F23 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 00007F27 C3                  <1> 	retn
  1255                              <1> 
  1256                              <1> pass_ppn_change_drive:
  1257 00007F28 8935[A2DD0000]      <1> 	mov	[First_Path_Pos], esi
  1258 00007F2E C705[A6DD0000]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1258 00007F36 0000                <1>
  1259 00007F38 AA                  <1> 	stosb
  1260 00007F39 8A06                <1> 	mov	al, [esi]
  1261                              <1> loc_scan_ppn_dslash:
  1262 00007F3B 3C2F                <1> 	cmp	al, '/'
  1263 00007F3D 7506                <1>   	jne	short loc_scan_next_slash_pos
  1264 00007F3F 8935[A6DD0000]      <1> 	mov	[Last_Slash_Pos], esi
  1265                              <1> loc_scan_next_slash_pos:
  1266 00007F45 46                  <1> 	inc	esi
  1267 00007F46 8A06                <1> 	mov	al, [esi]
  1268 00007F48 3C20                <1> 	cmp	al, 20h
  1269 00007F4A 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1270 00007F4C 833D[A6DD0000]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1271 00007F53 76A0                <1> 	jna	short pass_ppn_cdir
  1272                              <1> 	
  1273 00007F55 8B0D[A6DD0000]      <1> 	mov	ecx, [Last_Slash_Pos]
  1274 00007F5B 8B35[A2DD0000]      <1> 	mov	esi, [First_Path_Pos]
  1275 00007F61 29F1                <1> 	sub	ecx, esi
  1276 00007F63 41                  <1> 	inc	ecx
  1277                              <1> 	;cmp	ecx, 64
  1278 00007F64 80F940              <1> 	cmp	cl, 64
  1279 00007F67 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1280                              <1> 
  1281 00007F69 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1282 00007F6B F3A4                <1> 	rep	movsb
  1283                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1284 00007F6D 8B35[A6DD0000]      <1> 	mov	esi, [Last_Slash_Pos]
  1285 00007F73 46                  <1> 	inc	esi
  1286 00007F74 89C7                <1> 	mov	edi, eax
  1287 00007F76 AC                  <1> 	lodsb
  1288 00007F77 3C21                <1> 	cmp	al, 21h
  1289 00007F79 7381                <1> 	jnb	short loc_ppn_get_filename
  1290                              <1> loc_ppn_clc_return:
  1291                              <1> 	;clc
  1292 00007F7B 31C0                <1> 	xor	eax, eax
  1293 00007F7D C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> loc_ppn_invalid_drive_stc:
  1296 00007F7E F5                  <1> 	cmc	 ; stc
  1297                              <1> loc_ppn_invalid_drive:
  1298                              <1> 	; cf = 1
  1299                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1300 00007F7F 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 00007F83 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 00007F84 66B80008            <1> 	mov	ax, 0800h 
  1338                              <1> 		; it must not be volume name or longname
  1339 00007F88 E844DDFFFF          <1> 	call	find_first_file
  1340 00007F8D 7216                <1> 	jc	short loc_fln_retn
  1341                              <1>  
  1342                              <1> loc_fln_check_FAT_Type:
  1343 00007F8F 803D[7DD30000]01    <1> 	cmp	byte [Current_FATType], 1
  1344 00007F96 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1345                              <1> 
  1346 00007F98 E839000000          <1> 	call	get_fs_longname
  1347 00007F9D C3                  <1> 	retn
  1348                              <1> 
  1349                              <1> loc_fln_check_longname_yes_sign:
  1350 00007F9E 08FF                <1> 	or	bh, bh
  1351 00007FA0 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1352                              <1> loc_fln_longname_not_found_retn:
  1353 00007FA2 31C0                <1> 	xor	eax, eax 
  1354                              <1> 	; cf = 1 & al = 0 -> longname not found
  1355 00007FA4 F9                  <1> 	stc
  1356                              <1> loc_fln_retn:
  1357 00007FA5 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 00007FA6 803D[7DDC0000]01    <1>         cmp     byte [LongNameFound], 1
  1368 00007FAD 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1369                              <1>              
  1370                              <1> loc_fln_calculate_checksum: 
  1371 00007FAF 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 00007FB4 3805[7FDC0000]      <1> 	cmp	[LFN_CheckSum], al
  1382 00007FBA 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1383                              <1> 
  1384 00007FBC BE[80DC0000]        <1> 	mov	esi, LongFileName
  1385 00007FC1 A0[7DD30000]        <1> 	mov	al, [Current_FATType]
  1386 00007FC6 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 00007FC7 30C0                <1> 	xor	al, al
  1411 00007FC9 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 00007FCE D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1420 00007FD0 0206                <1> 	add	al, [esi]
  1421 00007FD2 46                  <1> 	inc	esi
  1422                              <1> 	;add	al, ah
  1423 00007FD3 E2F9                <1> 	loop	loc_next_sum
  1424 00007FD5 C3                  <1> 	retn
  1425                              <1> 
  1426                              <1> get_fs_longname:
  1427                              <1> 	; temporary (13/02/2016)
  1428 00007FD6 31C0                <1> 	xor eax, eax
  1429 00007FD8 F9                  <1> 	stc
  1430 00007FD9 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 00007FDA 80E107              <1> 	and	cl, 07h
  1454 00007FDD 880D[FCDD0000]      <1> 	mov	byte [mkdir_attrib], cl
  1455                              <1> 
  1456 00007FE3 56                  <1> 	push	esi
  1457 00007FE4 31DB                <1> 	xor	ebx, ebx
  1458 00007FE6 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  1459 00007FEC BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1460 00007FF1 01DE                <1> 	add	esi, ebx
  1461 00007FF3 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 00007FF4 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1466 00007FF8 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1467 00007FFA B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  1468 00007FFF 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 00008004 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 00008005 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1480 00008009 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1481                              <1> 
  1482                              <1> loc_make_fs_directory:
  1483 0000800B A1[78D30000]        <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 00008010 E8B8150000          <1> 	call	make_fs_directory
  1488 00008015 C3                  <1> 	retn
  1489                              <1> 
  1490                              <1> loc_mkdir_check_free_sectors:
  1491 00008016 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1492 0000801A 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1493 0000801D 39C1                <1> 	cmp	ecx, eax
  1494 0000801F 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1495                              <1> 
  1496                              <1> loc_make_fat_directory:
  1497 00008021 891D[ECDD0000]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1498 00008027 890D[F8DD0000]      <1> 	mov	[mkdir_FreeSectors], ecx
  1499                              <1> 
  1500                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1501 0000802D A2[FEDD0000]        <1> 	mov	byte [mkdir_SecPerClust], al
  1502                              <1> 
  1503                              <1> loc_mkdir_gffc_1:
  1504 00008032 E8F2170000          <1> 	call	get_first_free_cluster
  1505 00008037 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 00008039 A3[F0DD0000]        <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 0000803E 31C0                <1> 	xor	eax, eax
  1522 00008040 89C1                <1>         mov	ecx, eax
  1523 00008042 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 00008044 E8D2FAFFFF          <1> 	call	locate_current_dir_file
  1528 00008049 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 0000804B 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1532 0000804E 752B                <1> 	jne	short loc_mkdir_stc_return
  1533                              <1> 
  1534                              <1> loc_mkdir_add_new_cluster:
  1535 00008050 3805[7DD30000]      <1> 	cmp	byte [Current_FATType], al ; 2
  1536                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1537 00008056 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1538 00008058 803D[7CD30000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1539                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1540 0000805F 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1541                              <1> 
  1542 00008061 B00C                <1> 	mov	al, 12 ; No more files 
  1543                              <1> loc_mkdir_gffc_retn:
  1544 00008063 C3                  <1> 	retn
  1545                              <1> 
  1546                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1547 00008064 8B0D[F8DD0000]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1548                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1549 0000806A A0[FEDD0000]        <1> 	mov	al, [mkdir_SecPerClust]
  1550 0000806F 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1551 00008072 39C1                <1> 	cmp	ecx, eax
  1552 00008074 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 00008076 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 0000807A C3                  <1> 	retn
  1563                              <1> 
  1564                              <1> loc_mkdir_stc_return:
  1565 0000807B F9                  <1> 	stc
  1566 0000807C C3                  <1> 	retn 
  1567                              <1> 
  1568                              <1> loc_mkdir_gffc_2:
  1569 0000807D E8A7170000          <1> 	call	get_first_free_cluster
  1570 00008082 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 00008084 A3[F0DD0000]        <1> 	mov	[mkdir_FFCluster], eax
  1578                              <1> 
  1579 00008089 A1[F4DD0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1580                              <1> 
  1581 0000808E E825170000          <1> 	call	load_FAT_sub_directory 
  1582 00008093 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1583                              <1> 
  1584 00008095 31FF                <1> 	xor	edi, edi
  1585                              <1> loc_mkdir_set_ff_dir_entry_1:
  1586                              <1> 	; 27/02/2016
  1587 00008097 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1588                              <1> 	; EDI = Directory Entry Address
  1589 00008098 8B35[ECDD0000]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1590 0000809E A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1591                              <1> 
  1592 000080A3 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1593                              <1> 			; CH = 0 -> File size is 0
  1594 000080A7 0A0D[FCDD0000]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1595 000080AD E8B0010000          <1> 	call	make_directory_entry
  1596                              <1> 
  1597 000080B2 5E                  <1> 	pop	esi
  1598                              <1> 
  1599 000080B3 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1600 000080BA E880020000          <1> 	call	save_directory_buffer
  1601 000080BF 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1602                              <1> 
  1603                              <1> loc_mkdir_return:
  1604 000080C5 C3                  <1> 	retn
  1605                              <1> 
  1606                              <1> loc_mkdir_add_new_subdir_cluster:
  1607 000080C6 8B15[ADDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  1608 000080CC 8915[F4DD0000]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1609                              <1> 
  1610 000080D2 A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1611 000080D7 E8DC160000          <1> 	call	load_FAT_sub_directory 
  1612 000080DC 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 000080DE 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 000080E0 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1623 000080E4 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1624 000080E8 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1625 000080EB 6689C1              <1> 	mov	cx, ax
  1626 000080EE 6629C0              <1> 	sub	ax, ax ; 0
  1627 000080F1 F3AB                <1> 	rep	stosd ; clear directory buffer
  1628                              <1> 
  1629 000080F3 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1630 000080FA E840020000          <1> 	call	save_directory_buffer 
  1631 000080FF 72C4                <1> 	jc	short loc_mkdir_return
  1632                              <1> 
  1633                              <1> loc_mkdir_save_added_cluster:
  1634 00008101 A1[F4DD0000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1635 00008106 8B0D[F0DD0000]      <1> 	mov	ecx, [mkdir_FFCluster]
  1636                              <1> 	; 01/03/2016
  1637 0000810C 31D2                <1> 	xor	edx, edx
  1638 0000810E 8915[9EDB0000]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1639 00008114 E8E3170000          <1> 	call	update_cluster
  1640 00008119 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1641 0000811B 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1642 0000811D 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1643                              <1> 
  1644                              <1> loc_mkdir_save_fat_buffer_0:
  1645 0000811F A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1646 00008124 A3[F4DD0000]        <1> 	mov	[mkdir_LastDirCluster], eax
  1647                              <1> 
  1648 00008129 31C9                <1> 	xor	ecx, ecx
  1649 0000812B 49                  <1> 	dec	ecx ; FFFFFFFFh
  1650                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1651 0000812C E8CB170000          <1> 	call	update_cluster
  1652 00008131 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1653 00008133 09C0                <1> 	or	eax, eax
  1654 00008135 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 00008137 803D[9EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1659 0000813E 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1660                              <1> 
  1661 00008140 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 00008144 50                  <1> 	push	eax
  1664 00008145 E8041B0000          <1> 	call	calculate_fat_freespace
  1665 0000814A 58                  <1> 	pop	eax
  1666 0000814B F9                  <1> 	stc
  1667                              <1> loc_mkdir_save_fat_buffer_retn:
  1668 0000814C C3                  <1> 	retn
  1669                              <1> 
  1670                              <1> loc_mkdir_save_fat_buffer_1:
  1671                              <1> 	; byte [FAT_BuffValidData] = 2 
  1672 0000814D E8671A0000          <1> 	call	save_fat_buffer
  1673 00008152 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1674                              <1> 
  1675                              <1> 	; 01/03/2016
  1676 00008154 803D[9EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1677 0000815B 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1678                              <1> 
  1679                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1680 0000815D A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1681 00008162 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1682 00008166 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 0000816B 09C9                <1> 	or	ecx, ecx 
  1689 0000816D 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1690                              <1> 
  1691 0000816F 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1692 00008173 E8D61A0000          <1> 	call	calculate_fat_freespace
  1693                              <1> 
  1694                              <1> loc_mkdir_save_fat_buffer_2:
  1695 00008178 C605[FFDD0000]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1696 0000817F E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1697                              <1> 
  1698                              <1> loc_mkdir_update_sub_dir_cluster:
  1699 00008184 A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1700 00008189 29C9                <1> 	sub	ecx, ecx ; 0
  1701                              <1> 	; 01/03/2016
  1702 0000818B 890D[9EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1703 00008191 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1704                              <1> 
  1705                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1706 00008192 E865170000          <1> 	call	update_cluster
  1707 00008197 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1708 00008199 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1709 0000819B 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1710                              <1> 	; 01/03/2016
  1711 0000819D 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 0000819F A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1716                              <1> 	; Load disk sectors as a directory cluster
  1717 000081A4 E80F160000          <1> 	call	load_FAT_sub_directory 
  1718 000081A9 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 000081AB BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1724                              <1> 
  1725                              <1> 	; 02/03/2016
  1726 000081B0 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1727 000081B4 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1728 000081B8 F7E1                <1> 	mul 	ecx
  1729 000081BA 89C1                <1> 	mov	ecx, eax
  1730 000081BC 6629C0              <1> 	sub	ax, ax
  1731 000081BF 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 000081C1 BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1742                              <1> 	
  1743 000081C6 56                  <1> 	push	esi
  1744                              <1> 
  1745 000081C7 BE[00DE0000]        <1> 	mov	esi, mkdir_Name
  1746 000081CC 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1747                              <1> 
  1748 000081D1 A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1749 000081D6 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1750                              <1> 			; CH = 0 -> File size is 0
  1751 000081DA E883000000          <1> 	call	make_directory_entry
  1752                              <1> 
  1753 000081DF BF20000800          <1> 	mov	edi, Directory_Buffer + 32 ; 26/02/2016
  1754                              <1> 
  1755                              <1> 	; 03/03/2016
  1756                              <1> 	; Following modification has been done according to 
  1757                              <1> 	; 'Microsoft Extensible Firmware Initiative
  1758                              <1> 	; FAT32 File System Specification' document,
  1759                              <1> 	; 'FAT: General Overview of On-Disk FormatPage 25'.
  1760                              <1> 	; "Finally, you set DIR_FstClusLO and DIR_FstClusHI
  1761                              <1> 	; for the dotdot entry (the second entry) to the
  1762                              <1> 	; first cluster number of the directory in which you 
  1763                              <1> 	; just created the directory (value is 0 if this directory
  1764                              <1> 	; is the root directory even for FAT32 volumes)."
  1765                              <1> 	; (Correctness of this modification has been verified
  1766                              <1> 	;  by using Windows 98 'scandisk.exe'.)
  1767                              <1> 
  1768 000081E4 29C0                <1> 	sub	eax, eax
  1769 000081E6 3805[7CD30000]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1770 000081EC 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1771 000081EE A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1772                              <1> loc_mkdir_set_ff_dir_entry_3:
  1773 000081F3 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1774                              <1> 
  1775                              <1> 	;mov	cx, 10h
  1776 000081F9 E864000000          <1> 	call	make_directory_entry
  1777                              <1> 
  1778 000081FE 5E                  <1> 	pop	esi
  1779                              <1> 
  1780 000081FF C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1781 00008206 E834010000          <1> 	call	save_directory_buffer
  1782 0000820B 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1783                              <1>  
  1784                              <1> retn_make_fat_directory:
  1785 00008211 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 00008212 E8A2190000          <1> 	call	save_fat_buffer
  1791 00008217 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1792                              <1> 
  1793 0000821D 803D[9EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1794 00008224 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1795                              <1> 
  1796                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1797 00008226 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1798 0000822B 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1799 0000822F 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 00008234 09C9                <1> 	or	ecx, ecx 
  1806 00008236 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1807                              <1> 
  1808 00008238 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space
  1809 0000823C E80D1A0000          <1> 	call	calculate_fat_freespace
  1810                              <1> 
  1811                              <1> loc_mkdir_save_fat_buffer_4:	
  1812 00008241 C605[FFDD0000]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1813                              <1> 
  1814                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1815 00008248 E88D010000          <1> 	call	update_parent_dir_lmdt
  1816                              <1> 
  1817                              <1> 	; 01/03/2016
  1818 0000824D 803D[FFDD0000]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1819 00008254 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1820                              <1> 
  1821                              <1> loc_mkdir_retn_new_dir_cluster:
  1822 0000825A A1[F0DD0000]        <1> 	mov	eax, [mkdir_FFCluster]
  1823 0000825F 31D2                <1> 	xor	edx, edx
  1824                              <1> loc_mkdir_retn:
  1825 00008261 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 00008262 51                  <1> 	push	ecx
  1850                              <1> 
  1851 00008263 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1852 00008266 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1853 0000826A C1E810              <1> 	shr	eax, 16
  1854 0000826D 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1855 00008271 6631C0              <1> 	xor	ax, ax 
  1856 00008274 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1857                              <1> 			     ; CrtTimeTenth, 13
  1858 00008278 08ED                <1> 	or	ch, ch
  1859 0000827A 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1860                              <1> 
  1861 0000827C 8B03                <1> 	mov	eax, [ebx]
  1862                              <1>         
  1863                              <1> loc_make_direntry_set_filesize:
  1864 0000827E 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1865                              <1> 	
  1866 00008281 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 00008286 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 0000828B 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1874 0000828F 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1875 00008293 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1876 00008297 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1877 0000829B 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1878 0000829F 59                  <1> 	pop	ecx
  1879                              <1> 
  1880 000082A0 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 000082A1 B404                <1> 	mov	ah, 04h ; Return Current Date
  1891 000082A3 E8CAB9FFFF          <1> 	call	int1Ah 
  1892                              <1> 
  1893 000082A8 88E8                <1> 	mov	al, ch ; <- century BCD
  1894 000082AA 240F                <1> 	and	al, 0Fh
  1895 000082AC 88EC                <1> 	mov	ah, ch
  1896 000082AE C0EC04              <1> 	shr	ah, 4
  1897 000082B1 D50A                <1> 	aad
  1898 000082B3 88C5                <1> 	mov	ch, al ; -> century 
  1899                              <1> 
  1900 000082B5 88C8                <1> 	mov	al, cl ; <- year BCD
  1901 000082B7 240F                <1> 	and	al, 0Fh
  1902 000082B9 88CC                <1> 	mov	ah, cl
  1903 000082BB C0EC04              <1> 	shr	ah, 4
  1904 000082BE D50A                <1> 	aad
  1905 000082C0 88C1                <1> 	mov	cl, al ; -> year
  1906                              <1> 
  1907 000082C2 88E8                <1> 	mov	al, ch
  1908 000082C4 B464                <1> 	mov	ah, 100
  1909 000082C6 F6E4                <1> 	mul	ah
  1910 000082C8 30ED                <1> 	xor	ch, ch
  1911 000082CA 6601C8              <1> 	add	ax, cx
  1912 000082CD 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1913 000082D1 6689C1              <1> 	mov	cx, ax
  1914                              <1> 
  1915 000082D4 88F0                <1> 	mov	al, dh ; <- month in bcd
  1916 000082D6 240F                <1> 	and	al, 0Fh
  1917 000082D8 88F4                <1> 	mov	ah, dh
  1918 000082DA C0EC04              <1> 	shr	ah, 4
  1919 000082DD D50A                <1> 	aad
  1920 000082DF 88C6                <1> 	mov	dh, al ; -> month
  1921                              <1> 
  1922 000082E1 88D0                <1> 	mov	al, dl ; <- day BCD
  1923 000082E3 240F                <1> 	and	al, 0Fh
  1924 000082E5 88D4                <1> 	mov	ah, dl
  1925 000082E7 C0EC04              <1> 	shr	ah, 4
  1926 000082EA D50A                <1> 	aad
  1927 000082EC 88C2                <1> 	mov	dl, al ; -> day
  1928                              <1> 
  1929 000082EE 88C8                <1> 	mov	al, cl ; count of years from 1980
  1930 000082F0 66C1E004            <1> 	shl	ax, 4
  1931 000082F4 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1932 000082F6 66C1E005            <1> 	shl	ax, 5
  1933 000082FA 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1934                              <1> 	
  1935 000082FC 6650                <1> 	push	ax ; push date
  1936                              <1> 
  1937 000082FE B402                <1> 	mov	ah, 02h ; Return Current Time
  1938 00008300 E86DB9FFFF          <1> 	call	int1Ah
  1939                              <1> 
  1940 00008305 88E8                <1> 	mov	al, ch ; <- hours BCD
  1941 00008307 240F                <1> 	and	al, 0Fh
  1942 00008309 88EC                <1> 	mov	ah, ch
  1943 0000830B C0EC04              <1> 	shr	ah, 4
  1944 0000830E D50A                <1> 	aad
  1945 00008310 88C5                <1> 	mov	ch, al ; -> hours
  1946                              <1> 
  1947 00008312 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1948 00008314 240F                <1> 	and	al, 0Fh
  1949 00008316 88CC                <1> 	mov	ah, cl
  1950 00008318 C0EC04              <1> 	shr	ah, 4
  1951 0000831B D50A                <1> 	aad
  1952 0000831D 88C1                <1> 	mov	cl, al ; -> minutes
  1953                              <1> 
  1954 0000831F 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1955 00008321 240F                <1> 	and	al, 0Fh
  1956 00008323 88F4                <1> 	mov	ah, dh
  1957 00008325 C0EC04              <1> 	shr	ah, 4
  1958 00008328 D50A                <1> 	aad
  1959 0000832A 88C6                <1> 	mov	dh, al ; -> seconds
  1960                              <1> 
  1961 0000832C 88E8                <1> 	mov	al, ch ; hours
  1962 0000832E 66C1E006            <1> 	shl	ax, 6
  1963 00008332 08C8                <1> 	or	al, cl ; minutes
  1964 00008334 66C1E005            <1> 	shl	ax, 5
  1965 00008338 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 0000833A 08F0                <1> 	or	al, dh ; seconds
  1969                              <1> 
  1970 0000833C 665A                <1> 	pop	dx ; pop date
  1971                              <1> 	
  1972 0000833E 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 0000833F BB00000800          <1> 	mov	ebx, Directory_Buffer
  1991 00008344 803D[A8DB0000]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1992 0000834B 7403                <1> 	je	short loc_save_dir_buffer
  1993 0000834D 31C0                <1> 	xor	eax, eax
  1994 0000834F C3                  <1> 	retn            
  1995                              <1> 
  1996                              <1> loc_save_dir_buffer:
  1997 00008350 56                  <1> 	push	esi
  1998 00008351 31DB                <1> 	xor	ebx, ebx 
  1999 00008353 8A3D[A6DB0000]      <1>         mov     bh, [DirBuff_DRV]
  2000 00008359 80EF41              <1> 	sub	bh, 'A'
  2001 0000835C BE00010900          <1>         mov     esi, Logical_DOSDisks
  2002 00008361 01DE                <1> 	add	esi, ebx
  2003 00008363 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2004                              <1> 	; CH = FS Type (A1h for FS)
  2005                              <1> 	; CL = FAT Type (0 for FS)
  2006 00008367 08C9                <1> 	or	cl, cl
  2007 00008369 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2008                              <1> 
  2009                              <1> loc_save_dir_buffer_check_cluster_no:    
  2010 0000836B A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2011 00008370 28FF                <1> 	sub	bh, bh ; ebx = 0
  2012 00008372 09C0                <1> 	or	eax, eax
  2013 00008374 7540                <1> 	jnz	short loc_save_sub_dir_buffer
  2014 00008376 8A25[A7DB0000]      <1> 	mov	ah, [DirBuff_FATType]
  2015 0000837C FEC3                <1> 	inc	bl ;  bl = 1
  2016 0000837E 38DC                <1> 	cmp	ah, bl
  2017 00008380 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2018 00008382 FEC3                <1> 	inc	bl ; bl = 2
  2019 00008384 38E3                <1> 	cmp	bl, ah
  2020 00008386 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2021                              <1> 
  2022                              <1> loc_save_root_dir_buffer:
  2023 00008388 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2024 0000838C 6683C30F            <1> 	add	bx, 15
  2025 00008390 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2026 00008394 6609DB              <1> 	or	bx, bx
  2027 00008397 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2028                              <1> 	;mov	ecx, ebx 
  2029 00008399 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2030 0000839C EB23                <1> 	jmp	short loc_write_directory_to_disk
  2031                              <1> 
  2032                              <1> loc_save_dir_buff_stc_retn:
  2033 0000839E F9                  <1> 	stc
  2034                              <1> loc_save_dir_buff_inv_data_retn:
  2035 0000839F B00D                <1> 	mov	al, 0Dh ; Invalid data !
  2036 000083A1 C605[A8DB0000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2037 000083A8 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 000083AA B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error 
  2042                              <1> 
  2043                              <1> loc_save_dir_buff_retn:
  2044 000083AF BB00000800          <1> 	mov	ebx, Directory_Buffer
  2045 000083B4 5E                  <1> 	pop	esi
  2046 000083B5 C3                  <1> 	retn
  2047                              <1>  
  2048                              <1> loc_save_sub_dir_buffer:
  2049                              <1> 	; ebx  = 0
  2050 000083B6 83E802              <1> 	sub	eax, 2
  2051 000083B9 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2052 000083BC F7E3                <1> 	mul	ebx
  2053 000083BE 034668              <1>         add     eax, [esi+LD_DATABegin]
  2054                              <1>  	;mov	ecx, ebx
  2055                              <1> 
  2056                              <1> loc_write_directory_to_disk:
  2057 000083C1 89D9                <1>  	mov	ecx, ebx
  2058 000083C3 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2059 000083C8 E8513A0000          <1> 	call	disk_write
  2060 000083CD 72DB                <1> 	jc	short loc_write_directory_to_disk_err
  2061                              <1> 
  2062                              <1> loc_save_dir_buff_validate_retn:
  2063 000083CF C605[A8DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2064 000083D6 31C0                <1> 	xor	eax, eax
  2065                              <1> 	; 26/02/2016
  2066 000083D8 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 000083DA 29C0                <1> 	sub	eax, eax
  2082 000083DC 8A25[7CD30000]      <1> 	mov	ah, [Current_Dir_Level]
  2083 000083E2 A0[7DD30000]        <1> 	mov	al, [Current_FATType]
  2084 000083E7 3C01                <1> 	cmp	al, 1
  2085 000083E9 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2086                              <1>     
  2087                              <1> loc_update_parent_dir_lm_date_time:
  2088 000083EB 08E4                <1> 	or	ah, ah
  2089 000083ED 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2090                              <1> 
  2091 000083EF 56                  <1> 	push	esi ; *
  2092 000083F0 8825[20DE0000]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2093 000083F6 8B15[78D30000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2094 000083FC 8915[21DE0000]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2095                              <1> 
  2096 00008402 FECC                <1> 	dec	ah
  2097 00008404 B90C000000          <1> 	mov	ecx, 12
  2098 00008409 BE[DFDB0000]        <1>         mov     esi, PATH_Array
  2099                              <1> 
  2100 0000840E 8825[7CD30000]      <1> 	mov	[Current_Dir_Level], ah
  2101 00008414 08E4                <1> 	or	ah, ah
  2102 00008416 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2103 00008418 803D[7DD30000]02    <1> 	cmp	byte [Current_FATType], 2
  2104 0000841F 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2105 00008421 28C0                <1> 	sub	al, al ; eax = 0
  2106 00008423 EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2107                              <1> 
  2108                              <1> loc_UPDLMDT_proc_retn:
  2109 00008425 C3                  <1> 	retn
  2110                              <1>          
  2111                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2112 00008426 B010                <1> 	mov	al, 16
  2113 00008428 F6E4                <1> 	mul	ah 
  2114 0000842A 01C6                <1> 	add	esi, eax
  2115                              <1> 
  2116                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2117 0000842C 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2118                              <1> 
  2119                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2120 0000842F A3[78D30000]        <1> 	mov	[Current_Dir_FCluster], eax
  2121                              <1> 
  2122 00008434 83C610              <1> 	add	esi, 16
  2123 00008437 66BF[06DD]          <1> 	mov	di, Dir_File_Name  
  2124 0000843B F3A4                <1> 	rep	movsb
  2125                              <1> 	
  2126 0000843D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2127 00008442 29DB                <1> 	sub	ebx, ebx
  2128 00008444 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  2129 0000844A 01DE                <1> 	add	esi, ebx
  2130 0000844C E88FF7FFFF          <1> 	call	reload_current_directory
  2131 00008451 7232                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2132                              <1> 
  2133                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2134 00008453 BE[06DD0000]        <1> 	mov	esi, Dir_File_Name        
  2135 00008458 6631C9              <1> 	xor	cx, cx
  2136 0000845B 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2137 0000845F E8B7F6FFFF          <1>         call    locate_current_dir_file
  2138                              <1> 	; EDI = DirBuff Directory Entry Address
  2139 00008464 721F                <1> 	jc short loc_update_parent_dir_lmdt_restore_cdirlevel
  2140                              <1> 
  2141 00008466 E836FEFFFF          <1> 	call	convert_current_date_time
  2142 0000846B 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2143 0000846F 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2144 00008473 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2145                              <1> 
  2146 00008477 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2147 0000847E E8BCFEFFFF          <1> 	call	save_directory_buffer
  2148 00008483 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 00008485 8A25[20DE0000]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2153 0000848B 8825[7CD30000]      <1> 	mov	[Current_Dir_Level], ah
  2154 00008491 8B15[21DE0000]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2155 00008497 8915[78D30000]      <1> 	mov	[Current_Dir_FCluster], edx
  2156                              <1> 
  2157 0000849D 5E                  <1> 	pop	esi ; *
  2158 0000849E 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 0000849F 66A3[4CDE0000]      <1> 	mov	[DLN_EntryNumber], ax
  2173 000084A5 C605[4EDE0000]40    <1>         mov     byte [DLN_40h], 40h
  2174                              <1> 
  2175 000084AC E858000000          <1> 	call	locate_current_dir_entry
  2176 000084B1 7308                <1> 	jnc	short loc_dln_check_attributes
  2177 000084B3 C3                  <1> 	retn
  2178                              <1> 
  2179                              <1> loc_dln_longname_not_found:
  2180 000084B4 B802000000          <1> 	mov	eax, 2
  2181 000084B9 F9                  <1> 	stc
  2182 000084BA C3                  <1> 	retn
  2183                              <1> 
  2184                              <1> loc_dln_check_attributes:
  2185 000084BB B00F                <1> 	mov	al, 0Fh  ; long name
  2186 000084BD 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2187 000084C0 38C4                <1> 	cmp	ah, al
  2188 000084C2 75F0                <1> 	jne	short loc_dln_longname_not_found
  2189 000084C4 8A27                <1> 	mov	ah, [edi]
  2190 000084C6 2A25[4EDE0000]      <1> 	sub	ah, [DLN_40h]
  2191 000084CC 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2192 000084CE 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2193 000084D1 77E1                <1> 	ja	short loc_dln_longname_not_found
  2194                              <1>              
  2195 000084D3 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2196 000084D6 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2197 000084DD C605[4EDE0000]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2198                              <1> 	  
  2199                              <1> loc_dln_delete_next_ln_entry:
  2200 000084E4 80FC01              <1> 	cmp	ah, 1
  2201 000084E7 7616                <1> 	jna	short loc_dln_longname_retn
  2202                              <1> loc_dln_delete_next_ln_entry_0:
  2203 000084E9 66FF05[4CDE0000]    <1> 	inc	word [DLN_EntryNumber]
  2204 000084F0 0FB705[4CDE0000]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2205 000084F7 E80D000000          <1> 	call	locate_current_dir_entry
  2206 000084FC 73BD                <1> 	jnc	short loc_dln_check_attributes
  2207                              <1> 
  2208                              <1> loc_dln_longname_stc_retn:
  2209 000084FE 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 000084FF E83BFEFFFF          <1> 	call	save_directory_buffer
  2215 00008504 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2216                              <1> 
  2217                              <1> loc_dln_longname_retn_xor_eax:
  2218 00008506 31C0                <1> 	xor	eax, eax
  2219 00008508 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 00008509 56                  <1> 	push	esi
  2244 0000850A 89C1                <1> 	mov	ecx, eax
  2245 0000850C BA20000000          <1> 	mov	edx, 32
  2246 00008511 F7E2                <1> 	mul	edx 
  2247 00008513 A3[58DE0000]        <1> 	mov	[LCDE_ByteOffset], eax
  2248 00008518 31DB                <1> 	xor	ebx, ebx
  2249 0000851A 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  2250 00008520 A0[A6DB0000]        <1>         mov     al, [DirBuff_DRV]
  2251 00008525 2C41                <1> 	sub	al, 'A'
  2252 00008527 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2253 0000852C 01DE                <1> 	add	esi, ebx
  2254 0000852E 38C7                <1> 	cmp	bh, al
  2255 00008530 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2256                              <1> loc_lcde_cdl_check:
  2257 00008536 803D[7CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2258 0000853D 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 0000853F 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2263 00008543 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2264                              <1> 
  2265                              <1> loc_lcde_cdl_check_FAT12_16:
  2266 00008545 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2267 00008549 6648                <1> 	dec	ax
  2268                              <1> 	;xor	dx, dx  
  2269 0000854B 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2270 0000854E 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2271 00008550 66890D[50DE0000]    <1> 	mov	[LCDE_EntryIndex], cx
  2272 00008557 31C0                <1> 	xor	eax, eax
  2273 00008559 E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2274                              <1> 
  2275                              <1> loc_lcde_stc_12h_retn:
  2276 0000855E 5E                  <1> 	pop	esi
  2277 0000855F 89CB                <1> 	mov	ebx, ecx
  2278 00008561 89D1                <1> 	mov	ecx, edx
  2279 00008563 B812000000          <1> 	mov	eax, 12h ; No more files
  2280 00008568 C3                  <1> 	retn 
  2281                              <1> 
  2282                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2283 00008569 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2284 0000856C 30FF                <1> 	xor	bh, bh
  2285 0000856E 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2286 00008572 66F7E3              <1> 	mul	bx
  2287 00008575 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2288 00008578 755D                <1> 	jnz	short loc_lcde_invalid_format
  2289                              <1> 	;mov	ecx, eax
  2290 0000857A 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2291 0000857D A1[58DE0000]        <1> 	mov	eax, [LCDE_ByteOffset]
  2292                              <1> 	;sub	edx, edx
  2293 00008582 F7F1                <1> 	div	ecx
  2294 00008584 3DFFFF0000          <1> 	cmp	eax, 65535
  2295 00008589 774C                <1> 	ja	short loc_lcde_invalid_format
  2296                              <1> 
  2297                              <1> 	; cluster sequence number of directory (< 65536)
  2298 0000858B 66A3[52DE0000]      <1> 	mov	[LCDE_ClusterSN], ax 
  2299                              <1> 
  2300 00008591 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2301 00008594 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2302 00008598 6629D2              <1>         sub     dx, dx  ; 0
  2303 0000859B 66F7F3              <1> 	div	bx 
  2304 0000859E 66A3[50DE0000]      <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 000085A4 A1[78D30000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2308                              <1> 
  2309                              <1> loc_lcde_get_next_cluster:
  2310 000085A9 66833D[52DE0000]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2311 000085B1 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2312 000085B3 A3[54DE0000]        <1> 	mov	[LCDE_Cluster], eax
  2313 000085B8 E815100000          <1> 	call	get_next_cluster
  2314 000085BD 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2315 000085BF 66FF0D[52DE0000]    <1>   	dec	word [LCDE_ClusterSN]
  2316 000085C6 EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2317                              <1> 
  2318                              <1> loc_lcde_reload_current_directory:
  2319 000085C8 51                  <1> 	push	ecx
  2320 000085C9 E812F6FFFF          <1> 	call	reload_current_directory
  2321 000085CE 59                  <1> 	pop	ecx
  2322 000085CF 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2323 000085D5 5E                  <1> 	pop	esi
  2324 000085D6 C3                  <1> 	retn
  2325                              <1> 
  2326                              <1> loc_lcde_invalid_format:
  2327 000085D7 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 000085DC F9                  <1> 	stc
  2331 000085DD 5E                  <1> 	pop	esi 
  2332 000085DE C3                  <1> 	retn  
  2333                              <1> 
  2334                              <1> loc_lcde_check_gnc_error:
  2335 000085DF 09C0                <1> 	or	eax, eax
  2336 000085E1 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2337 000085E3 66FF0D[52DE0000]    <1> 	dec	word [LCDE_ClusterSN]
  2338 000085EA 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2339 000085EC A1[54DE0000]        <1> 	mov	eax, [LCDE_Cluster]
  2340                              <1> 
  2341                              <1> loc_lcde_check_dir_buffer_cluster:
  2342 000085F1 3B05[ADDB0000]      <1> 	cmp	eax, [DirBuff_Cluster]
  2343 000085F7 755C                <1> 	jne	short loc_lcde_load_dir_cluster
  2344 000085F9 803D[A8DB0000]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2345 00008600 7727                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2346 00008602 803D[7CD30000]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2347 00008609 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 0000860B 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2351 0000860F 7359                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2352                              <1> 	;
  2353 00008611 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2354 00008615 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2355 00008619 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2356                              <1> 
  2357 0000861D 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2358 00008620 EB54                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2359                              <1> 
  2360                              <1> loc_lcde_validate_dirBuff:
  2361 00008622 C605[A8DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2362                              <1> 
  2363                              <1> lcde_check_dir_buffer_cluster_next:
  2364 00008629 0FB71D[50DE0000]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2365 00008630 663B1D[ABDB0000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2366 00008637 779E                <1> 	ja	short loc_lcde_invalid_format 
  2367 00008639 B820000000          <1> 	mov	eax, 32
  2368 0000863E F7E3                <1> 	mul	ebx
  2369                              <1> 	;or	edx, edx
  2370                              <1> 	;jnz	short loc_lcde_invalid_format
  2371                              <1> 
  2372 00008640 BF00000800          <1> 	mov	edi, Directory_Buffer  
  2373 00008645 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2374                              <1> 
  2375                              <1> loc_lcde_dir_buffer_last_check:
  2376 00008647 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
  2377 0000864C 0FB60D[A8DB0000]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2378                              <1> 
  2379                              <1> loc_lcde_retn:
  2380 00008653 5E                  <1> 	pop	esi
  2381 00008654 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 00008655 50                  <1> 	push	eax
  2387 00008656 E8E4FCFFFF          <1> 	call	save_directory_buffer
  2388 0000865B 58                  <1> 	pop	eax
  2389 0000865C 72F5                <1> 	jc	short loc_lcde_retn
  2390                              <1> 
  2391                              <1> loc_lcde_load_dir_cluster_n2:
  2392 0000865E C605[A8DB0000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2393 00008665 A3[ADDB0000]        <1> 	mov	[DirBuff_Cluster], eax
  2394                              <1> 
  2395                              <1> loc_lcde_load_dir_cluster_0:
  2396 0000866A 83E802              <1> 	sub	eax, 2
  2397 0000866D 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2398 00008671 F7E1                <1> 	mul	ecx
  2399 00008673 034668              <1>         add     eax, [esi+LD_DATABegin]
  2400                              <1> 
  2401                              <1> loc_lcde_load_dir_cluster_1:
  2402 00008676 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2403                              <1> 	; ecx = sector count
  2404 0000867B E8AD370000          <1> 	call	disk_read
  2405 00008680 73A0                <1> 	jnc	short loc_lcde_validate_dirBuff
  2406                              <1> 
  2407                              <1> 	; 23/03/2016
  2408 00008682 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  2409 00008687 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 00008689 29C0                <1> 	sub	eax, eax
  2423 0000868B 88FC                <1> 	mov	ah, bh
  2424 0000868D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2425 00008692 01C6                <1> 	add	esi, eax
  2426                              <1> 
  2427 00008694 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2428 00008698 7312                <1> 	jnb	short loc_del_fat_file 
  2429                              <1>               
  2430 0000869A 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2431 0000869E 7406                <1> 	je	short loc_del_fs_file
  2432                              <1> 
  2433                              <1> loc_del_file_invalid_format:
  2434 000086A0 30E4                <1> 	xor	ah, ah
  2435 000086A2 B00B                <1> 	mov	al, 0Bh ; Invalid Format
  2436 000086A4 F9                  <1> 	stc 
  2437 000086A5 C3                  <1> 	retn
  2438                              <1> 
  2439                              <1> loc_del_fs_file:
  2440 000086A6 E8200F0000          <1> 	call	delete_fs_file
  2441 000086AB C3                  <1> 	retn
  2442                              <1> 
  2443                              <1> loc_del_fat_file:
  2444 000086AC E808000000          <1> 	call	delete_directory_entry
  2445 000086B1 7205                <1> 	jc	short loc_del_file_err_retn 
  2446                              <1> 
  2447                              <1> loc_delfile_unlink_cluster_chain:
  2448 000086B3 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 000086B8 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 000086B9 881D[EADD0000]      <1> 	mov	[DelFile_LNEL], bl
  2474 000086BF 66890D[E8DD0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2475                              <1> 
  2476 000086C6 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2477 000086CA C1E010              <1> 	shl	eax, 16
  2478 000086CD 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2479                              <1> 
  2480 000086D1 A3[E4DD0000]        <1> 	mov	[DelFile_FCluster], eax
  2481                              <1> 
  2482                              <1> loc_del_short_name:
  2483 000086D6 C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2484                              <1> 
  2485 000086D9 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2486 000086E0 E85AFCFFFF          <1> 	call	save_directory_buffer
  2487 000086E5 723D                <1> 	jc	short loc_delete_direntry_err_return
  2488                              <1>  
  2489                              <1> loc_del_long_name:
  2490 000086E7 0FB615[EADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2491 000086EE 08D2                <1> 	or	dl, dl
  2492 000086F0 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2493                              <1> 
  2494 000086F2 8835[EADD0000]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2495                              <1>   
  2496 000086F8 0FB705[E8DD0000]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2497 000086FF 29D0                <1> 	sub	eax, edx
  2498                              <1> 	;jnc	short loc_del_long_name_continue
  2499 00008701 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 00008703 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 00008708 801D[EADD0000]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2512                              <1> 
  2513 0000870F E8C6FCFFFF          <1> 	call	update_parent_dir_lmdt
  2514 00008714 B700                <1> 	mov	bh, 0
  2515 00008716 80D700              <1> 	adc	bh, 0
  2516                              <1> 
  2517 00008719 8A1D[EADD0000]      <1> 	mov	bl, byte [DelFile_LNEL]
  2518                              <1>  
  2519                              <1> loc_delete_direntry_return:
  2520 0000871F A1[E4DD0000]        <1> 	mov	eax, [DelFile_FCluster]
  2521                              <1> loc_delete_direntry_err_return:
  2522 00008724 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 00008725 803D[7DD30000]00    <1> 	cmp	byte [Current_FATType], 0
  2541 0000872C 7706                <1> 	ja	short loc_rename_directory_entry
  2542                              <1> 
  2543 0000872E E8990E0000          <1> 	call	rename_fs_file_or_directory
  2544 00008733 C3                  <1> 	retn 
  2545                              <1> 	
  2546                              <1> loc_rename_directory_entry:
  2547 00008734 881D[EADD0000]      <1> 	mov	[DelFile_LNEL], bl
  2548 0000873A 66890D[E8DD0000]    <1> 	mov	[DelFile_EntryCounter], cx
  2549 00008741 A3[E4DD0000]        <1> 	mov	[DelFile_FCluster], eax
  2550                              <1> 
  2551 00008746 0FB7C1              <1> 	movzx	eax, cx
  2552 00008749 E8BBFDFFFF          <1> 	call	locate_current_dir_entry
  2553 0000874E 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2554                              <1> 
  2555                              <1> loc_rename_direntry_pop_retn:
  2556 00008750 C3                  <1> 	retn
  2557                              <1> 
  2558                              <1> loc_rename_direntry_pop_invd_retn:
  2559 00008751 F9                  <1> 	stc
  2560                              <1> loc_rename_direntry_invd_retn:
  2561 00008752 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  2562                              <1> loc_rename_retn:
  2563 00008757 C3                  <1> 	retn 
  2564                              <1> 
  2565                              <1> loc_rename_direntry_check_fcluster:
  2566 00008758 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2567 0000875C 66C1E210            <1> 	shl	dx, 16
  2568 00008760 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2569 00008764 3B15[E4DD0000]      <1> 	cmp	edx, [DelFile_FCluster]
  2570 0000876A 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 0000876C E89FF6FFFF          <1> 	call	convert_file_name
  2581                              <1> 
  2582 00008771 C605[A8DB0000]02    <1>         mov     byte [DirBuff_ValidData], 2
  2583 00008778 E8C2FBFFFF          <1> 	call	save_directory_buffer
  2584 0000877D 72D8                <1> 	jc	short loc_rename_retn
  2585                              <1> 
  2586                              <1> loc_rename_direntry_del_ln:
  2587 0000877F 0FB615[EADD0000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2588 00008786 08D2                <1> 	or	dl, dl
  2589 00008788 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2590                              <1> 
  2591 0000878A 0FB705[E8DD0000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2592 00008791 29D0                <1> 	sub	eax, edx
  2593 00008793 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 00008795 E805FDFFFF          <1> 	call	delete_longname
  2598                              <1> 
  2599                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2600 0000879A E83BFCFFFF          <1> 	call	update_parent_dir_lmdt
  2601 0000879F 31C0                <1> 	xor	eax, eax 
  2602 000087A1 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 000087A2 3C02                <1> 	cmp	al, 2
  2643 000087A4 0F846D010000        <1> 	je	msftdf_df2_check_directory
  2644 000087AA A2[66DF0000]        <1> 	mov	[move_cmd_phase], al
  2645                              <1> 
  2646                              <1> msftdf_parse_sf_path:
  2647                              <1> 	; ESI = ASCIIZ pathname (Source)
  2648 000087AF 57                  <1> 	push	edi 
  2649 000087B0 BF[64DE0000]        <1> 	mov	edi, SourceFile_Drv
  2650 000087B5 E821F7FFFF          <1> 	call	parse_path_name
  2651 000087BA 5E                  <1> 	pop	esi
  2652 000087BB 7211                <1> 	jc	short msftdf_psf_retn
  2653                              <1> 
  2654                              <1> msftdf_parse_df_path:
  2655                              <1> 	; ESI = ASCIIZ pathname	(Destination)
  2656 000087BD BF[E4DE0000]        <1> 	mov	edi, DestinationFile_Drv
  2657 000087C2 E814F7FFFF          <1> 	call	parse_path_name
  2658 000087C7 7306                <1> 	jnc	short msftdf_check_sf_drv
  2659                              <1> 
  2660 000087C9 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  2661 000087CB 7602                <1> 	jna	short msftdf_check_sf_drv
  2662                              <1> 
  2663                              <1> msftdf_stc_retn:
  2664 000087CD F9                  <1> 	stc
  2665                              <1> msftdf_psf_retn:
  2666 000087CE C3                  <1> 	retn 
  2667                              <1> 
  2668                              <1> msftdf_check_sf_drv:
  2669 000087CF A0[64DE0000]        <1> 	mov	al, [SourceFile_Drv]
  2670                              <1> 
  2671                              <1> msftdf_check_df_drv:
  2672 000087D4 8A15[E4DE0000]      <1> 	mov	dl, [DestinationFile_Drv]
  2673                              <1> 
  2674                              <1> msftdf_compare_sf_df_drv:
  2675 000087DA 29DB                <1> 	sub	ebx, ebx
  2676 000087DC 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  2677 000087E2 38C2                <1> 	cmp	dl, al
  2678 000087E4 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 000087E6 88C6                <1> 	mov	dh, al ; destination file's drive number
  2683 000087E8 B811000000          <1> 	mov	eax, 11h ; Not the same drive
  2684 000087ED F9                  <1> 	stc
  2685 000087EE C3                  <1> 	retn 
  2686                              <1> 
  2687                              <1> msftdf_check_sf_df_drv_ok:
  2688 000087EF 8815[67DF0000]      <1> 	mov	[msftdf_sf_df_drv], dl
  2689                              <1> 
  2690 000087F5 29C0                <1>         sub	eax, eax
  2691 000087F7 88D4                <1> 	mov	ah, dl
  2692 000087F9 0500010900          <1> 	add	eax, Logical_DOSDisks
  2693 000087FE A3[68DF0000]        <1> 	mov	[msftdf_drv_offset], eax
  2694                              <1> 
  2695 00008803 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  2696 00008805 7407                <1> 	je	short msftdf_df_check_directory
  2697                              <1> 
  2698                              <1> msftdf_change_drv:
  2699 00008807 E829C1FFFF          <1> 	call 	change_current_drive
  2700 0000880C 725B                <1> 	jc	short msftdf_df_error_retn
  2701                              <1> 	  
  2702                              <1> msftdf_check_destination_file:
  2703                              <1> msftdf_df_check_directory:
  2704 0000880E BE[E5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  2705 00008813 803E20              <1> 	cmp	byte [esi], 20h
  2706 00008816 760F                <1> 	jna	short msftdf_df_find_1
  2707                              <1> 
  2708                              <1> msftdf_df_change_directory:
  2709 00008818 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2710 0000881E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2711 00008820 E8A2F0FFFF          <1> 	call	change_current_directory
  2712 00008825 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 00008827 BE[26DF0000]        <1>         mov     esi, DestinationFile_Name
  2719 0000882C 803E20              <1> 	cmp	byte [esi], 20h
  2720 0000882F 761F                <1> 	jna	short msftdf_df_copy_sf_name
  2721                              <1> 
  2722                              <1> msftdf_df_find_2:
  2723 00008831 6631C0              <1> 	xor	ax, ax ; DestinationFile_AttributesMask -> any/zero
  2724 00008834 E898D4FFFF          <1> 	call	find_first_file
  2725 00008839 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 0000883B 3C02                <1> 	cmp	al, 2
  2730 0000883D 7529                <1> 	jne	short msftdf_df_stc_retn
  2731                              <1>               
  2732                              <1> msftdf_convert_df_direntry_name:
  2733 0000883F BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  2734 00008844 BF[36DF0000]        <1> 	mov	edi, DestinationFile_DirEntry
  2735 00008849 E8C2F5FFFF          <1> 	call	convert_file_name
  2736 0000884E EB1A                <1>   	jmp	short msftdf_restore_current_dir_1
  2737                              <1> 
  2738                              <1> msftdf_df_copy_sf_name:
  2739 00008850 89F7                <1> 	mov	edi, esi
  2740 00008852 57                  <1> 	push	edi 
  2741 00008853 BE[A6DE0000]        <1>         mov     esi, SourceFile_Name
  2742 00008858 B90C000000          <1> 	mov	ecx, 12
  2743                              <1> msftdf_df_copy_sf_name_loop:
  2744 0000885D AC                  <1> 	lodsb
  2745 0000885E AA                  <1>         stosb
  2746 0000885F 08C0                <1> 	or	al, al
  2747 00008861 7402                <1> 	jz	short msftdf_df_copy_sf_name_ok	
  2748 00008863 E2F8                <1>         loop    msftdf_df_copy_sf_name_loop
  2749                              <1> msftdf_df_copy_sf_name_ok:	
  2750 00008865 5E                  <1> 	pop	esi  
  2751 00008866 EBC9                <1> 	jmp	short msftdf_df_find_2
  2752                              <1> 
  2753                              <1> msftdf_df_stc_retn:
  2754 00008868 F9                  <1> 	stc
  2755                              <1> msftdf_restore_cdir_failed:
  2756                              <1> msftdf_df_error_retn:
  2757 00008869 C3                  <1> 	retn
  2758                              <1> 
  2759                              <1> msftdf_restore_current_dir_1:
  2760 0000886A 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2761 00008871 760D                <1> 	jna	short msftdf_sf_check_directory
  2762 00008873 8B35[68DF0000]      <1> 	mov	esi, [msftdf_drv_offset] 
  2763 00008879 E869C1FFFF          <1> 	call	restore_current_directory
  2764 0000887E 72E9                <1> 	jc	short msftdf_restore_cdir_failed
  2765                              <1> 
  2766                              <1> msftdf_sf_check_directory:
  2767 00008880 BE[65DE0000]        <1> 	mov	esi, SourceFile_Directory
  2768 00008885 803E20              <1> 	cmp	byte [esi], 20h
  2769 00008888 760F                <1> 	jna	short msftdf_sf_find
  2770                              <1> msftdf_sf_change_directory:
  2771 0000888A FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2772 00008890 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2773 00008892 E830F0FFFF          <1> 	call	change_current_directory
  2774 00008897 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 00008899 BE[A6DE0000]        <1>         mov     esi, SourceFile_Name  ; Offset 66
  2781 0000889E 66B80018            <1> 	mov	ax, 1800h ; Only files
  2782 000088A2 E82AD4FFFF          <1> 	call	find_first_file
  2783 000088A7 7217                <1> 	jc	short msftdf_return
  2784                              <1> 
  2785                              <1> msftdf_sf_ambgfn_check:
  2786 000088A9 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  2787 000088AC 7407                <1> 	jz	short msftdf_sf_found
  2788                              <1> 
  2789                              <1> msftdf_ambiguous_file_name_error:
  2790 000088AE B802000000          <1> 	mov	eax, 2 ; File not found error
  2791 000088B3 F9                  <1> 	stc
  2792 000088B4 C3                  <1> 	retn
  2793                              <1> 
  2794                              <1> msftdf_sf_found:
  2795 000088B5 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  2796 000088B8 7416                <1> 	jz	short msftdf_save_sf_structure
  2797                              <1> 
  2798                              <1> msftdf_permission_denied_retn:
  2799 000088BA B805000000          <1> 	mov	eax, 05h ; Access (Permission) denied !
  2800 000088BF F9                  <1> 	stc
  2801                              <1> msftdf_rest_cdir_err_retn:
  2802                              <1> msftdf_return:
  2803 000088C0 C3                  <1> 	retn
  2804                              <1> 
  2805                              <1> msftdf_phase_1_return:
  2806 000088C1 31C0                <1> 	xor	eax, eax
  2807 000088C3 A2[66DF0000]        <1> 	mov	[move_cmd_phase], al ; 0
  2808 000088C8 FEC0                <1> 	inc	al ; mov al, 1
  2809 000088CA BB[17890000]        <1> 	mov	ebx, msftdf_df2_check_directory
  2810                              <1> 	;mov	edx, 0FFFFFFFFh 
  2811 000088CF C3                  <1> 	retn
  2812                              <1> 
  2813                              <1> msftdf_save_sf_structure:
  2814 000088D0 BE[74DD0000]        <1> 	mov	esi, FindFile_DirEntry
  2815 000088D5 BF[B6DE0000]        <1> 	mov	edi, SourceFile_DirEntry
  2816 000088DA B908000000          <1> 	mov	ecx, 8
  2817 000088DF F3A5                <1> 	rep	movsd
  2818                              <1> 
  2819                              <1> msftdf_df_copy_sf_parameters:
  2820 000088E1 BE0B000000          <1> 	mov	esi, 11
  2821 000088E6 89F7                <1> 	mov	edi, esi
  2822 000088E8 81C6[B6DE0000]      <1> 	add	esi, SourceFile_DirEntry
  2823 000088EE 81C7[36DF0000]      <1> 	add	edi, DestinationFile_DirEntry
  2824                              <1> 	;mov	ecx, 21
  2825 000088F4 B115                <1> 	mov	cl, 21
  2826 000088F6 F3A4                <1> 	rep	movsb
  2827                              <1> 
  2828                              <1> msftdf_restore_current_dir_2:
  2829 000088F8 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2830 000088FF 760D                <1> 	jna	short msftdf_df2_check_move_cmd_phase
  2831 00008901 8B35[68DF0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2832 00008907 E8DBC0FFFF          <1> 	call	restore_current_directory
  2833 0000890C 72B2                <1> 	jc	short msftdf_rest_cdir_err_retn
  2834                              <1> 
  2835                              <1> msftdf_df2_check_move_cmd_phase:
  2836 0000890E 803D[66DF0000]01    <1> 	cmp	byte [move_cmd_phase], 1
  2837 00008915 74AA                <1> 	je	short msftdf_phase_1_return
  2838                              <1> 
  2839                              <1> msftdf_df2_check_directory:
  2840 00008917 BE[E5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  2841 0000891C 803E20              <1> 	cmp	byte [esi], 20h
  2842 0000891F 760F                <1> 	jna	short msftdf_make_dfde_locate_ffe_on_directory
  2843                              <1> msftdf_df2_change_directory:
  2844 00008921 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2845 00008927 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2846 00008929 E899EFFFFF          <1> 	call	change_current_directory
  2847 0000892E 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 00008930 31C0                <1> 	xor	eax, eax
  2859 00008932 89C1                <1> 	mov	ecx, eax
  2860 00008934 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 00008936 E8E0F1FFFF          <1> 	call	locate_current_dir_file
  2865 0000893B 733F                <1> 	jnc	msftdf_make_dfde_set_ff_dir_entry
  2866                              <1> 	
  2867                              <1> 	;cmp	eax, 2
  2868 0000893D 3C02                <1>         cmp	al, 2
  2869 0000893F 7537                <1> 	jne	short msftdf_error_retn
  2870                              <1> 
  2871                              <1> msftdf_add_new_dir_entry_check_fs:
  2872 00008941 8B35[68DF0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2873 00008947 A1[ADDB0000]        <1> 	mov 	eax, [DirBuff_Cluster]
  2874 0000894C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2875 00008950 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 00008952 30ED                <1> 	xor	ch, ch ; cx = 0 --> add a new subdir section
  2881 00008954 E8750C0000          <1> 	call	add_new_fs_section
  2882 00008959 721E                <1>         jc	short msftdf_dsfde_error_retn
  2883                              <1> 	;mov	[createfile_LastDirCluster], eax
  2884                              <1> 
  2885 0000895B E8950E0000          <1> 	call	load_FS_sub_directory 
  2886                              <1> 	;mov	ebx, Directory_Buffer 
  2887 00008960 7318                <1> 	jnc	short msftdf_add_new_fs_subdir_section_ok
  2888 00008962 C3                  <1> 	retn	 
  2889                              <1> 
  2890                              <1> msftdf_add_new_subdir_cluster:
  2891 00008963 E863150000          <1> 	call	add_new_cluster
  2892 00008968 720F                <1> 	jc	short msftdf_dsfde_error_retn
  2893                              <1> 	
  2894                              <1> 	;mov	[createfile_LastDirCluster], eax
  2895                              <1> 
  2896 0000896A E8490E0000          <1> 	call	load_FAT_sub_directory
  2897 0000896F 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 00008971 50                  <1> 	push	eax
  2903 00008972 E863FAFFFF          <1> 	call	update_parent_dir_lmdt
  2904 00008977 58                  <1> 	pop	eax
  2905                              <1> 
  2906                              <1> msftdf_error_retn:
  2907 00008978 F9                  <1> 	stc
  2908                              <1> msftdf_dsfde_restore_cdir_failed:
  2909                              <1> msftdf_dsfde_error_retn:
  2910 00008979 C3                  <1> 	retn
  2911                              <1> 
  2912                              <1> msftdf_add_new_fs_subdir_section_ok:
  2913                              <1> msftdf_add_new_subdir_cluster_ok:
  2914 0000897A 89DF                <1> 	mov	edi, ebx ; Directory buffer address
  2915                              <1> 
  2916                              <1> msftdf_make_dfde_set_ff_dir_entry:
  2917 0000897C 8B15[78D30000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2918 00008982 8915[CCDF0000]      <1> 	mov	[createfile_FFCluster], edx
  2919                              <1> 	; EDI = Directory entry offset
  2920 00008988 BE[36DF0000]        <1> 	mov	esi, DestinationFile_DirEntry
  2921 0000898D B908000000          <1> 	mov	ecx, 8
  2922 00008992 F3A5                <1> 	rep	movsd
  2923                              <1> 
  2924 00008994 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  2925 0000899B E89FF9FFFF          <1> 	call	save_directory_buffer
  2926 000089A0 72CF                <1> 	jc	short msftdf_make_dfde_err_upd_pdir_lmdt
  2927                              <1> 
  2928                              <1> msftdf_make_dfde_update_pdir_lmdt:
  2929 000089A2 E833FAFFFF          <1> 	call	update_parent_dir_lmdt
  2930                              <1> 
  2931                              <1> msftdf_dsfde_restore_current_dir_1:
  2932 000089A7 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2933 000089AE 760D                <1> 	jna	short msftdf_dsfde_check_directory
  2934 000089B0 8B35[68DF0000]      <1>  	mov	esi, [msftdf_drv_offset]
  2935 000089B6 E82CC0FFFF          <1> 	call	restore_current_directory
  2936 000089BB 72BC                <1> 	jc	short msftdf_dsfde_restore_cdir_failed
  2937                              <1> 
  2938                              <1> msftdf_dsfde_check_directory:
  2939 000089BD BE[65DE0000]        <1> 	mov	esi, SourceFile_Directory
  2940 000089C2 803E20              <1> 	cmp	byte [esi], 20h
  2941 000089C5 760F                <1> 	jna	short msftdf_dsfde_find_file
  2942                              <1> 
  2943                              <1> msftdf_dsfde_change_directory:
  2944 000089C7 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  2945 000089CD 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  2946 000089CF E8F3EEFFFF          <1> 	call	change_current_directory
  2947 000089D4 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 000089D6 BE[A6DE0000]        <1> 	mov	esi, SourceFile_Name  ; Offset 66
  2954 000089DB 668B460E            <1> 	mov	ax, [esi+14] ; 80 -> SourceFile_AttributesMask
  2955 000089DF E8EDD2FFFF          <1> 	call	find_first_file
  2956 000089E4 7293                <1> 	jc	short msftdf_dsfde_error_retn
  2957                              <1> 
  2958                              <1> msftdf_dsfde_delete_direntry:
  2959 000089E6 8B35[68DF0000]      <1> 	mov	esi, [msftdf_drv_offset]
  2960                              <1> 	
  2961 000089EC 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2962 000089F0 770A                <1> 	ja	short msftdf_delete_FAT_direntry
  2963                              <1> 	
  2964 000089F2 30DB                <1> 	xor	bl, bl
  2965                              <1> 	; BL = 0 -> File
  2966                              <1> 	; EDI -> Directory buffer entry offset/address 
  2967 000089F4 E8D60B0000          <1> 	call	delete_fs_directory_entry
  2968 000089F9 7315                <1> 	jnc	short msftdf_dsfde_restore_current_dir_2
  2969 000089FB C3                  <1> 	retn
  2970                              <1> 
  2971                              <1> msftdf_delete_FAT_direntry:	
  2972 000089FC 8A1D[71DD0000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  2973 00008A02 668B0D[9CDD0000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  2974                              <1> 	; ESI = Logical DOS drive description table address
  2975                              <1> 	; EDI = Directory buffer entry offset/address 
  2976 00008A09 E8ABFCFFFF          <1> 	call	delete_directory_entry
  2977 00008A0E 721C                <1> 	jc	short msftdf_retn
  2978                              <1> 
  2979                              <1> msftdf_dsfde_restore_current_dir_2:
  2980 00008A10 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2981 00008A17 7607                <1> 	jna	short msftdf_new_dir_fcluster_retn
  2982                              <1> 	;mov	esi, [msftdf_drv_offset]
  2983 00008A19 E8C9BFFFFF          <1> 	call	restore_current_directory
  2984 00008A1E 720C                <1> 	jc	short msftdf_retn
  2985                              <1> 
  2986                              <1> msftdf_new_dir_fcluster_retn:
  2987 00008A20 31C9                <1> 	xor	ecx, ecx 
  2988 00008A22 A1[CCDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  2989 00008A27 BB[E4DE0000]        <1> 	mov	ebx, DestinationFile_Drv
  2990                              <1> 
  2991                              <1> msftdf_retn:
  2992 00008A2C 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 00008A2D 3C02                <1> 	cmp	al, 2
  3053 00008A2F 0F844C020000        <1> 	je	csftdf2_check_cdrv
  3054                              <1> 
  3055                              <1> ; Phase 1
  3056                              <1> 
  3057 00008A35 A2[8CDF0000]        <1> 	mov	byte [copy_cmd_phase], al
  3058                              <1> 
  3059 00008A3A 57                  <1> 	push	edi ; *
  3060                              <1> 
  3061                              <1> csftdf_parse_sf_path:
  3062 00008A3B BF[64DE0000]        <1> 	mov	edi, SourceFile_Drv
  3063 00008A40 E896F4FFFF          <1> 	call	parse_path_name
  3064 00008A45 721C                <1> 	jc	short csftdf_parse_sf_path_failed
  3065                              <1> 
  3066                              <1> csftdf_parse_df_path:	
  3067 00008A47 5E                  <1> 	pop	esi ; * (pushed edi) 
  3068                              <1> 
  3069                              <1> csftdf_sf_check_filename_exists:
  3070 00008A48 803D[A6DE0000]21    <1> 	cmp	byte [SourceFile_Name], 21h
  3071 00008A4F 7215                <1> 	jb	short csftdf_sf_file_not_found_error
  3072                              <1> 
  3073 00008A51 BF[E4DE0000]        <1> 	mov	edi, DestinationFile_Drv
  3074 00008A56 E880F4FFFF          <1> 	call	parse_path_name
  3075 00008A5B 7310                <1> 	jnc	short csftdf_check_sf_cdrv
  3076                              <1> 	
  3077 00008A5D 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  3078 00008A5F 760C                <1> 	jna	short csftdf_check_sf_cdrv
  3079                              <1> 
  3080                              <1> csftdf_parse_df_path_failed:
  3081 00008A61 F9                  <1> 	stc 
  3082                              <1> csftdf_sf_error_retn: 
  3083 00008A62 C3                  <1> 	retn
  3084                              <1> 
  3085                              <1> csftdf_parse_sf_path_failed:	
  3086 00008A63 5F                  <1> 	pop	edi ; *
  3087 00008A64 EBFC                <1> 	jmp	short csftdf_sf_error_retn
  3088                              <1> 
  3089                              <1> csftdf_sf_file_not_found_error:
  3090 00008A66 B802000000          <1> 	mov	eax, 2 ; File not found 
  3091 00008A6B EBF5                <1> 	jmp	short csftdf_sf_error_retn
  3092                              <1> 
  3093                              <1> csftdf_check_sf_cdrv:
  3094 00008A6D 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  3095                              <1> 
  3096 00008A73 883D[8FDF0000]      <1> 	mov	[csftdf_cdrv], bh ; 23/03/2016
  3097                              <1> 
  3098 00008A79 8A15[64DE0000]      <1> 	mov	dl, [SourceFile_Drv]
  3099 00008A7F 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  3100 00008A81 7407                <1> 	je	short csftdf_sf_check_directory
  3101                              <1> 
  3102 00008A83 E8ADBEFFFF          <1> 	call	change_current_drive
  3103 00008A88 72D8                <1> 	jc	short csftdf_sf_error_retn
  3104                              <1> 
  3105                              <1> csftdf_sf_check_directory:
  3106 00008A8A BE[65DE0000]        <1> 	mov	esi, SourceFile_Directory
  3107 00008A8F 803E20              <1> 	cmp	byte [esi], 20h
  3108 00008A92 760F                <1> 	jna	short csftdf_find_sf
  3109                              <1> 
  3110                              <1> csftdf_sf_change_directory:
  3111 00008A94 FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3112 00008A9A 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3113 00008A9C E826EEFFFF          <1> 	call	change_current_directory
  3114 00008AA1 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 00008AA3 BE[A6DE0000]        <1> 	mov	esi, SourceFile_Name
  3121 00008AA8 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3122 00008AAC E820D2FFFF          <1> 	call	find_first_file
  3123 00008AB1 72AF                <1> 	jc	short csftdf_sf_error_retn
  3124                              <1> 
  3125                              <1> csftdf_sf_ambgfn_check:
  3126 00008AB3 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3127 00008AB6 7407                <1> 	jz	short csftdf_sf_found
  3128                              <1> 
  3129                              <1> csftdf_ambiguous_file_name_error:
  3130 00008AB8 B802000000          <1> 	mov	eax, 2 ; File not found error
  3131 00008ABD F9                  <1> 	stc
  3132 00008ABE C3                  <1> 	retn
  3133                              <1> 
  3134                              <1> csftdf_sf_found:
  3135 00008ABF A3[90DF0000]        <1> 	mov	[csftdf_filesize], eax
  3136                              <1> 
  3137 00008AC4 09C0                <1> 	or	eax, eax
  3138 00008AC6 7507                <1> 	jnz	short csftdf_set_source_file_direnry
  3139                              <1> 
  3140                              <1> csftdf_sf_file_size_zero:
  3141 00008AC8 B80E000000          <1> 	mov	eax, 0Eh ; TRDOS zero length error
  3142 00008ACD F9                  <1> 	stc
  3143 00008ACE C3                  <1> 	retn
  3144                              <1> 
  3145                              <1> csftdf_set_source_file_direnry:
  3146 00008ACF BE[74DD0000]        <1> 	mov	esi, FindFile_DirEntry
  3147 00008AD4 BF[B6DE0000]        <1> 	mov	edi, SourceFile_DirEntry
  3148 00008AD9 B908000000          <1> 	mov	ecx, 8
  3149 00008ADE F3A5                <1> 	rep	movsd
  3150                              <1> 
  3151                              <1> csftdf_sf_restore_cdrv:
  3152                              <1> 	; 22/03/2016
  3153 00008AE0 8A15[8FDF0000]      <1> 	mov	dl, [csftdf_cdrv]
  3154 00008AE6 3A15[7ED30000]      <1> 	cmp	dl, [Current_Drv]
  3155 00008AEC 7407                <1> 	je	short csftdf_sf_restore_cdir
  3156 00008AEE E842BEFFFF          <1> 	call	change_current_drive 
  3157 00008AF3 724F                <1> 	jc	short csftdf_df_error_retn ; 30/03/2016
  3158                              <1> 
  3159                              <1> csftdf_sf_restore_cdir:
  3160 00008AF5 803D[19C20000]00    <1> 	cmp	byte [Restore_CDIR], 0
  3161 00008AFC 7612                <1> 	jna	short csftdf_df_check_filename_exists
  3162 00008AFE 29C0                <1> 	sub	eax, eax
  3163 00008B00 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3164 00008B05 88D4                <1> 	mov	ah, dl ; byte [csftdf_cdrv]
  3165 00008B07 01C6                <1> 	add	esi, eax
  3166 00008B09 E8D9BEFFFF          <1> 	call	restore_current_directory
  3167 00008B0E 7234                <1> 	jc	short csftdf_df_error_retn
  3168                              <1>   
  3169                              <1> csftdf_df_check_filename_exists:
  3170 00008B10 803D[26DF0000]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  3171 00008B17 7716                <1> 	ja	short csftdf_check_df_cdrv
  3172                              <1> 
  3173                              <1> csftdf_copy_sf_name:
  3174 00008B19 BF[26DF0000]        <1> 	mov	edi, DestinationFile_Name
  3175 00008B1E BE[A6DE0000]        <1> 	mov	esi, SourceFile_Name
  3176 00008B23 B10C                <1> 	mov	cl, 12
  3177                              <1> 
  3178                              <1> csftdf_df_copy_sf_name_loop:
  3179 00008B25 AC                  <1> 	lodsb
  3180 00008B26 AA                  <1> 	stosb
  3181 00008B27 08C0                <1> 	or	al, al
  3182 00008B29 7404                <1> 	jz	short csftdf_check_df_cdrv             
  3183 00008B2B FEC9                <1> 	dec	cl
  3184 00008B2D 75F6                <1> 	jnz	csftdf_df_copy_sf_name_loop
  3185                              <1> 
  3186                              <1> csftdf_check_df_cdrv:
  3187 00008B2F 8A15[E4DE0000]      <1> 	mov	dl, [DestinationFile_Drv]
  3188 00008B35 3A15[7ED30000]      <1> 	cmp	dl, [Current_Drv]
  3189 00008B3B 7408                <1> 	je	short csftdf_df_check_directory
  3190                              <1> 
  3191 00008B3D E8F3BDFFFF          <1> 	call	change_current_drive
  3192 00008B42 7301                <1> 	jnc	short csftdf_df_check_directory
  3193                              <1> 
  3194                              <1> csftdf_df_error_retn:
  3195 00008B44 C3                  <1> 	retn
  3196                              <1> 
  3197                              <1> csftdf_df_check_directory:
  3198 00008B45 BE[E5DE0000]        <1> 	mov	esi, DestinationFile_Directory
  3199 00008B4A 803E20              <1>         cmp     byte [esi], 20h
  3200 00008B4D 760F                <1> 	jna	short csftdf_find_df
  3201                              <1> 
  3202                              <1> csftdf_df_change_directory:
  3203 00008B4F FE05[19C20000]      <1> 	inc	byte [Restore_CDIR]
  3204 00008B55 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  3205 00008B57 E86BEDFFFF          <1> 	call	change_current_directory
  3206 00008B5C 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 00008B5E 29DB                <1> 	sub	ebx, ebx
  3214 00008B60 8A3D[E4DE0000]      <1> 	mov	bh,  [DestinationFile_Drv]
  3215 00008B66 81C300010900        <1> 	add	ebx, Logical_DOSDisks
  3216 00008B6C 891D[BCDF0000]      <1> 	mov	[csftdf_df_drv_dt], ebx
  3217                              <1> 
  3218 00008B72 BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  3219 00008B77 6631C0              <1> 	xor	ax, ax 
  3220                              <1> 		; DestinationFile_AttributesMask -> any/zero
  3221 00008B7A E852D1FFFF          <1> 	call	find_first_file
  3222 00008B7F 7218                <1> 	jc	short csftdf_df_check_error_code
  3223                              <1> 
  3224                              <1> csftdf_df_ambgfn_check:
  3225 00008B81 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3226 00008B84 7511                <1> 	jnz	short csftdf_df_error_stc_retn
  3227                              <1> 	
  3228                              <1> csftdf_df_found:
  3229 00008B86 C605[8EDF0000]01    <1> 	mov	byte [DestinationFileFound], 1
  3230 00008B8D 80E11F              <1> 	and	cl, 1Fh ; Attributes, D-V-S-H-R
  3231 00008B90 7451                <1> 	jz	short csftdf_df_save_first_cluster
  3232                              <1> 
  3233                              <1> csftdf_df_permission_denied_retn:	 
  3234 00008B92 B805000000          <1> 	mov	eax, 05h ; Access/Permisson denied.
  3235                              <1> csftdf_df_error_stc_retn:
  3236 00008B97 F9                  <1> 	stc
  3237 00008B98 C3                  <1> 	retn
  3238                              <1> 
  3239                              <1> csftdf_df_check_error_code:
  3240                              <1> 	;cmp	eax, 2
  3241 00008B99 3C02                <1> 	cmp	al, 2
  3242 00008B9B 75FA                <1> 	jne	short csftdf_df_error_stc_retn
  3243                              <1> 
  3244                              <1> 	; 21/03/2016
  3245                              <1> 	; (Capitalized file name)
  3246 00008B9D BE[64DD0000]        <1> 	mov	esi, FindFile_Name
  3247 00008BA2 BF[26DF0000]        <1> 	mov	edi, DestinationFile_Name
  3248 00008BA7 A5                  <1> 	movsd
  3249 00008BA8 A5                  <1> 	movsd	
  3250 00008BA9 A5                  <1> 	movsd
  3251                              <1> 	;movsb
  3252                              <1> 
  3253 00008BAA C605[8EDF0000]00    <1> 	mov	byte [DestinationFileFound], 0
  3254                              <1> 
  3255                              <1> csftdf_check_disk_free_size_0:
  3256 00008BB1 A1[D2DE0000]        <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 00008BB6 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3265                              <1> 
  3266 00008BBC 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3267 00008BC0 01C8                <1> 	add	eax, ecx
  3268 00008BC2 48                  <1> 	dec	eax  ; file size (additional bytes) + 511 (round up)
  3269                              <1> csftdf_check_disk_free_size_3: ; 16/03/2016
  3270 00008BC3 29D2                <1> 	sub	edx, edx
  3271 00008BC5 F7F1                <1> 	div	ecx ; bytes per sector
  3272                              <1> 
  3273                              <1> csftdf_check_disk_free_size:
  3274 00008BC7 3B4674              <1> 	cmp	eax, [esi+LD_FreeSectors]
  3275 00008BCA 0F8294000000        <1>         jb      csftdf_check_disk_free_size_ok
  3276 00008BD0 770A                <1> 	ja	short csftdf_df_insufficient_disk_space
  3277                              <1> 
  3278 00008BD2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0 ; FS needs FDT sector also.
  3279 00008BD6 0F8788000000        <1>         ja      csftdf_check_disk_free_size_ok 
  3280                              <1> 
  3281                              <1> csftdf_df_insufficient_disk_space:
  3282 00008BDC B827000000          <1> 	mov	eax, 27h ; insufficient disk space
  3283 00008BE1 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 00008BE3 81EF00000800        <1> 	sub	edi, Directory_Buffer  ; (<65536)
  3291 00008BE9 66C1EF05            <1> 	shr	di, 5 ; Convert entry offset to entry index/number
  3292 00008BED 66893D[5EDF0000]    <1> 	mov	[DestinationFile_DirEntryNumber], di ; (<2048)
  3293                              <1> 
  3294                              <1> csftdf_df_check_sf_df_fcluster:
  3295 00008BF4 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  3296 00008BF8 C1E210              <1> 	shl	edx, 16
  3297 00008BFB 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  3298 00008BFF 8915[A0DF0000]      <1> 	mov	[csftdf_df_cluster], edx
  3299                              <1> csftdf_df_check_sf_df_fcluster_1:
  3300 00008C05 668B15[CADE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3301 00008C0C C1E210              <1> 	shl	edx, 16
  3302 00008C0F 668B15[D0DE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3303 00008C16 3B15[A0DF0000]      <1> 	cmp	edx, [csftdf_df_cluster]
  3304 00008C1C 7512                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3305                              <1> csftdf_df_check_sf_df_drv:
  3306 00008C1E 8A15[64DE0000]      <1> 	mov	dl, [SourceFile_Drv]
  3307 00008C24 3A15[E4DE0000]      <1> 	cmp	dl, [DestinationFile_Drv]
  3308 00008C2A 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 00008C2C 31C0                <1> 	xor	eax, eax ; mov eax, 0 -> Bad command or file name !
  3314 00008C2E F9                  <1> 	stc
  3315 00008C2F 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 00008C30 BF[36DF0000]        <1> 	mov	edi, DestinationFile_DirEntry
  3321 00008C35 B908000000          <1> 	mov	ecx, 8
  3322 00008C3A F3A5                <1> 	rep	movsd
  3323                              <1> 	
  3324                              <1> csftdf_check_disk_free_size_2:
  3325 00008C3C 89C2                <1> 	mov	edx, eax ; Old destination file size
  3326                              <1> 
  3327                              <1> 	;mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3328 00008C3E A1[90DF0000]        <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 00008C43 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3338                              <1> 
  3339 00008C49 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3340 00008C4D 01CA                <1> 	add	edx, ecx ; + 512
  3341 00008C4F 01C8                <1> 	add	eax, ecx ; + 512
  3342 00008C51 4A                  <1> 	dec	edx ; old file size + 511 (round up)
  3343 00008C52 48                  <1> 	dec	eax ; new file size + 511 (round up)
  3344 00008C53 F7D9                <1> 	neg	ecx ; -512 ; 0FFFFFE00h
  3345 00008C55 21CA                <1> 	and	edx, ecx ; = old sector count * 512 
  3346 00008C57 21C8                <1> 	and	eax, ecx ; = new sector count * 512 
  3347                              <1> 
  3348 00008C59 29D0                <1> 	sub	eax, edx ; new file size - old file size (on disk)
  3349 00008C5B 7607                <1> 	jna	short csftdf_check_disk_free_size_ok
  3350                              <1> 
  3351 00008C5D 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 00008C5F 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 00008C64 A0[8CDF0000]        <1> 	mov	al, [copy_cmd_phase]
  3361 00008C69 3C01                <1> 	cmp	al, 1
  3362 00008C6B 7514                <1> 	jne	short csftdf2_check_cdrv
  3363                              <1> 	
  3364 00008C6D 31C0                <1> 	xor	eax, eax
  3365 00008C6F A2[8CDF0000]        <1> 	mov	[copy_cmd_phase], al ; 0
  3366                              <1> 
  3367 00008C74 8A15[8EDF0000]      <1> 	mov	dl, [DestinationFileFound]            
  3368 00008C7A 8A35[C1DE0000]      <1> 	mov	dh, [SourceFile_DirEntry+11] ; Attributes
  3369                              <1>  
  3370                              <1> csftdf_return:	
  3371 00008C80 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 00008C81 803D[8EDF0000]00    <1> 	cmp	byte [DestinationFileFound], 0 
  3405 00008C88 7739                <1> 	ja	short csftdf2_set_sf_percentage
  3406                              <1> 
  3407                              <1> csftdf2_create_file:
  3408 00008C8A BE[26DF0000]        <1> 	mov	esi, DestinationFile_Name
  3409 00008C8F A1[90DF0000]        <1> 	mov	eax, [csftdf_filesize]
  3410 00008C94 30C9                <1> 	xor	cl, cl ; 0
  3411                              <1> 
  3412 00008C96 31DB                <1> 	xor	ebx, ebx ; 0
  3413 00008C98 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 00008C99 E8EC050000          <1> 	call	create_file
  3432                              <1> 	;pop	esi
  3433 00008C9E 0F82A3050000        <1>         jc      csftdf2_rw_error
  3434                              <1> 
  3435                              <1> csftdf2_create_file_OK:
  3436 00008CA4 A3[A0DF0000]        <1> 	mov	[csftdf_df_cluster], eax
  3437                              <1> 	
  3438                              <1> 	; 24/03/2016
  3439 00008CA9 668915[5EDF0000]    <1> 	mov	[DestinationFile_DirEntryNumber], dx 
  3440                              <1> 
  3441                              <1> 	; 21/03/2016
  3442 00008CB0 BE00000800          <1> 	mov	esi, Directory_Buffer
  3443 00008CB5 C1E205              <1> 	shl	edx, 5 ; 32 * index number
  3444 00008CB8 01D6                <1> 	add	esi, edx
  3445 00008CBA BF[36DF0000]        <1> 	mov	edi, DestinationFile_DirEntry	
  3446 00008CBF B108                <1> 	mov	cl, 8 ; 32 bytes
  3447 00008CC1 F3A5                <1> 	rep	movsd
  3448                              <1> 
  3449                              <1> csftdf2_set_sf_percentage:
  3450                              <1> 	; 17/03/2016
  3451 00008CC3 31C0                <1> 	xor	eax, eax	
  3452 00008CC5 A2[B4DF0000]        <1> 	mov 	[csftdf_percentage], al ; 0, reset
  3453                              <1> 
  3454 00008CCA A3[ACDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax ; 0, reset
  3455 00008CCF A3[B0DF0000]        <1> 	mov	[csftdf_df_wbytes], eax ; 0, reset
  3456                              <1> 
  3457 00008CD4 8A25[64DE0000]      <1> 	mov	ah, [SourceFile_Drv]	
  3458 00008CDA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3459 00008CDF 01C6                <1> 	add	esi, eax
  3460                              <1> 	
  3461 00008CE1 8935[B8DF0000]      <1> 	mov	[csftdf_sf_drv_dt], esi ; 23/03/2016
  3462                              <1> 
  3463 00008CE7 668B15[CADE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3464 00008CEE C1E210              <1> 	shl	edx, 16
  3465 00008CF1 668B15[D0DE0000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3466 00008CF8 8915[9CDF0000]      <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 00008CFE 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  3475 00008D02 880D[E2DE0000]      <1> 	mov	[SourceFile_SecPerClust], cl
  3476                              <1> 
  3477                              <1> 	; 17/03/2016
  3478 00008D08 386E03              <1> 	cmp	[esi+LD_FATType], ch ; 0
  3479 00008D0B 7707                <1> 	ja	short csftdf2_set_sf_percent_rsize1
  3480                              <1> 
  3481 00008D0D B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3482 00008D12 EB06                <1> 	jmp	short csftdf2_set_sf_percent_rsize2	
  3483                              <1>  
  3484                              <1> csftdf2_set_sf_percent_rsize1:
  3485 00008D14 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  3486 00008D18 F7E1                <1> 	mul	ecx
  3487                              <1> 	;sub	edx, edx
  3488                              <1> csftdf2_set_sf_percent_rsize2:
  3489 00008D1A A3[A4DF0000]        <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 00008D1F 8B3D[BCDF0000]      <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 00008D25 8A4F13              <1> 	mov	cl, [edi+LD_BPB+SecPerClust]
  3508 00008D28 880D[62DF0000]      <1> 	mov	[DestinationFile_SecPerClust], cl
  3509                              <1> 
  3510                              <1> 	; 17/03/2016
  3511 00008D2E 386F03              <1> 	cmp	[edi+LD_FATType], ch ; 0
  3512 00008D31 7707                <1> 	ja	short csftdf2_set_df_percent_wsize1
  3513                              <1> 	
  3514 00008D33 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3515 00008D38 EB06                <1> 	jmp	short csftdf2_set_df_percent_wsize2	
  3516                              <1> 
  3517                              <1> csftdf2_set_df_percent_wsize1:
  3518 00008D3A 0FB74711            <1> 	movzx	eax, word [edi+LD_BPB+BytesPerSec]
  3519 00008D3E F7E1                <1> 	mul	ecx
  3520                              <1> 	;sub	edx, edx
  3521                              <1> csftdf2_set_df_percent_wsize2:
  3522 00008D40 A3[A8DF0000]        <1> 	mov	[csftdf_w_size], eax
  3523                              <1> 
  3524 00008D45 A1[90DF0000]        <1> 	mov	eax, [csftdf_filesize]
  3525                              <1> 
  3526 00008D4A 3D00000100          <1> 	cmp	eax, 65536 ; 64KB	; small file
  3527 00008D4F 721F                <1> 	jb	short csftdf2_load_file ; do not display percentage
  3528                              <1> 	
  3529                              <1> csftdf2_reset_wf_percent_ptr_chk_64k:
  3530 00008D51 B201                <1> 	mov	dl, 1 ; 25/03/2016
  3531                              <1> 
  3532 00008D53 3D00000400          <1> 	cmp	eax, 65536*4 ; 256KB
  3533 00008D58 7310                <1> 	jnb	short csftdf2_enable_percentage_display ; big file
  3534                              <1> 
  3535                              <1> 	; 64-128KB file size for floppy disks
  3536 00008D5A 3815[64DE0000]      <1> 	cmp	byte [SourceFile_Drv], dl ; 1 ; read from floppy disk ?
  3537 00008D60 7608                <1> 	jna	short csftdf2_enable_percentage_display
  3538                              <1> 
  3539 00008D62 3815[E4DE0000]      <1> 	cmp	byte [DestinationFile_Drv], dl ; 1 ; write to floppy disk ?
  3540 00008D68 7706                <1> 	ja	short csftdf2_load_file
  3541                              <1> 
  3542                              <1> csftdf2_enable_percentage_display:	
  3543 00008D6A 8815[B4DF0000]      <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 00008D70 B40F                <1> 	mov	ah, 0Fh
  3551 00008D72 E8BA85FFFF          <1> 	call	_int10h
  3552                              <1> 	; 13/05/2016
  3553 00008D77 883D[B5DF0000]      <1> 	mov	[csftdf_videopage], bh ; active video page
  3554 00008D7D B403                <1> 	mov	ah, 03h
  3555 00008D7F E8AD85FFFF          <1> 	call	_int10h
  3556 00008D84 668915[B6DF0000]    <1> 	mov	[csftdf_cursorpos], dx
  3557                              <1> 
  3558 00008D8B 29C0                <1> 	sub	eax, eax
  3559 00008D8D A2[8DDF0000]        <1> 	mov	[csftdf_rw_err], al ; 0 
  3560                              <1> 
  3561                              <1> ; ///
  3562                              <1> csftdf_sf_amb: ; 15/03/2016
  3563 00008D92 8B0D[90DF0000]      <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 00008D98 E864ACFFFF          <1> 	call	allocate_memory_block
  3576 00008D9D 7304                <1> 	jnc	short loc_check_sf_save_loading_parms
  3577                              <1> 
  3578 00008D9F 29C0                <1> 	sub	eax, eax
  3579 00008DA1 29C9                <1> 	sub	ecx, ecx
  3580                              <1> 	
  3581                              <1> loc_check_sf_save_loading_parms:
  3582 00008DA3 A3[94DF0000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  3583 00008DA8 890D[98DF0000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  3584                              <1> ; ///   
  3585                              <1> 	; 19/03/2016
  3586 00008DAE 8B35[B8DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt] ; logical dos drv desc. tbl.
  3587                              <1> 
  3588                              <1> 	; 17/03/2016
  3589 00008DB4 09C0                <1> 	or	eax, eax ; contiguous free memory block address 
  3590 00008DB6 0F845B010000        <1>         jz      csftdf2_read_sf_cluster
  3591                              <1> 
  3592                              <1> 	; 18/03/2016
  3593 00008DBC 8B1D[94DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3594                              <1> 
  3595 00008DC2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3596 00008DC6 0F8605020000        <1>         jna     csftdf2_load_fs_file
  3597                              <1> 
  3598                              <1> csftdf2_load_fat_file:
  3599 00008DCC 53                  <1> 	push	ebx ; *
  3600                              <1> 
  3601                              <1> csftdf2_load_fat_file_next:
  3602 00008DCD BE[6FC80000]        <1> 	mov	esi, msg_reading
  3603 00008DD2 E859B2FFFF          <1> 	call	print_msg
  3604                              <1> 
  3605 00008DD7 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3606 00008DDE 7605                <1> 	jna	short csftdf2_load_fat_file_1
  3607                              <1> 	
  3608 00008DE0 E87C000000          <1> 	call	csftdf2_print_percentage ; 19/03/2016
  3609                              <1> 
  3610                              <1> csftdf2_load_fat_file_1:
  3611 00008DE5 8B35[B8DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3612 00008DEB 5B                  <1> 	pop	ebx ; *
  3613                              <1> 
  3614                              <1> csftdf2_load_fat_file_2:
  3615 00008DEC E8B8000000          <1> 	call	csftdf2_read_fat_file_sectors ; 19/03/2016
  3616 00008DF1 0F8250040000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3617                              <1> 
  3618 00008DF7 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3619 00008DF9 7520                <1> 	jnz	short csftdf2_load_fat_file_ok
  3620                              <1> 
  3621 00008DFB 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3622 00008E02 76E8                <1> 	jna	short csftdf2_load_fat_file_2
  3623                              <1> 
  3624 00008E04 53                  <1> 	push	ebx ; *	
  3625                              <1> 
  3626                              <1> 	; Set cursor position
  3627                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3628 00008E05 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3629 00008E0B 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3630 00008E12 B402                <1> 	mov	ah, 2
  3631 00008E14 E81885FFFF          <1> 	call	_int10h
  3632 00008E19 EBB2                <1> 	jmp	short csftdf2_load_fat_file_next
  3633                              <1> 	
  3634                              <1> csftdf2_load_fat_file_ok:
  3635 00008E1B 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3636 00008E22 0F8651020000        <1>         jna     csftdf2_save_file ; 25/03/2016
  3637                              <1> 	
  3638                              <1> 	; "Reading... 100%"
  3639 00008E28 BF[87C80000]        <1> 	mov	edi, percentagestr
  3640 00008E2D B031                <1> 	mov	al, '1'
  3641 00008E2F AA                  <1> 	stosb
  3642 00008E30 B030                <1> 	mov	al, '0'
  3643 00008E32 AA                  <1> 	stosb
  3644 00008E33 AA                  <1> 	stosb
  3645                              <1> 
  3646 00008E34 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3647 00008E3A 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3648 00008E41 B402                <1> 	mov	ah, 2
  3649 00008E43 E8E984FFFF          <1> 	call	_int10h
  3650                              <1> 
  3651 00008E48 BE[6FC80000]        <1> 	mov	esi, msg_reading
  3652 00008E4D E8DEB1FFFF          <1> 	call	print_msg
  3653                              <1> 	
  3654 00008E52 BE[87C80000]        <1> 	mov	esi, percentagestr
  3655 00008E57 E8D4B1FFFF          <1> 	call	print_msg
  3656                              <1> 
  3657 00008E5C 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 00008E61 B020                <1> 	mov	al, 20h
  3663 00008E63 BF[87C80000]        <1> 	mov	edi, percentagestr
  3664 00008E68 AA                  <1> 	stosb
  3665 00008E69 AA                  <1> 	stosb
  3666 00008E6A A1[ACDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3667 00008E6F BA64000000          <1> 	mov	edx, 100
  3668 00008E74 F7E2                <1> 	mul	edx
  3669 00008E76 8B0D[90DF0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3670 00008E7C F7F1                <1> 	div	ecx
  3671 00008E7E B10A                <1> 	mov	cl, 10
  3672 00008E80 F6F1                <1> 	div	cl
  3673 00008E82 80C430              <1> 	add	ah, '0'
  3674 00008E85 8827                <1> 	mov	[edi], ah
  3675 00008E87 20C0                <1> 	and	al, al
  3676 00008E89 740A                <1> 	jz	short csftdf2_print_percent_1
  3677 00008E8B 4F                  <1> 	dec	edi
  3678 00008E8C 6698                <1> 	cbw
  3679 00008E8E F6F1                <1> 	div	cl
  3680 00008E90 80C430              <1> 	add	ah, '0'
  3681 00008E93 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 00008E95 BE[87C80000]        <1> 	mov	esi, percentagestr
  3689                              <1> 	;call	print_msg
  3690                              <1> 	;retn
  3691 00008E9A E991B1FFFF          <1> 	jmp	print_msg
  3692                              <1> 
  3693                              <1> csftdf2_read_file_sectors:
  3694                              <1> 	; 19/03/2016
  3695 00008E9F 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3696 00008EA3 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 00008EA9 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3708 00008EAF 2B15[ACDF0000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  3709 00008EB5 3B15[A4DF0000]      <1> 	cmp	edx, [csftdf_r_size]	
  3710 00008EBB 7306                <1> 	jnb	short csftdf2_read_fat_file_secs_1
  3711 00008EBD 8915[A4DF0000]      <1> 	mov	[csftdf_r_size], edx
  3712                              <1> 		
  3713                              <1> csftdf2_read_fat_file_secs_1:
  3714 00008EC3 A1[A4DF0000]        <1> 	mov	eax, [csftdf_r_size]
  3715 00008EC8 29D2                <1> 	sub	edx, edx
  3716 00008ECA 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3717 00008ECE 01C8                <1> 	add	eax, ecx
  3718 00008ED0 48                  <1> 	dec	eax
  3719 00008ED1 F7F1                <1> 	div	ecx
  3720 00008ED3 89C1                <1> 	mov	ecx, eax ; sector count
  3721 00008ED5 A1[9CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3722                              <1> 
  3723                              <1> 	; EBX = memory block address (current)
  3724                              <1> 	
  3725 00008EDA E821090000          <1> 	call	read_fat_file_sectors
  3726 00008EDF 7235                <1> 	jc	short csftdf2_read_fat_file_secs_3
  3727                              <1> 
  3728                              <1> 	; EBX = next memory address
  3729                              <1> 
  3730 00008EE1 A1[ACDF0000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3731 00008EE6 0305[A4DF0000]      <1> 	add	eax, [csftdf_r_size]
  3732 00008EEC 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3733 00008EF2 39D0                <1> 	cmp	eax, edx
  3734 00008EF4 7320                <1> 	jnb	short csftdf2_read_fat_file_secs_3 ; edx > 0
  3735 00008EF6 A3[ACDF0000]        <1> 	mov	[csftdf_sf_rbytes], eax
  3736                              <1> 
  3737 00008EFB 53                  <1> 	push	ebx ; *
  3738                              <1> 	; get next cluster (csftdf_r_size! bytes)
  3739 00008EFC A1[9CDF0000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3740 00008F01 E8CC060000          <1> 	call	get_next_cluster
  3741 00008F06 5B                  <1> 	pop	ebx ; *
  3742 00008F07 7306                <1> 	jnc	short csftdf2_read_fat_file_secs_2
  3743                              <1> 
  3744 00008F09 B815000000          <1> 	mov	eax, 15h ; Read error !
  3745 00008F0E C3                  <1> 	retn
  3746                              <1> 
  3747                              <1> csftdf2_read_fat_file_secs_2:
  3748 00008F0F 29D2                <1> 	sub	edx, edx ; 0
  3749 00008F11 A3[9CDF0000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  3750                              <1> 
  3751                              <1> csftdf2_read_fat_file_secs_3:
  3752 00008F16 C3                  <1> 	retn
  3753                              <1> 
  3754                              <1> csftdf2_read_sf_cluster:
  3755                              <1> 	; 19/03/2016
  3756 00008F17 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3757                              <1> 
  3758 00008F1C 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3759 00008F23 760D                <1> 	jna	short csftdf2_read_sf_clust_2
  3760                              <1> 
  3761 00008F25 53                  <1> 	push	ebx ; *	
  3762                              <1> 
  3763                              <1> csftdf2_read_sf_clust_next:
  3764 00008F26 E836FFFFFF          <1> 	call	csftdf2_print_percentage
  3765                              <1> 
  3766                              <1> csftdf2_read_sf_clust_0:
  3767 00008F2B 8B35[B8DF0000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3768                              <1> csftdf2_read_sf_clust_1:
  3769 00008F31 5B                  <1> 	pop	ebx ; *
  3770                              <1> 
  3771                              <1> csftdf2_read_sf_clust_2:
  3772 00008F32 89DA                <1> 	mov	edx, ebx
  3773 00008F34 0315[A4DF0000]      <1> 	add	edx, [csftdf_r_size]
  3774 00008F3A 81FA00000800        <1> 	cmp	edx, Cluster_Buffer + 65536
  3775 00008F40 772F                <1> 	ja	short csftdf2_write_df_cluster
  3776                              <1> 
  3777 00008F42 E858FFFFFF          <1> 	call	csftdf2_read_file_sectors ; 19/03/2016
  3778 00008F47 0F8280020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3779                              <1> 
  3780 00008F4D 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3781 00008F4F 7520                <1> 	jnz	short csftdf2_write_df_cluster
  3782                              <1> 
  3783 00008F51 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3784 00008F58 76D8                <1> 	jna	short csftdf2_read_sf_clust_2
  3785                              <1> 
  3786 00008F5A 53                  <1> 	push	ebx ; *	
  3787                              <1> 
  3788                              <1> 	; Set cursor position
  3789                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3790 00008F5B 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3791 00008F61 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3792 00008F68 B402                <1> 	mov	ah, 2
  3793 00008F6A E8C283FFFF          <1> 	call	_int10h
  3794 00008F6F EBB5                <1> 	jmp	short csftdf2_read_sf_clust_next
  3795                              <1> 
  3796                              <1> csftdf2_write_df_cluster:
  3797                              <1> 	; 19/03/2016
  3798 00008F71 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt]	
  3799 00008F77 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3800                              <1> 
  3801                              <1> csftdf2_write_df_clust_next:
  3802 00008F7C E855000000          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016
  3803 00008F81 0F8246020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3804                              <1> 
  3805 00008F87 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3806 00008F89 750A                <1> 	jnz	short csftdf2_rw_f_clust_ok
  3807                              <1> 
  3808 00008F8B 81FB00000800        <1> 	cmp	ebx, Cluster_Buffer + 65536
  3809 00008F91 72E9                <1> 	jb	short csftdf2_write_df_clust_next
  3810                              <1> 	
  3811 00008F93 EB82                <1> 	jmp	short csftdf2_read_sf_cluster
  3812                              <1>  
  3813                              <1> csftdf2_rw_f_clust_ok:
  3814 00008F95 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3815 00008F9C 0F86B2010000        <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  3816                              <1> 
  3817                              <1> 	; "100%"
  3818 00008FA2 BF[87C80000]        <1> 	mov	edi, percentagestr
  3819 00008FA7 B031                <1> 	mov	al, '1'
  3820 00008FA9 AA                  <1> 	stosb
  3821 00008FAA B030                <1> 	mov	al, '0'
  3822 00008FAC AA                  <1> 	stosb
  3823 00008FAD AA                  <1> 	stosb
  3824                              <1> 
  3825 00008FAE 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3826 00008FB4 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3827 00008FBB B402                <1> 	mov	ah, 2
  3828 00008FBD E86F83FFFF          <1> 	call	_int10h
  3829                              <1> 
  3830 00008FC2 BE[87C80000]        <1> 	mov	esi, percentagestr
  3831 00008FC7 E864B0FFFF          <1> 	call	print_msg
  3832                              <1> 
  3833 00008FCC E983010000          <1>         jmp     csftdf2_save_fat_file_4
  3834                              <1> 
  3835                              <1> csftdf2_load_fs_file:
  3836                              <1> 	; temporary - 18/03/2016
  3837 00008FD1 E96F020000          <1>         jmp     csftdf2_read_error
  3838                              <1> 
  3839                              <1> csftdf2_write_file_sectors:
  3840                              <1> 	; 19/03/2016
  3841 00008FD6 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3842 00008FDA 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 00008FE0 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3854 00008FE6 2B15[B0DF0000]      <1> 	sub	edx, [csftdf_df_wbytes]
  3855 00008FEC 3B15[A8DF0000]      <1> 	cmp	edx, [csftdf_w_size]	
  3856 00008FF2 7306                <1> 	jnb	short csftdf2_write_fat_file_secs_1
  3857 00008FF4 8915[A8DF0000]      <1> 	mov	[csftdf_w_size], edx		
  3858                              <1> 
  3859                              <1> csftdf2_write_fat_file_secs_1:
  3860 00008FFA A1[A8DF0000]        <1> 	mov	eax, [csftdf_w_size]
  3861 00008FFF 29D2                <1> 	sub	edx, edx
  3862 00009001 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3863 00009005 01C8                <1> 	add	eax, ecx
  3864 00009007 48                  <1> 	dec	eax
  3865 00009008 F7F1                <1> 	div	ecx
  3866 0000900A 89C1                <1> 	mov	ecx, eax ; sector count
  3867 0000900C A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3868                              <1> 
  3869                              <1> 	; EBX = memory block address (current)	
  3870                              <1> 
  3871 00009011 E8920F0000          <1> 	call	write_fat_file_sectors
  3872 00009016 7259                <1> 	jc	short csftdf2_write_fat_file_secs_4
  3873                              <1> 
  3874                              <1> 	; EBX = next memory address
  3875                              <1> 
  3876 00009018 A1[B0DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3877 0000901D 0305[A8DF0000]      <1> 	add	eax, [csftdf_w_size]
  3878 00009023 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  3879 00009029 39D0                <1> 	cmp	eax, edx
  3880 0000902B 7344                <1> 	jnb	short csftdf2_write_fat_file_secs_4
  3881 0000902D A3[B0DF0000]        <1> 	mov	[csftdf_df_wbytes], eax
  3882                              <1> 	;
  3883 00009032 A3[52DF0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  3884                              <1> 
  3885 00009037 53                  <1> 	push	ebx ; *
  3886                              <1> 
  3887 00009038 803D[8EDF0000]01    <1> 	cmp	byte [DestinationFileFound], 1
  3888 0000903F 7210                <1> 	jb	short csftdf2_write_fat_file_secs_2
  3889                              <1> 
  3890                              <1> 	; get next cluster (csftdf_w_size! bytes)
  3891 00009041 A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  3892 00009046 E887050000          <1> 	call	get_next_cluster
  3893 0000904B 731C                <1> 	jnc	short csftdf2_write_fat_file_secs_3
  3894                              <1> 
  3895 0000904D 21C0                <1> 	and	eax, eax ; end of cluster chain!?
  3896 0000904F 7521                <1> 	jnz	short csftdf2_write_fat_file_secs_5 ; disk error !
  3897                              <1> 
  3898                              <1> csftdf2_write_fat_file_secs_2:
  3899 00009051 A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  3900 00009056 E8700E0000          <1> 	call	add_new_cluster		
  3901 0000905B 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 0000905D 8B15[A8DF0000]      <1> 	mov	edx, [csftdf_w_size] ; bytes per cluster
  3909 00009063 0115[52DF0000]      <1> 	add	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  3910                              <1> 
  3911                              <1> csftdf2_write_fat_file_secs_3:
  3912 00009069 5B                  <1> 	pop	ebx ; *
  3913 0000906A 29D2                <1> 	sub	edx, edx ; 0
  3914 0000906C A3[A0DF0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  3915                              <1> 
  3916                              <1> csftdf2_write_fat_file_secs_4:
  3917 00009071 C3                  <1> 	retn
  3918                              <1> 
  3919                              <1> csftdf2_write_fat_file_secs_5:
  3920 00009072 5B                  <1> 	pop	ebx ; *
  3921 00009073 B81D000000          <1> 	mov	eax, 1Dh ; Write error !
  3922 00009078 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 00009079 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; logical dos drv desc. tbl.
  3929                              <1> 
  3930 0000907F 8B1D[94DF0000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3931                              <1> 
  3932 00009085 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3933 00009089 0F86F4010000        <1>         jna     csftdf2_save_fs_file
  3934                              <1> 
  3935                              <1> csftdf2_save_fat_file:
  3936 0000908F 53                  <1> 	push	ebx; *
  3937                              <1> 
  3938 00009090 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3939 00009097 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 00009099 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  3944 0000909F 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  3945 000090A6 B402                <1> 	mov	ah, 2
  3946 000090A8 E88482FFFF          <1> 	call	_int10h
  3947                              <1> 	
  3948 000090AD BE[7BC80000]        <1> 	mov	esi, msg_writing
  3949 000090B2 E879AFFFFF          <1> 	call	print_msg
  3950                              <1> 
  3951                              <1> csftdf2_save_fat_file_next:
  3952 000090B7 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 25/03/2016
  3953                              <1> 
  3954                              <1> csftdf2_save_fat_file_0:
  3955 000090BD 5B                  <1> 	pop	ebx ; *
  3956                              <1> 
  3957                              <1> csftdf2_save_fat_file_1:
  3958 000090BE E813FFFFFF          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016	
  3959 000090C3 0F827E010000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3960                              <1> 
  3961 000090C9 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3962 000090CB 756D                <1>         jnz     short csftdf2_save_fat_file_3 ; 25/03/2016
  3963                              <1> 
  3964 000090CD 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3965 000090D4 76E8                <1> 	jna	short csftdf2_save_fat_file_1
  3966                              <1> 
  3967 000090D6 B020                <1> 	mov	al, 20h
  3968 000090D8 BF[87C80000]        <1> 	mov	edi, percentagestr
  3969 000090DD AA                  <1> 	stosb
  3970 000090DE AA                  <1> 	stosb
  3971 000090DF A1[B0DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3972 000090E4 BA64000000          <1> 	mov	edx, 100
  3973 000090E9 F7E2                <1> 	mul	edx
  3974 000090EB 8B0D[90DF0000]      <1> 	mov	ecx, [csftdf_filesize]	
  3975 000090F1 F7F1                <1> 	div	ecx
  3976 000090F3 B10A                <1> 	mov	cl, 10
  3977 000090F5 F6F1                <1> 	div	cl
  3978 000090F7 80C430              <1> 	add	ah, '0'
  3979 000090FA 8827                <1> 	mov	[edi], ah
  3980 000090FC 20C0                <1> 	and	al, al
  3981 000090FE 740A                <1> 	jz	short csftdf2_save_fat_file_2
  3982 00009100 4F                  <1> 	dec	edi
  3983 00009101 6698                <1> 	cbw
  3984 00009103 F6F1                <1> 	div	cl
  3985 00009105 80C430              <1> 	add	ah, '0'
  3986 00009108 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 0000910A 53                  <1> 	push	ebx ; *
  3994                              <1> 
  3995 0000910B E802000000          <1> 	call	csftdf2_print_wr_percentage ; 25/03/2016
  3996                              <1> 
  3997 00009110 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 00009112 8A3D[B5DF0000]      <1> 	mov	bh, [csftdf_videopage]
  4003 00009118 668B15[B6DF0000]    <1> 	mov	dx, [csftdf_cursorpos]
  4004 0000911F B402                <1> 	mov	ah, 2
  4005 00009121 E80B82FFFF          <1> 	call	_int10h
  4006                              <1> 
  4007 00009126 BE[7BC80000]        <1> 	mov	esi, msg_writing
  4008 0000912B E800AFFFFF          <1> 	call	print_msg
  4009                              <1> 
  4010 00009130 BE[87C80000]        <1> 	mov	esi, percentagestr
  4011                              <1> 	;call	print_msg
  4012                              <1> 	;retn
  4013 00009135 E9F6AEFFFF          <1> 	jmp	print_msg
  4014                              <1> 
  4015                              <1> csftdf2_save_fat_file_3:
  4016 0000913A 803D[B4DF0000]00    <1> 	cmp	byte [csftdf_percentage], 0
  4017 00009141 7611                <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  4018                              <1> 
  4019                              <1> 	; "100%"
  4020 00009143 BF[87C80000]        <1> 	mov	edi, percentagestr
  4021 00009148 B031                <1> 	mov	al, '1'
  4022 0000914A AA                  <1> 	stosb
  4023 0000914B B030                <1> 	mov	al, '0'
  4024 0000914D AA                  <1> 	stosb
  4025 0000914E AA                  <1> 	stosb
  4026                              <1> 
  4027 0000914F E8BEFFFFFF          <1> 	call	csftdf2_print_wr_percentage
  4028                              <1> 
  4029                              <1> csftdf2_save_fat_file_4:
  4030 00009154 803D[8EDF0000]00    <1> 	cmp	byte [DestinationFileFound], 0
  4031 0000915B 7647                <1> 	jna	short csftdf2_save_fat_file_6
  4032                              <1> 
  4033 0000915D 8B35[BCDF0000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 31/03/2016	
  4034                              <1> 
  4035 00009163 A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4036 00009168 E865040000          <1> 	call	get_next_cluster
  4037 0000916D 7235                <1> 	jc	short csftdf2_save_fat_file_6 ; eocc! or disk error!
  4038                              <1> 
  4039 0000916F A1[A0DF0000]        <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 00009174 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4045 00009179 E87E070000          <1> 	call	update_cluster
  4046 0000917E 7224                <1> 	jc	short csftdf2_save_fat_file_6 ; really last cluster!?
  4047                              <1> 
  4048 00009180 A3[A0DF0000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  4049                              <1> 	
  4050                              <1> 	; byte [FAT_BuffValidData] = 2 
  4051 00009185 E82F0A0000          <1> 	call	save_fat_buffer
  4052 0000918A 730E                <1> 	jnc	short csftdf2_save_fat_file_5
  4053                              <1> 	
  4054 0000918C 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  4055 00009192 8915[52DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4056 00009198 EB58                <1> 	jmp	short csftdf2_save_fat_file_err3
  4057                              <1> 
  4058                              <1> csftdf2_save_fat_file_5:
  4059 0000919A A1[A0DF0000]        <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 0000919F E8480C0000          <1> 	call	truncate_cluster_chain
  4064                              <1> 
  4065                              <1> csftdf2_save_fat_file_6:
  4066                              <1> 	; 28/03/2016
  4067 000091A4 BE[C1DE0000]        <1> 	mov	esi, SourceFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4068 000091A9 BF[41DF0000]        <1> 	mov	edi, DestinationFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4069 000091AE A4                  <1> 	movsb ; +11
  4070 000091AF A5                  <1> 	movsd ; +12 .. +15
  4071 000091B0 66A5                <1> 	movsw ; +16 .. +17
  4072                              <1> 		; + 18
  4073 000091B2 83C604              <1> 	add	esi, 4
  4074 000091B5 83C704              <1> 	add	edi, 4
  4075 000091B8 A5                  <1> 	movsd	; DirEntry_WrtTime ; +22 .. +25
  4076                              <1> 
  4077 000091B9 8B15[90DF0000]      <1> 	mov	edx, [csftdf_filesize]
  4078 000091BF 8915[52DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4079                              <1> 
  4080 000091C5 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 000091CA EB4D                <1> 	jmp	short csftdf2_save_fat_file_7
  4084                              <1> 
  4085                              <1> csftdf2_save_fat_file_err1:
  4086 000091CC 5B                  <1> 	pop	ebx ; *	
  4087                              <1> csftdf2_save_fat_file_err2:
  4088 000091CD A1[B0DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]
  4089 000091D2 8B15[52DF0000]      <1> 	mov	edx, [DestinationFile_DirEntry+DirEntry_FileSize]
  4090 000091D8 39C2                <1> 	cmp	edx, eax
  4091 000091DA 7616                <1> 	jna	short csftdf2_save_fat_file_err3
  4092 000091DC A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster] ; last (empty) cluster
  4093                              <1> 	; ESI = Logical dos drive description table address
  4094 000091E1 E8060C0000          <1> 	call	truncate_cluster_chain
  4095 000091E6 720A                <1> 	jc	short csftdf2_save_fat_file_err3
  4096 000091E8 A1[B0DF0000]        <1> 	mov	eax, [csftdf_df_wbytes]	
  4097 000091ED A3[52DF0000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  4098                              <1> csftdf2_save_fat_file_err3:
  4099 000091F2 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 000091F7 C605[43DF0000]00    <1> 	mov	byte [DestinationFile_DirEntry+DirEntry_CrtTimeTenth], 0
  4103 000091FE 66A3[44DF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtTime], ax
  4104 00009204 668915[46DF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtDate], dx		
  4105 0000920B 66A3[4CDF0000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtTime], ax
  4106 00009211 668915[4EDF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtDate], dx
  4107 00009218 F9                  <1> 	stc
  4108                              <1> csftdf2_save_fat_file_7:
  4109 00009219 9C                  <1> 	pushf
  4110 0000921A 668915[48DF0000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_LastAccDate], dx
  4111 00009221 BE[36DF0000]        <1> 	mov	esi, DestinationFile_DirEntry
  4112 00009226 BF00000800          <1> 	mov	edi, Directory_Buffer
  4113 0000922B 0FB70D[5EDF0000]    <1> 	movzx	ecx, word [DestinationFile_DirEntryNumber] ; (<2048)
  4114 00009232 66C1E105            <1> 	shl	cx, 5 ; 32 * directory entry number
  4115 00009236 01CF                <1> 	add	edi, ecx
  4116                              <1> 	;mov	ecx, 8
  4117 00009238 66B90800            <1> 	mov	cx, 8
  4118 0000923C F3A5                <1> 	rep	movsd
  4119 0000923E 9D                  <1> 	popf
  4120 0000923F 730B                <1> 	jnc	short csftdf2_write_file_OK
  4121                              <1> 	 		
  4122                              <1> csftdf2_write_error:
  4123                              <1> 	; 18/03/2016
  4124 00009241 B01D                <1> 	mov	al, 1Dh ; write error
  4125 00009243 EB02                <1> 	jmp	short csftdf2_rw_error
  4126                              <1> 
  4127                              <1> 	; 16/03/2016
  4128                              <1> csftdf2_read_error:
  4129 00009245 B015                <1> 	mov	al, 15h ; ; Drive not ready or read error!
  4130                              <1> csftdf2_rw_error:
  4131 00009247 A2[8DDF0000]        <1> 	mov	[csftdf_rw_err], al 
  4132                              <1> 
  4133                              <1> csftdf2_write_file_OK:
  4134                              <1> 	; 18/03/2016
  4135 0000924C C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  4136 00009253 E8E7F0FFFF          <1> 	call	save_directory_buffer
  4137                              <1> 
  4138                              <1>  	; Update last modification date&time of destination
  4139                              <1> 	; file's (parent) directory
  4140 00009258 E87DF1FFFF          <1> 	call	update_parent_dir_lmdt
  4141                              <1> 	;
  4142 0000925D A1[94DF0000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  4143                              <1> 
  4144 00009262 21C0                <1> 	and	eax, eax
  4145 00009264 750E                <1> 	jnz	short csftdf2_dealloc_mblock
  4146                              <1> 
  4147 00009266 88C5                <1> 	mov	ch, al ; 0 (Cluster r/w, not full loading)
  4148                              <1> csftdf2_dealloc_retn:
  4149 00009268 8A0D[8DDF0000]      <1> 	mov	cl, [csftdf_rw_err]
  4150 0000926E A1[A0DF0000]        <1> 	mov	eax, [csftdf_df_cluster]
  4151 00009273 C3                  <1> 	retn
  4152                              <1> 
  4153                              <1> csftdf2_dealloc_mblock:
  4154 00009274 8B0D[98DF0000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  4155 0000927A E883A9FFFF          <1> 	call	deallocate_memory_block
  4156 0000927F B5FF                <1>         mov     ch, 0FFh ; (File was full loaded at memory)
  4157 00009281 EBE5                <1> 	jmp	short csftdf2_dealloc_retn
  4158                              <1> 
  4159                              <1> csftdf2_save_fs_file:
  4160                              <1> 	; temporary - (21/03/2016)
  4161 00009283 B81D000000          <1> 	mov	eax, 1Dh ; write error
  4162 00009288 F9                  <1> 	stc
  4163 00009289 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 0000928A 80E107              <1> 	and	cl, 07h ; S, H, R
  4193 0000928D 880D[DCDF0000]      <1>         mov     [createfile_attrib], cl 
  4194                              <1> 
  4195 00009293 89D9                <1> 	mov	ecx, ebx
  4196 00009295 89F3                <1> 	mov	ebx, esi ; ASCIIZ File Name address
  4197 00009297 29D2                <1> 	sub	edx, edx
  4198 00009299 8A35[7ED30000]      <1>         mov     dh, [Current_Drv]
  4199 0000929F BE00010900          <1>         mov     esi, Logical_DOSDisks
  4200 000092A4 01D6                <1> 	add	esi, edx
  4201                              <1> 
  4202 000092A6 8815[E7DF0000]      <1> 	mov	[createfile_UpdatePDir], dl ; 0 ; 31/03/2016 
  4203                              <1> 
  4204                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  4205 000092AC 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  4206 000092B0 730A                <1> 	jnb	short loc_createfile_check_file_sytem
  4207 000092B2 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  4208 000092B7 66BA0000            <1> 	mov	dx, 0
  4209                              <1> 	; err retn: EDX = 0, EBX = File name offset
  4210                              <1> 	; ESI -> Dos drive description table address	
  4211 000092BB 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 000092BC 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  4220 000092C0 730A                <1> 	jnb	short loc_createfile_chk_empty_FAT_file_sign1
  4221                              <1> 
  4222 000092C2 A3[C8DF0000]        <1> 	mov	[createfile_size], eax
  4223                              <1> 	; ESI = Logical Dos Drive Description Table address
  4224                              <1> 	; EBX = ASCIIZ File Name address
  4225 000092C7 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 000092CC 41                  <1> 	inc	ecx
  4230 000092CD 7506                <1> 	jnz	short loc_createfile_chk_empty_FAT_file_sign2
  4231 000092CF 890D[C8DF0000]      <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 000092D5 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec]
  4236 000092D9 66890D[E4DF0000]    <1> 	mov	[createfile_BytesPerSec], cx
  4237                              <1> 	
  4238                              <1> 	; EBX = ASCIIZ File Name address
  4239 000092E0 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  4240 000092E4 8815[DDDF0000]      <1> 	mov	[createfile_SecPerClust], dl
  4241 000092EA 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  4242 000092ED 39D1                <1> 	cmp	ecx, edx ; byte [createfile_SecPerClust]
  4243 000092EF 7306                <1> 	jnb	short loc_create_fat_file
  4244                              <1> 	  
  4245                              <1> loc_createfile_insufficient_disk_space:
  4246 000092F1 B827000000          <1> 	mov	eax, 27h
  4247                              <1> loc_createfile_gffc_retn:
  4248 000092F6 C3                  <1> 	retn
  4249                              <1> 
  4250                              <1> loc_create_fat_file:
  4251 000092F7 891D[C0DF0000]      <1> 	mov	[createfile_Name_Offset], ebx
  4252 000092FD 890D[C4DF0000]      <1> 	mov	[createfile_FreeSectors], ecx
  4253                              <1> 
  4254                              <1> loc_createfile_gffc_1:
  4255 00009303 E821050000          <1> 	call	get_first_free_cluster
  4256 00009308 72EC                <1> 	jc	short loc_createfile_gffc_retn
  4257                              <1> 
  4258 0000930A A3[CCDF0000]        <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 0000930F 56                  <1> 	push	esi ; *
  4267 00009310 31C0                <1> 	xor	eax, eax
  4268                              <1> 
  4269 00009312 A3[9EDB0000]        <1> 	mov	dword [FAT_ClusterCounter], eax ; 0
  4270                              <1> 	; 21/03/2016
  4271 00009317 A2[E6DF0000]        <1> 	mov	byte [createfile_wfc], al ; 0 
  4272                              <1> 
  4273 0000931C 89C1                <1>  	mov	ecx, eax
  4274 0000931E 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 00009320 E8F6E7FFFF          <1> 	call	locate_current_dir_file
  4279 00009325 0F83EE000000        <1> 	jnc	loc_createfile_set_ff_dir_entry
  4280 0000932B 5E                  <1> 	pop	esi ; *
  4281                              <1> 	 ; ESI = Logical DOS Drv. Description Table Address 
  4282 0000932C 83F802              <1> 	cmp	eax, 2
  4283 0000932F 7402                <1> 	je	short loc_createfile_add_new_cluster
  4284                              <1> loc_createfile_locate_file_stc_retn:
  4285 00009331 F9                  <1> 	stc
  4286 00009332 C3                  <1> 	retn
  4287                              <1> 
  4288                              <1> loc_createfile_add_new_cluster:
  4289 00009333 803D[7DD30000]02    <1> 	cmp	byte [Current_FATType], 2
  4290                              <1> 	;cmp	byte [esi+LD_FATType], 2
  4291 0000933A 770C                <1> 	ja	short loc_createfile_add_new_cluster_check_fsc
  4292 0000933C 803D[7CD30000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  4293                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  4294 00009343 7303                <1> 	jnb	short loc_createfile_add_new_cluster_check_fsc
  4295                              <1> 	
  4296                              <1> 	;mov	eax, 12
  4297 00009345 B00C                <1> 	mov	al, 12 ; No more files 
  4298                              <1> 
  4299                              <1> loc_createfile_anc_retn:
  4300 00009347 C3                  <1> 	retn
  4301                              <1> 
  4302                              <1> loc_createfile_add_new_cluster_check_fsc:
  4303 00009348 8B0D[C4DF0000]      <1> 	mov	ecx, [createfile_FreeSectors]
  4304 0000934E 0FB605[DDDF0000]    <1> 	movzx	eax, byte [createfile_SecPerClust]
  4305 00009355 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  4306 00009358 39C1                <1> 	cmp	ecx, eax
  4307 0000935A 7295                <1>         jb	short loc_createfile_insufficient_disk_space
  4308                              <1> 
  4309                              <1> loc_createfile_add_new_subdir_cluster:
  4310 0000935C 8B15[ADDB0000]      <1> 	mov	edx, [DirBuff_Cluster]
  4311 00009362 8915[D0DF0000]      <1> 	mov	[createfile_LastDirCluster], edx	
  4312                              <1> 
  4313 00009368 A1[CCDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4314 0000936D E846040000          <1> 	call	load_FAT_sub_directory 
  4315 00009372 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 00009374 0FB705[E4DF0000]    <1> 	movzx	eax, word [createfile_BytesPerSec] ; 23/03/2016
  4320 0000937B F7E1                <1> 	mul	ecx ; ecx = directory buffer sector count
  4321 0000937D 89C1                <1> 	mov	ecx, eax
  4322 0000937F C1E902              <1> 	shr	ecx, 2 ; dword count
  4323 00009382 29C0                <1> 	sub	eax, eax ; 0
  4324 00009384 F3AB                <1> 	rep	stosd 
  4325                              <1> 	;
  4326 00009386 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4327 0000938D E8ADEFFFFF          <1> 	call	save_directory_buffer
  4328 00009392 72B3                <1> 	jc	short loc_createfile_anc_retn
  4329                              <1> 
  4330                              <1> loc_createfile_save_added_subdir_cluster:
  4331 00009394 A1[D0DF0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4332 00009399 8B0D[CCDF0000]      <1> 	mov	ecx, [createfile_FFCluster]
  4333 0000939F E858050000          <1> 	call	update_cluster
  4334 000093A4 7304                <1> 	jnc	short loc_createfile_save_fat_buffer_0
  4335 000093A6 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4336 000093A8 751A                <1> 	jnz	short loc_createfile_save_fat_buffer_stc_retn
  4337                              <1> 
  4338                              <1> loc_createfile_save_fat_buffer_0:
  4339 000093AA A1[CCDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4340 000093AF A3[D0DF0000]        <1> 	mov	[createfile_LastDirCluster], eax
  4341 000093B4 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh ; 28 bit
  4342 000093B9 E83E050000          <1> 	call	update_cluster
  4343 000093BE 7306                <1> 	jnc	short loc_createfile_save_fat_buffer_1
  4344 000093C0 09C0                <1> 	or	eax, eax ; Was it free cluster
  4345 000093C2 7402                <1> 	jz	short loc_createfile_save_fat_buffer_1
  4346                              <1> 
  4347                              <1> loc_createfile_save_fat_buffer_stc_retn:
  4348 000093C4 F9                  <1> 	stc
  4349                              <1> loc_createfile_save_fat_buffer_retn:
  4350                              <1> loc_createfile_gffc_2_stc_retn:
  4351 000093C5 C3                  <1> 	retn
  4352                              <1> 
  4353                              <1> loc_createfile_save_fat_buffer_1:
  4354                              <1> 	; byte [FAT_BuffValidData] = 2 
  4355 000093C6 E8EE070000          <1> 	call	save_fat_buffer
  4356 000093CB 72F8                <1> 	jc	short loc_createfile_save_fat_buffer_retn
  4357                              <1> 
  4358 000093CD 803D[9EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4359 000093D4 7222                <1> 	jb	short loc_createfile_save_fat_buffer_2
  4360                              <1> 
  4361                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4362 000093D6 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4363                              <1> 
  4364 000093DB C605[9EDB0000]00    <1> 	mov	byte [FAT_ClusterCounter], 0 ; 21/03/2016
  4365                              <1> 
  4366 000093E2 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4367 000093E6 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 000093EB 09C9                <1> 	or	ecx, ecx 
  4374 000093ED 7409                <1> 	jz	short loc_createfile_save_fat_buffer_2
  4375                              <1> 
  4376 000093EF 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4377 000093F3 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 000093F8 E82C040000          <1> 	call	get_first_free_cluster
  4384 000093FD 72C6                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4385                              <1> 
  4386 000093FF A3[CCDF0000]        <1> 	mov	[createfile_FFCluster], eax
  4387                              <1> 
  4388 00009404 A1[D0DF0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4389                              <1> 	
  4390 00009409 E8AA030000          <1> 	call	load_FAT_sub_directory 
  4391 0000940E 72B5                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4392                              <1> 
  4393 00009410 BF00000800          <1> 	mov	edi, Directory_Buffer
  4394                              <1> 
  4395 00009415 6629DB              <1> 	sub	bx, bx ; directory entry index/number = 0
  4396                              <1> 
  4397 00009418 56                  <1> 	push	esi ; * ; 23/03/2016
  4398                              <1> 
  4399                              <1> loc_createfile_set_ff_dir_entry:
  4400 00009419 66891D[DEDF0000]    <1> 	mov	[createfile_DirIndex], bx
  4401                              <1> 
  4402                              <1>         ; EDI = Directory entry address
  4403 00009420 8B35[C0DF0000]      <1> 	mov	esi, [createfile_Name_Offset]
  4404 00009426 A1[CCDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4405 0000942B A3[D4DF0000]        <1> 	mov	[createfile_Cluster], eax ; 24/03/2016
  4406 00009430 B5FF                <1> 	mov	ch, 0FFh
  4407 00009432 8A0D[DCDF0000]      <1>         mov	cl, [createfile_attrib] ; file attributes
  4408                              <1> 	; CH > 0 -> File size is in EBX
  4409 00009438 BB[C8DF0000]        <1> 	mov	ebx, createfile_size
  4410                              <1>   
  4411 0000943D E820EEFFFF          <1> 	call	make_directory_entry
  4412                              <1> 	
  4413 00009442 5E                  <1> 	pop	esi ; * ; ESI = Logical Dos Drv Desc. Table address
  4414                              <1> 
  4415 00009443 C605[A8DB0000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4416 0000944A E8F0EEFFFF          <1> 	call	save_directory_buffer
  4417 0000944F 7221                <1> 	jc	short loc_createfile_set_ff_dir_entry_retn
  4418                              <1> 
  4419 00009451 C605[E7DF0000]01    <1> 	mov	byte [createfile_UpdatePDir], 1 ; 31/03/2016 
  4420                              <1> 
  4421                              <1> loc_createfile_get_set_write_file_cluster:
  4422 00009458 A1[C8DF0000]        <1> 	mov	eax, [createfile_size]
  4423 0000945D 09C0                <1> 	or	eax, eax
  4424 0000945F 7570                <1> 	jnz	short loc_createfile_get_set_wfc_cont
  4425 00009461 40                  <1> 	inc	eax
  4426                              <1> 	; 23/03/2016
  4427 00009462 0FB61D[DDDF0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4428                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512
  4429 00009469 0FB70D[E4DF0000]    <1>         movzx   ecx, word [createfile_BytesPerSec] ; 512
  4430 00009470 EB7C                <1> 	jmp	loc_createfile_set_cluster_count 
  4431                              <1> 
  4432                              <1> loc_createfile_set_ff_dir_entry_retn:
  4433 00009472 C3                  <1> 	retn
  4434                              <1> 
  4435                              <1> loc_createfile_write_fcluster_to_disk:
  4436 00009473 034668              <1> 	add	eax, [esi+LD_DATABegin] ; convert to physical address
  4437 00009476 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 0000947B E89E290000          <1> 	call	disk_write
  4443 00009480 7211                <1> 	jc	short loc_createfile_dsk_wr_err
  4444                              <1> 
  4445                              <1> loc_createfile_update_fat_cluster:
  4446                              <1> 	; 21/03/2016	
  4447 00009482 803D[E6DF0000]00    <1> 	cmp	byte [createfile_wfc], 0 
  4448 00009489 7712                <1> 	ja	short loc_createfile_update_fat_cluster_n1
  4449                              <1> 
  4450 0000948B FE05[E6DF0000]      <1> 	inc	byte [createfile_wfc] ; 1
  4451 00009491 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 00009493 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  4456 00009498 E9BD000000          <1> 	jmp	loc_createfile_stc_retn
  4457                              <1> 
  4458                              <1> loc_createfile_update_fat_cluster_n1:
  4459 0000949D A1[D8DF0000]        <1> 	mov	eax, [createfile_PCluster]
  4460 000094A2 8B0D[D4DF0000]      <1> 	mov	ecx, [createfile_Cluster]
  4461 000094A8 E84F040000          <1> 	call	update_cluster
  4462 000094AD 7308                <1> 	jnc	short loc_createfile_update_fat_cluster_n2
  4463 000094AF 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4464 000094B1 0F85A3000000        <1> 	jnz	loc_createfile_stc_retn
  4465                              <1> 
  4466                              <1> loc_createfile_update_fat_cluster_n2:
  4467 000094B7 A1[D4DF0000]        <1>         mov	eax, [createfile_Cluster]
  4468 000094BC B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4469 000094C1 E836040000          <1> 	call	update_cluster
  4470 000094C6 734E                <1> 	jnc	short loc_createfile_save_fat_buffer_3
  4471 000094C8 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4472 000094CA 744A                <1> 	jz	short loc_createfile_save_fat_buffer_3
  4473                              <1> 
  4474                              <1> loc_createfile_upd_fat_fcluster_stc_retn:
  4475 000094CC 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 000094D1 0FB70D[E4DF0000]    <1> 	movzx	ecx, word [createfile_BytesPerSec] ; 512
  4480 000094D8 01C8                <1> 	add	eax, ecx
  4481 000094DA 48                  <1> 	dec	eax  ; add eax, 511
  4482 000094DB 29D2                <1> 	sub	edx, edx
  4483 000094DD F7F1                <1> 	div	ecx
  4484 000094DF 0FB61D[DDDF0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4485 000094E6 01D8                <1> 	add	eax, ebx
  4486 000094E8 48                  <1> 	dec	eax  ; add eax, SecPerClust - 1
  4487 000094E9 6631D2              <1> 	xor	dx, dx
  4488 000094EC F7F3                <1> 	div	ebx
  4489                              <1> 
  4490                              <1> loc_createfile_set_cluster_count:
  4491 000094EE A3[E0DF0000]        <1> 	mov 	[createfile_CCount], eax
  4492                              <1> 	
  4493 000094F3 BF00000700          <1> 	mov	edi, Cluster_Buffer
  4494 000094F8 89C8                <1> 	mov	eax, ecx ; Bytes per Sector
  4495 000094FA F7E3                <1> 	mul	ebx ; Sectors per Cluster 
  4496                              <1> 	; EAX = Bytes per Cluster
  4497 000094FC 89C1                <1> 	mov	ecx, eax
  4498 000094FE C1E902              <1> 	shr	ecx, 2 ; dword count
  4499 00009501 31C0                <1> 	xor	eax, eax
  4500 00009503 F3AB                <1> 	rep	stosd ; clear cluster buffer
  4501                              <1> 
  4502 00009505 A1[D4DF0000]        <1> 	mov	eax, [createfile_Cluster] ; 24/03/2016
  4503                              <1> 
  4504 0000950A 89D9                <1> 	mov	ecx, ebx
  4505                              <1> 
  4506                              <1> loc_createfile_get_set_wf_fclust_cont:
  4507 0000950C 83E802              <1> 	sub	eax, 2
  4508 0000950F F7E1                <1> 	mul	ecx
  4509                              <1> 	; EAX = Logical DOS disk address (offset)
  4510 00009511 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 00009516 E89E060000          <1> 	call	save_fat_buffer
  4515 0000951B 723D                <1> 	jc	loc_createfile_stc_retn
  4516                              <1> 
  4517                              <1> 	; 21/03/2016
  4518 0000951D 803D[9EDB0000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4519 00009524 721B                <1> 	jb	short loc_createfile_save_fat_buffer_4
  4520                              <1> 
  4521                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4522 00009526 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4523 0000952B 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4524 0000952F 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 00009534 09C9                <1> 	or	ecx, ecx 
  4531 00009536 7409                <1> 	jz	short loc_createfile_save_fat_buffer_4
  4532                              <1> 
  4533 00009538 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4534 0000953C E80D070000          <1> 	call	calculate_fat_freespace
  4535                              <1> 
  4536                              <1> loc_createfile_save_fat_buffer_4:
  4537 00009541 FF0D[E0DF0000]      <1> 	dec	dword [createfile_CCount]
  4538                              <1> 	;jz	short loc_createfile_upd_dir_modif_date_time
  4539 00009547 743F                <1> 	jz	short loc_createfile_stc_retn_cc ; 31/03/2016
  4540                              <1> 
  4541                              <1> loc_createfile_get_set_write_next_cluster:
  4542 00009549 E8DB020000          <1> 	call	get_first_free_cluster
  4543 0000954E 720A                <1> 	jc	short loc_createfile_stc_retn
  4544                              <1> 
  4545                              <1> loc_createfile_get_set_write_next_cluster_1:
  4546 00009550 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  4547 00009553 7213                <1> 	jb	short loc_createfile_get_set_write_next_cluster_2
  4548                              <1> 
  4549                              <1> loc_createfile_wnc_insufficient_disk_space:	
  4550 00009555 B827000000          <1> 	mov	eax, 27h ; Insufficient disk space
  4551                              <1> 
  4552                              <1> loc_createfile_stc_retn:
  4553 0000955A 803D[E6DF0000]01    <1> 	cmp	byte [createfile_wfc], 1
  4554 00009561 7324                <1> 	jnb	short loc_createfile_err_retn
  4555 00009563 C3                  <1> 	retn
  4556                              <1> 
  4557                              <1> loc_createfile_wnc_inv_format_retn:
  4558                              <1> 	;mov	eax, 0Bh
  4559 00009564 B00B                <1> 	mov	al, 0Bh ; Invalid format
  4560 00009566 EBF2                <1> 	jmp	short loc_createfile_stc_retn
  4561                              <1> 	         
  4562                              <1> loc_createfile_get_set_write_next_cluster_2:
  4563 00009568 83F802              <1> 	cmp	eax, 2
  4564 0000956B 72F7                <1> 	jb	short loc_createfile_wnc_inv_format_retn
  4565                              <1> 
  4566                              <1> loc_createfile_get_set_write_next_cluster_3:
  4567 0000956D 8B0D[D4DF0000]      <1> 	mov	ecx, [createfile_Cluster]
  4568 00009573 A3[D4DF0000]        <1> 	mov	[createfile_Cluster], eax
  4569 00009578 890D[D8DF0000]      <1> 	mov	[createfile_PCluster], ecx
  4570 0000957E 0FB60D[DDDF0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust]
  4571 00009585 EB85                <1> 	jmp	short loc_createfile_get_set_wf_fclust_cont
  4572                              <1> 
  4573                              <1> loc_createfile_err_retn:
  4574 00009587 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 00009588 9C                  <1> 	pushf	; cpu is here for an error return or completion 
  4579 00009589 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 0000958A A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4585 0000958F 09C0                <1> 	or	eax, eax
  4586 00009591 741A                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4587 00009593 8A3D[7ED30000]      <1> 	mov	bh, [Current_Drv]
  4588 00009599 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 0000959B 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 000095A0 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  4595 000095A2 7409                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4596                              <1> 
  4597                              <1> loc_createfile_stc_retn_recalc_FAT_freespace:
  4598 000095A4 66BB00FF            <1> 	mov	bx, 0FF00h ; bh = 0FFh -> 
  4599                              <1> 	; ESI = Logical DOS Drv DT Addr
  4600                              <1> 	; BL = 0 -> Recalculate 
  4601 000095A8 E8A1060000          <1> 	call	calculate_fat_freespace
  4602                              <1> 
  4603                              <1> loc_createfile_stc_retn_pop_eax:
  4604 000095AD 58                  <1> 	pop	eax
  4605 000095AE 9D                  <1> 	popf
  4606 000095AF 7218                <1> 	jc	short loc_createfile_retn
  4607                              <1> 
  4608                              <1> loc_createfile_retn_fcluster:
  4609 000095B1 A1[CCDF0000]        <1> 	mov	eax, [createfile_FFCluster]
  4610 000095B6 BB[C8DF0000]        <1> 	mov	ebx, createfile_size
  4611                              <1> 	;movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  4612 000095BB 0FB60D[DDDF0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust] ; 23/03/2016
  4613 000095C2 0FB715[DEDF0000]    <1> 	movzx	edx, word [createfile_DirIndex]
  4614                              <1> 
  4615                              <1> loc_createfile_retn:
  4616 000095C9 C3                  <1> 	retn
  4617                              <1> 
  4618                              <1> create_fs_file:
  4619                              <1> 	; temporary (21/03/2016)
  4620 000095CA C3                  <1> 	retn
  4621                              <1> 
  4622                              <1> delete_fs_file:
  4623                              <1> 	; temporary (28/02/2016)
  4624 000095CB C3                  <1> 	retn
  4625                              <1> 
  4626                              <1> rename_fs_file_or_directory:
  4627 000095CC C3                  <1> 	retn
  4628                              <1> 
  4629                              <1> make_fs_directory:
  4630                              <1> 	; temporary (21/02/2016)
  4631 000095CD C3                  <1> 	retn
  4632                              <1> 
  4633                              <1> add_new_fs_section:
  4634                              <1> 	; temporary (11/03/2016)
  4635 000095CE C3                  <1> 	retn
  4636                              <1> 
  4637                              <1> delete_fs_directory_entry:
  4638                              <1> 	; temporary (11/03/2016)
  4639 000095CF C3                  <1> 	retn
  4640                              <1> 
  4641                              <1> csftdf2_read_fs_file_sectors:
  4642                              <1> 	; temporary (19/03/2016)
  4643 000095D0 C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> csftdf2_write_fs_file_sectors:
  4646                              <1> 	; temporary (19/03/2016)
  4647 000095D1 C3                  <1> 	retn
  1907                                  %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 000095D2 A3[92DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
    34                              <1> check_next_cluster_fat_type:
    35 000095D7 29D2                <1> 	sub	edx, edx ; 0
    36 000095D9 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    37 000095DD 7250                <1> 	jb	short get_FAT12_next_cluster
    38 000095DF 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    39                              <1> get_FAT16_next_cluster:
    40 000095E5 BB00030000          <1> 	mov	ebx, 300h ;768
    41 000095EA F7F3                <1> 	div	ebx
    42                              <1> 	; EAX = Count of 3 FAT sectors
    43                              <1> 	; EDX = Cluster Offset (< 768)
    44 000095EC 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    45 000095EF 89D3                <1> 	mov	ebx, edx ; Byte Offset
    46 000095F1 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    47 000095F7 66BA0300            <1> 	mov	dx, 3
    48 000095FB F7E2                <1> 	mul	edx  
    49                              <1> 	; EAX = FAT Sector (<= 256)
    50                              <1> 	; EDX = 0
    51 000095FD 8A0E                <1> 	mov	cl, [esi+LD_Name]
    52 000095FF 803D[96DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    53 00009606 0F86CC000000        <1>         jna     load_FAT_sectors0
    54 0000960C 3A0D[97DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    55 00009612 0F85C0000000        <1>         jne     load_FAT_sectors0
    56 00009618 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
    57 0000961E 0F85BA000000        <1>         jne     load_FAT_sectors1
    58                              <1> 	;movzx	eax, word [ebx]
    59 00009624 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 00009627 6683F8F7            <1> 	cmp	ax, 0FFF7h
    69 0000962B 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    70                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    71 0000962D EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    72                              <1> 
    73                              <1> get_FAT12_next_cluster:
    74 0000962F BB00040000          <1> 	mov	ebx, 400h ;1024
    75 00009634 F7F3                <1> 	div	ebx
    76                              <1> 	; EAX = Count of 3 FAT sectors
    77                              <1> 	; EDX = Cluster Offset (< 1024)
    78 00009636 6650                <1> 	push	ax
    79 00009638 66B80300            <1> 	mov	ax, 3	
    80 0000963C 66F7E2              <1> 	mul	dx    	; Multiply by 3
    81 0000963F 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    82 00009642 6689C3              <1>         mov	bx, ax 	; Byte Offset
    83 00009645 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    84 0000964B 6658                <1> 	pop	ax
    85 0000964D 66BA0300            <1> 	mov	dx, 3
    86 00009651 F7E2                <1> 	mul	edx 
    87                              <1> 	; EAX = FAT Sector (<= 12)
    88                              <1> 	; EDX = 0
    89 00009653 8A0E                <1> 	mov	cl, [esi+LD_Name]
    90 00009655 803D[96DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    91 0000965C 767A                <1> 	jna	short load_FAT_sectors0
    92 0000965E 3A0D[97DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    93 00009664 7572                <1> 	jne	short load_FAT_sectors0
    94 00009666 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
    95 0000966C 7570                <1> 	jne	short load_FAT_sectors1
    96 0000966E A1[92DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
    97 00009673 66D1E8              <1> 	shr	ax, 1
    98                              <1> 	;movzx	eax, word [ebx]
    99 00009676 668B03              <1> 	mov	ax, [ebx]
   100 00009679 7314                <1> 	jnc	short get_FAT12_nc_even
   101 0000967B 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 0000967F 663DF70F            <1> 	cmp	ax, 0FF7h
   108 00009683 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 00009685 31C0                <1> 	xor	eax, eax ; 0
   113                              <1> loc_pass_gnc_FAT16_eoc_check:
   114                              <1> loc_pass_gnc_FAT32_eoc_check:
   115 00009687 8B0D[92DB0000]      <1> 	mov	ecx, [FAT_CurrentCluster]
   116 0000968D F5                  <1> 	cmc
   117 0000968E C3                  <1> 	retn
   118                              <1> 
   119                              <1> get_FAT12_nc_even:
   120 0000968F 80E40F              <1> 	and	ah, 0Fh
   121 00009692 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   122                              <1> 
   123                              <1> get_FAT32_next_cluster:
   124 00009694 BB80010000          <1> 	mov	ebx, 180h ;384
   125 00009699 F7F3                <1> 	div	ebx
   126                              <1> 	; EAX = Count of 3 FAT sectors
   127                              <1> 	; EDX = Cluster Offset (< 384)
   128 0000969B 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   129 0000969F 89D3                <1> 	mov	ebx, edx ; Byte Offset
   130 000096A1 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   131 000096A7 66BA0300            <1> 	mov	dx, 3
   132 000096AB 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 000096AD 8A0E                <1> 	mov	cl, [esi+LD_Name]
   138 000096AF 803D[96DB0000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   139 000096B6 7620                <1> 	jna	short load_FAT_sectors0
   140 000096B8 3A0D[97DB0000]      <1> 	cmp	cl, [FAT_BuffDrvName]
   141 000096BE 7518                <1> 	jne	short load_FAT_sectors0
   142 000096C0 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   143 000096C6 7516                <1> 	jne	short load_FAT_sectors1
   144 000096C8 8B03                <1> 	mov	eax, [ebx]
   145 000096CA 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   146 000096CF 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   147 000096D4 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   148                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   149 000096D6 EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   150                              <1> 
   151                              <1> load_FAT_sectors0:
   152 000096D8 880D[97DB0000]      <1> 	mov	[FAT_BuffDrvName], cl
   153                              <1> load_FAT_sectors1:
   154 000096DE A3[9ADB0000]        <1> 	mov	[FAT_BuffSector], eax
   155 000096E3 89C3                <1> 	mov	ebx, eax
   156 000096E5 034660              <1>         add     eax, [esi+LD_FATBegin]
   157 000096E8 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   158 000096EC 7706                <1>         ja      short load_FAT_sectors3
   159 000096EE 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   160 000096F2 EB03                <1> 	jmp	short load_FAT_sectors4
   161                              <1> load_FAT_sectors3:
   162 000096F4 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   163                              <1> load_FAT_sectors4:
   164 000096F7 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   165 000096F9 83F903              <1>         cmp     ecx, 3
   166 000096FC 7605                <1>         jna     short load_FAT_sectors5
   167 000096FE B903000000          <1> 	mov	ecx, 3
   168                              <1> load_FAT_sectors5:
   169 00009703 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   170 00009708 E820270000          <1> 	call	disk_read
   171 0000970D 730D                <1> 	jnc	short load_FAT_sectors_ok
   172                              <1> 	; 23/03/2016
   173 0000970F B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   174 00009714 C605[96DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   175 0000971B C3                  <1> 	retn
   176                              <1> load_FAT_sectors_ok:
   177 0000971C C605[96DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
   178 00009723 A1[92DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
   179 00009728 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 0000972D 8A1E                <1> 	mov	bl, [esi+LD_Name]
   204 0000972F 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   205                              <1> 
   206                              <1> 	;mov	[DirBuff_DRV], bl
   207                              <1> 	;mov	[DirBuff_FATType], bh
   208 00009732 66891D[A6DB0000]    <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 00009739 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 0000973D 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   219 00009742 7414                <1> 	je	short lrd_mov_ecx_32
   220 00009744 89D0                <1> 	mov	eax, edx
   221 00009746 6683C00F            <1> 	add	ax, 15 ; round up 
   222 0000974A 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
   223 0000974E 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
   224 00009750 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
   225 00009754 664A                <1> 	dec	dx    ; Last entry number of root dir
   226                              <1> 	; cx = Dir Buffer sector count             
   227 00009756 EB0B                <1> 	jmp	short lrd_check_dir_buffer
   228                              <1> 
   229                              <1> lrd_mov_ecx_32:
   230 00009758 B920000000          <1> 	mov	ecx, 32
   231 0000975D 664A                <1> 	dec	dx ; 511
   232 0000975F 66B80040            <1> 	mov	ax, 32*512 
   233                              <1>  
   234                              <1> lrd_check_dir_buffer:
   235 00009763 29DB                <1> 	sub	ebx, ebx ; 0
   236 00009765 881D[A8DB0000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   237 0000976B 668915[ABDB0000]    <1> 	mov	[DirBuff_LastEntry], dx
   238 00009772 891D[ADDB0000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   239 00009778 66A3[B1DB0000]      <1> 	mov	[DirBuffer_Size], ax
   240                              <1> 
   241 0000977E 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   242                              <1> read_directory:
   243 00009781 BB00000800          <1> 	mov	ebx, Directory_Buffer
   244 00009786 51                  <1> 	push	ecx ; Directory buffer sector count
   245 00009787 53                  <1> 	push	ebx
   246 00009788 E8A0260000          <1> 	call	disk_read
   247 0000978D 5B                  <1> 	pop	ebx
   248 0000978E 720B                <1> 	jc	short load_DirBuff_error
   249                              <1> 
   250                              <1> validate_DirBuff_and_return:
   251 00009790 59                  <1> 	pop	ecx ; Number of loaded sectors
   252 00009791 C605[A8DB0000]01    <1> 	mov	byte [DirBuff_ValidData], 1
   253 00009798 31C0                <1> 	xor	eax, eax ; 0 = no error
   254 0000979A C3                  <1> 	retn
   255                              <1> 
   256                              <1> load_DirBuff_error:
   257 0000979B 89C8                <1> 	mov	eax, ecx ; remaining sectors
   258 0000979D 59                  <1> 	pop	ecx ; sector count
   259 0000979E 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   260 000097A0 B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
   261 000097A5 F9                  <1> 	stc
   262 000097A6 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 000097A7 8A1E                <1> 	mov	bl, [esi+LD_Name]
   281 000097A9 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   282                              <1> 
   283                              <1> 	;mov	[DirBuff_DRV], bl
   284                              <1> 	;mov	[DirBuff_FATType], bh
   285 000097AC 66891D[A6DB0000]    <1> 	mov	[DirBuff_DRV], bx
   286                              <1> 
   287                              <1> load_FAT32_root_dir0:
   288 000097B3 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   289 000097B6 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 000097B8 8A1E                <1> 	mov	bl, [esi+LD_Name]
   311 000097BA 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   312                              <1> 
   313                              <1> 	;mov	[DirBuff_DRV], bl
   314                              <1> 	;mov	[DirBuff_FATType], bh
   315 000097BD 66891D[A6DB0000]    <1> 	mov	[DirBuff_DRV], bx
   316                              <1> 
   317                              <1> load_FAT_sub_dir0:
   318 000097C4 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   319                              <1> 
   320 000097C8 882D[A8DB0000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   321 000097CE A3[ADDB0000]        <1> 	mov	[DirBuff_Cluster], eax
   322                              <1> 
   323 000097D3 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   324 000097D7 F7E1                <1> 	mul	ecx
   325 000097D9 C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   326 000097DC 6648                <1> 	dec	ax ; last entry
   327 000097DE 66A3[ABDB0000]      <1> 	mov	[DirBuff_LastEntry], ax
   328                              <1> 
   329 000097E4 A1[ADDB0000]        <1> 	mov	eax, [DirBuff_Cluster]
   330 000097E9 83E802              <1> 	sub	eax, 2
   331 000097EC F7E1                <1> 	mul	ecx
   332 000097EE 034668              <1> 	add	eax, [esi+LD_DATABegin]
   333                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   334 000097F1 EB8E                <1> 	jmp	short read_directory
   335                              <1> 
   336                              <1> ; DRV_FS.ASM
   337                              <1> 
   338                              <1> load_current_FS_directory:
   339 000097F3 C3                  <1> 	retn
   340                              <1> load_FS_root_directory:
   341 000097F4 C3                  <1> 	retn
   342                              <1> load_FS_sub_directory:
   343 000097F5 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 000097F6 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 000097FA 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   369 000097FE 761C                <1> 	jna	short read_fs_cluster
   370                              <1> 
   371                              <1> read_fat_file_sectors: ; 18/03/2016
   372 00009800 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   373 00009803 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
   374 00009807 F7E2                <1> 	mul	edx
   375 00009809 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 0000980C E81C260000          <1> 	call	disk_read
   384 00009811 7306                <1> 	jnc	short rclust_retn
   385                              <1> 	
   386 00009813 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
   387 00009818 C3                  <1> 	retn
   388                              <1> 
   389                              <1> rclust_retn:
   390 00009819 29C0                <1> 	sub	eax, eax ; 0
   391 0000981B 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 0000981C B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   406 00009821 E801000000          <1> 	call	read_fs_sectors
   407 00009826 C3                  <1> 	retn
   408                              <1> 
   409                              <1> read_fs_sectors:
   410                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   411 00009827 F9                  <1> 	stc
   412 00009828 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 00009829 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   430 0000982C 40                  <1> 	inc	eax ; add eax, 1
   431 0000982D A3[30DE0000]        <1> 	mov	[gffc_last_free_cluster], eax
   432                              <1> 
   433 00009832 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   434                              <1> 
   435 00009834 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   436 00009838 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 0000983A E834060000          <1> 	call	get_fat32_fsinfo_sector_parms
   441 0000983F 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 00009841 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   453 00009843 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   454 00009846 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 00009848 B802000000          <1> 	mov	eax, 2
   459                              <1> 	;xor	edx, edx
   460                              <1> 
   461                              <1> loc_gffc_get_first_fat_free_cluster1:
   462 0000984D 53                  <1> 	push	ebx ; 02/03/2016 
   463                              <1> 
   464                              <1> loc_gffc_get_first_fat_free_cluster2:   
   465 0000984E A3[2CDE0000]        <1> 	mov	[gffc_first_free_cluster], eax
   466 00009853 A3[28DE0000]        <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 00009858 E875FDFFFF          <1> 	call	get_next_cluster
   474 0000985D 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   475 0000985F 09C0                <1> 	or	eax, eax
   476 00009861 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   477 00009863 5B                  <1> 	pop	ebx ; 02/03/2016
   478 00009864 F5                  <1> 	cmc 	; stc
   479 00009865 C3                  <1> 	retn
   480                              <1> 
   481                              <1> loc_gffc_get_first_fat_free_cluster4:
   482 00009866 21C0                <1> 	and	eax, eax ; next cluster value
   483 00009868 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   484 0000986A 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   485 0000986C EB22                <1> 	jmp	short loc_gffc_check_for_set
   486                              <1>  
   487                              <1> loc_gffc_first_free_fat_cluster_next:
   488 0000986E A1[28DE0000]        <1> 	mov	eax, [gffc_next_free_cluster]
   489 00009873 3B05[30DE0000]      <1> 	cmp	eax, [gffc_last_free_cluster]
   490 00009879 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   491                              <1> pass_gffc_last_cluster_eax_check:
   492 0000987B 40                  <1> 	inc	eax ; add eax, 1
   493 0000987C A3[28DE0000]        <1> 	mov	[gffc_next_free_cluster], eax
   494 00009881 EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   495                              <1> 
   496                              <1> retn_stc_from_get_first_free_cluster:
   497 00009883 A1[2CDE0000]        <1> 	mov	eax, [gffc_first_free_cluster]
   498 00009888 83F802              <1> 	cmp	eax, 2
   499 0000988B 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   500 0000988D 29C0                <1> 	sub	eax, eax
   501 0000988F 48                  <1> 	dec	eax ; FFFFFFFFh
   502                              <1> 
   503                              <1> loc_gffc_check_for_set:
   504                              <1> 	; 02/03/2016
   505 00009890 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 00009891 09DB                <1> 	or	ebx, ebx
   512 00009893 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 00009895 C3                  <1> 	retn
   521                              <1> 
   522                              <1> loc_gffc_check_previous_clusters:
   523 00009896 48                  <1> 	dec	eax ; sub eax, 1
   524 00009897 A3[30DE0000]        <1> 	mov	[gffc_last_free_cluster], eax 
   525 0000989C B802000000          <1> 	mov	eax, 2
   526                              <1> 	;xor	edx, edx
   527 000098A1 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 000098A3 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 000098A6 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   565 000098AC 7540                <1> 	jne	short loc_sffc_read_fsinfo_sector
   566 000098AE 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   566 000098B7 61                  <1>
   567 000098B8 7534                <1> 	jne	short loc_sffc_read_fsinfo_sector
   568                              <1> 
   569 000098BA 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   570 000098C0 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 000098C2 8983EC010000        <1> 	mov	[ebx+492], eax
   576 000098C8 A1[40DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   577 000098CD B901000000          <1> 	mov	ecx, 1
   578 000098D2 53                  <1> 	push	ebx
   579 000098D3 E846250000          <1> 	call	disk_write
   580 000098D8 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   581 000098DA 5B                  <1> 	pop	ebx
   582                              <1> 
   583 000098DB 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   584                              <1> 
   585                              <1> loc_sffc_retn:
   586 000098E1 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 000098E2 BB00000000          <1> 	mov	ebx, 0
   594                              <1> 	; 23/03/2016
   595 000098E7 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
   596                              <1> 
   597                              <1> loc_sffc_read_fsinfo_sector_err2:
   598 000098EC 5A                  <1> 	pop	edx
   599 000098ED C3                  <1> 	retn
   600                              <1> 	
   601                              <1> loc_sffc_read_fsinfo_sector:
   602 000098EE 50                  <1> 	push	eax
   603                              <1> 
   604 000098EF E87F050000          <1> 	call	get_fat32_fsinfo_sector_parms
   605 000098F4 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   606                              <1> 
   607 000098F6 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 000098F7 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   612 000098F9 75C7                <1> 	jne	short loc_sffc_write_fsinfo_sector
   613                              <1> 
   614 000098FB 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 000098FC A3[92DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   648 00009901 890D[34DE0000]      <1> 	mov	[ClusterValue], ecx
   649                              <1> 
   650                              <1> loc_update_cluster_check_fat_buffer:
   651 00009907 8A1E                <1> 	mov	bl, [esi+LD_Name]
   652 00009909 381D[97DB0000]      <1> 	cmp	[FAT_BuffDrvName], bl
   653 0000990F 741A                <1> 	je	short loc_update_cluster_check_fat_type
   654 00009911 803D[96DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   655 00009918 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   656                              <1> 
   657                              <1> loc_uc_reset_fat_buffer_validation:
   658 0000991E C605[96DB0000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   659                              <1> 
   660                              <1> loc_uc_check_fat_type_reset_drvname:
   661 00009925 881D[97DB0000]      <1> 	mov	[FAT_BuffDrvName], bl
   662                              <1> 
   663                              <1> loc_update_cluster_check_fat_type:
   664 0000992B 29D2                <1> 	sub	edx, edx ; 26/02/2016
   665 0000992D 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   666 00009930 83F802              <1> 	cmp	eax, 2
   667 00009933 0F82BE000000        <1>         jb      update_cluster_inv_data
   668 00009939 80FB02              <1> 	cmp	bl, 2 
   669 0000993C 0F877A010000        <1>         ja      update_fat32_cluster
   670                              <1> 	;cmp	bl, 1
   671                              <1> 	;jb	short update_cluster_inv_data
   672 00009942 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   673 00009945 41                  <1> 	inc	ecx  
   674 00009946 890D[A2DB0000]      <1> 	mov	[LastCluster], ecx
   675 0000994C 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   676 0000994E 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 00009954 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   685 00009957 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 0000995D BB00030000          <1> 	mov	ebx, 300h ;768
   691 00009962 F7F3                <1> 	div	ebx
   692                              <1> 	; EAX = Count of 3 FAT sectors
   693                              <1> 	; DX = Cluster offset in FAT buffer
   694 00009964 6689D3              <1> 	mov	bx, dx  
   695 00009967 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   696 0000996A 66BA0300            <1> 	mov	dx, 3
   697 0000996E F7E2                <1> 	mul	edx  
   698                              <1> 	; EAX = FAT Sector
   699                              <1> 	; EDX = 0
   700                              <1> 	; EBX = Byte offset in FAT buffer
   701 00009970 8A0D[96DB0000]      <1> 	mov	cl, [FAT_BuffValidData]
   702 00009976 80F902              <1> 	cmp	cl, 2
   703 00009979 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   704                              <1> 
   705                              <1> loc_uc_check_fat16_buff_sector_save:
   706 0000997B 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   707 00009981 755D                <1> 	jne	short loc_uc_save_fat_buffer
   708 00009983 EB15                <1> 	jmp	short loc_update_fat16_cell
   709                              <1> 
   710                              <1> loc_uc_check_fat16_buff_sector_load:
   711 00009985 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   712 00009988 0F85FB010000        <1>         jne     loc_uc_load_fat_sectors
   713 0000998E 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   714 00009994 0F85EF010000        <1>         jne     loc_uc_load_fat_sectors
   715                              <1> 
   716                              <1> loc_update_fat16_cell:
   717                              <1> loc_update_fat16_buffer:
   718 0000999A 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   719                              <1> 	;movzx	eax, word [ebx]
   720 000099A0 668B03              <1> 	mov	ax, [ebx]
   721                              <1> 	; 01/03/2016
   722 000099A3 89C2                <1> 	mov	edx, eax ; old value of the cluster
   723 000099A5 A3[92DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   724 000099AA 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   725 000099B0 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   726                              <1> 
   727 000099B3 C605[96DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   728                              <1> 	
   729 000099BA 6683F802            <1> 	cmp	ax, 2
   730 000099BE 723A                <1> 	jb	short return_uc_fat_stc
   731 000099C0 3B05[A2DB0000]      <1> 	cmp	eax, [LastCluster]
   732 000099C6 7732                <1> 	ja	short return_uc_fat_stc
   733                              <1> 
   734                              <1> loc_fat_buffer_updated:
   735                              <1> 	; 01/03/2016
   736 000099C8 F8                  <1> 	clc
   737                              <1> loc_fat_buffer_stc_1:
   738 000099C9 9C                  <1> 	pushf
   739 000099CA 21C9                <1> 	and	ecx, ecx
   740 000099CC 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 000099CE FF05[9EDB0000]      <1> 	inc	dword [FAT_ClusterCounter]
   746                              <1> 
   747                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   748 000099D4 09D2                <1> 	or	edx, edx ; 02/03/2016
   749 000099D6 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 000099D8 FF0D[9EDB0000]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   753                              <1> 
   754                              <1> loc_fat_buffer_updated_2:
   755 000099DE 9D                  <1> 	popf
   756 000099DF C3                  <1> 	retn
   757                              <1> 
   758                              <1> loc_uc_save_fat_buffer:
   759                              <1> 	; byte [FAT_BuffValidData] = 2 
   760 000099E0 E8D4010000          <1> 	call	save_fat_buffer
   761 000099E5 0F8297010000        <1>         jc      loc_fat_sectors_rw_error2
   762                              <1> 	;mov	byte [FAT_BuffValidData], 1
   763 000099EB A1[92DB0000]        <1> 	mov	eax, [FAT_CurrentCluster]
   764                              <1> 	;mov	ecx, [ClusterValue]
   765                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   766 000099F0 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   767 000099F2 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   768                              <1> 
   769                              <1> update_cluster_inv_data:
   770                              <1> 	;mov	eax, 0Dh
   771 000099F7 B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   772 000099F9 C3                  <1> 	retn 
   773                              <1> 
   774                              <1> return_uc_fat_stc:
   775                              <1> 	; 01/03/2016
   776 000099FA 31C0                <1> 	xor	eax, eax
   777 000099FC F9                  <1> 	stc
   778 000099FD 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 000099FF BB00040000          <1> 	mov	ebx, 400h ;1024
   784 00009A04 F7F3                <1> 	div	ebx
   785                              <1> 	; EAX = Count of 3 FAT sectors
   786                              <1> 	; DX = Cluster offset in FAT buffer
   787 00009A06 66B90300            <1> 	mov	cx, 3
   788 00009A0A 6689C3              <1> 	mov	bx, ax
   789 00009A0D 6689C8              <1> 	mov	ax, cx ; 3
   790 00009A10 66F7E2              <1> 	mul	dx     ; Multiply by 3
   791 00009A13 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   792 00009A16 6693                <1> 	xchg	bx, ax
   793                              <1> 	; EAX = Count of 3 FAT sectors
   794                              <1> 	; EBX = Byte Offset in FAT buffer   
   795 00009A18 66F7E1              <1> 	mul	cx  ; 3 * AX
   796                              <1> 	; EAX = FAT Beginning Sector
   797                              <1> 	; EDX = 0
   798 00009A1B 8A0D[96DB0000]      <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 00009A21 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   803 00009A24 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   804                              <1> 
   805                              <1> loc_uc_check_fat12_buff_sector_save:
   806 00009A26 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   807 00009A2C 75B2                <1>         jne     short loc_uc_save_fat_buffer
   808 00009A2E EB15                <1> 	jmp	short loc_update_fat12_cell
   809                              <1> 
   810                              <1> loc_uc_check_fat12_buff_sector_load:
   811 00009A30 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   812 00009A33 0F8550010000        <1>         jne     loc_uc_load_fat_sectors
   813 00009A39 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   814 00009A3F 0F8544010000        <1>         jne     loc_uc_load_fat_sectors
   815                              <1> 
   816                              <1> loc_update_fat12_cell:
   817 00009A45 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   818 00009A4B 668B0D[92DB0000]    <1> 	mov	cx, [FAT_CurrentCluster]
   819 00009A52 66D1E9              <1> 	shr	cx, 1
   820 00009A55 668B03              <1> 	mov	ax, [ebx]
   821 00009A58 6689C2              <1> 	mov	dx, ax
   822 00009A5B 7344                <1> 	jnc	short uc_fat12_nc_even
   823                              <1> 
   824 00009A5D 6683E00F            <1> 	and	ax, 0Fh
   825 00009A61 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   826 00009A67 66C1E104            <1> 	shl	cx, 4
   827 00009A6B 6609C1              <1> 	or	cx, ax
   828 00009A6E 6689D0              <1> 	mov	ax, dx
   829 00009A71 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   830 00009A74 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   831                              <1> 
   832                              <1> update_fat12_buffer:
   833 00009A78 A3[92DB0000]        <1> 	mov	[FAT_CurrentCluster], eax
   834 00009A7D 89C2                <1> 	mov	edx, eax ; 01/03/2016
   835 00009A7F C605[96DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   836 00009A86 6683F802            <1> 	cmp	ax, 2
   837 00009A8A 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   838 00009A90 3B05[A2DB0000]      <1> 	cmp	eax, [LastCluster]
   839 00009A96 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   840 00009A9C E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   841                              <1> 
   842                              <1> uc_fat12_nc_even:
   843 00009AA1 662500F0            <1> 	and	ax, 0F000h
   844 00009AA5 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   845 00009AAB 80E50F              <1> 	and	ch, 0Fh
   846 00009AAE 6609C1              <1> 	or	cx, ax
   847 00009AB1 6689D0              <1> 	mov	ax, dx
   848 00009AB4 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   849 00009AB7 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   850 00009ABA EBBC                <1> 	jmp	short update_fat12_buffer
   851                              <1> 
   852                              <1> update_fat32_cluster:
   853 00009ABC 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   854 00009ABF 41                  <1> 	inc	ecx
   855 00009AC0 890D[A2DB0000]      <1> 	mov	[LastCluster], ecx
   856                              <1> 
   857 00009AC6 39C8                <1> 	cmp	eax, ecx
   858 00009AC8 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   859                              <1> 
   860                              <1> pass_uc_fat32_errc:
   861                              <1> 	;sub	edx, edx
   862 00009ACE BB80010000          <1> 	mov	ebx, 180h ;384
   863 00009AD3 F7F3                <1> 	div	ebx
   864                              <1> 	; EAX = Count of 3 FAT sectors
   865                              <1> 	; DX = Cluster offset in FAT buffer
   866 00009AD5 89D3                <1> 	mov	ebx, edx
   867 00009AD7 C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   868 00009ADA BA03000000          <1> 	mov	edx, 3	
   869 00009ADF F7E2                <1> 	mul	edx
   870                              <1> 	; EBX = Cluster Offset in FAT buffer
   871                              <1> 	; EAX = FAT Sector
   872                              <1> 	; EDX = 0
   873 00009AE1 8A0D[96DB0000]      <1> 	mov	cl, [FAT_BuffValidData]
   874 00009AE7 80F902              <1> 	cmp	cl, 2
   875 00009AEA 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   876                              <1> 
   877                              <1> loc_uc_check_fat32_buff_sector_save:
   878 00009AEC 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   879 00009AF2 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   880 00009AF8 EB11                <1> 	jmp	short loc_update_fat32_cell
   881                              <1> 
   882                              <1> loc_uc_check_fat32_buff_sector_load:
   883 00009AFA 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   884 00009AFD 0F8586000000        <1>         jne     loc_uc_load_fat_sectors
   885 00009B03 3B05[9ADB0000]      <1> 	cmp	eax, [FAT_BuffSector]
   886 00009B09 757E                <1>         jne     loc_uc_load_fat_sectors
   887                              <1> 
   888                              <1> loc_update_fat32_cell:
   889                              <1> loc_update_fat32_buffer:
   890 00009B0B 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   891 00009B11 8B03                <1> 	mov	eax, [ebx]
   892 00009B13 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   893                              <1> 	
   894 00009B18 8B15[92DB0000]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   895                              <1> 
   896 00009B1E A3[92DB0000]        <1> 	mov 	[FAT_CurrentCluster], eax
   897 00009B23 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue]
   898 00009B29 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   899                              <1> 
   900 00009B2B C605[96DB0000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   901                              <1> 
   902                              <1> 	; 01/03/2016
   903 00009B32 21C0                <1> 	and	eax, eax ; was it free cluster ?
   904 00009B34 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 00009B36 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   910 00009B39 7520                <1> 	jne	short loc_upd_fat32_c3
   911                              <1> 
   912 00009B3B 3B15[A2DB0000]      <1> 	cmp	edx, [LastCluster]
   913 00009B41 7207                <1> 	jb	short loc_upd_fat32_c0
   914                              <1> 
   915 00009B43 BA02000000          <1> 	mov	edx, 2 ; rewind !
   916 00009B48 EB0E                <1> 	jmp	short loc_upd_fat32_c2
   917                              <1> 
   918                              <1> loc_upd_fat32_c0:
   919 00009B4A FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   920 00009B4D EB0C                <1> 	jmp	short loc_upd_fat32_c3
   921                              <1> 
   922                              <1> loc_upd_fat32_c1:
   923 00009B4F 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   924 00009B51 7508                <1> 	jnz	short loc_upd_fat32_c3
   925                              <1> 
   926 00009B53 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   927 00009B56 7303                <1> 	jnb	short loc_upd_fat32_c3
   928                              <1> 
   929                              <1> loc_upd_fat32_c2:	
   930 00009B58 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   931                              <1> 
   932                              <1> loc_upd_fat32_c3:
   933 00009B5B 89C2                <1> 	mov	edx, eax
   934                              <1> 
   935                              <1> loc_upd_fat32_c4:
   936 00009B5D 83F802              <1> 	cmp	eax, 2
   937 00009B60 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   938                              <1> 
   939                              <1> pass_uc_fat32_c_zero_check_2:
   940 00009B66 3B05[A2DB0000]      <1> 	cmp	eax, [LastCluster]
   941 00009B6C 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   942                              <1> 	
   943 00009B72 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 00009B77 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   949 00009B7C 8825[96DB0000]      <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 00009B82 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue]
   955 00009B88 C3                  <1> 	retn
   956                              <1> 
   957                              <1> loc_uc_load_fat_sectors:
   958 00009B89 A3[9ADB0000]        <1> 	mov	[FAT_BuffSector], eax
   959                              <1> 
   960                              <1> load_uc_fat_sectors_zero:
   961 00009B8E 034660              <1> 	add	eax, [esi+LD_FATBegin]
   962 00009B91 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   963 00009B96 B903000000          <1> 	mov	ecx, 3
   964 00009B9B E88D220000          <1> 	call	disk_read
   965 00009BA0 72D5                <1> 	jc	short loc_fat_sectors_rw_error1
   966                              <1> 
   967 00009BA2 C605[96DB0000]01    <1>         mov     byte [FAT_BuffValidData], 1
   968 00009BA9 A1[92DB0000]        <1> 	mov 	eax, [FAT_CurrentCluster]
   969 00009BAE 8B0D[34DE0000]      <1> 	mov	ecx, [ClusterValue]
   970 00009BB4 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 00009BB9 31D2                <1> 	xor	edx, edx
   996 00009BBB 8A35[97DB0000]      <1> 	mov	dh, [FAT_BuffDrvName]
   997 00009BC1 80FE41              <1> 	cmp	dh, 'A'
   998 00009BC4 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
   999 00009BC6 80EE41              <1> 	sub	dh, 'A'
  1000 00009BC9 56                  <1> 	push	esi ; *
  1001 00009BCA BE00010900          <1>         mov     esi, Logical_DOSDisks
  1002 00009BCF 01D6                <1> 	add	esi, edx
  1003                              <1> 	
  1004 00009BD1 8A5603              <1> 	mov	dl, [esi+LD_FATType]
  1005 00009BD4 20D2                <1> 	and	dl, dl
  1006 00009BD6 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
  1007                              <1> 
  1008 00009BD8 A1[9ADB0000]        <1> 	mov	eax, [FAT_BuffSector]
  1009 00009BDD 80FA02              <1> 	cmp	dl, 2
  1010 00009BE0 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 00009BE2 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
  1019 00009BE6 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 00009BE8 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1023 00009BEA EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1024                              <1> 
  1025                              <1> loc_save_fat32_buff:
  1026 00009BEC 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1027 00009BEF 29C1                <1> 	sub	ecx, eax
  1028 00009BF1 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1029                              <1> 
  1030                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1031 00009BF3 5E                  <1> 	pop	esi ; *
  1032                              <1> loc_save_fat_buffer_inv_data_retn:
  1033 00009BF4 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1034 00009BF9 C3                  <1> 	retn
  1035                              <1> 
  1036                              <1> loc_save_fat_buff_remain_sectors_3:
  1037 00009BFA B903000000          <1> 	mov	ecx, 3
  1038 00009BFF EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1039                              <1> 
  1040                              <1> loc_save_fat_buffer_check_rs3:
  1041 00009C01 83F903              <1> 	cmp	ecx, 3
  1042 00009C04 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1043                              <1> 
  1044                              <1> loc_save_fat_buff_continue:
  1045 00009C06 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1046 00009C0B 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1047 00009C0E 51                  <1> 	push	ecx
  1048 00009C0F E80A220000          <1> 	call	disk_write
  1049 00009C14 59                  <1> 	pop	ecx
  1050 00009C15 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1051                              <1> 	
  1052 00009C17 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1053 00009C1B 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1054                              <1> 
  1055                              <1> loc_calc_2nd_fat32_addr:
  1056 00009C1D 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1057 00009C20 EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1058                              <1> 
  1059                              <1> loc_calc_2nd_fat12_16_addr:
  1060 00009C22 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1061                              <1> 
  1062                              <1> loc_calc_2nd_fat_addr:
  1063 00009C26 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1064 00009C29 0305[9ADB0000]      <1> 	add	eax, [FAT_BuffSector]
  1065 00009C2F BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1066                              <1> 	; ecx = 1 to 3
  1067 00009C34 E8E5210000          <1> 	call	disk_write
  1068 00009C39 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1069                              <1>  	; Valid  buffer (1 = valid but do not save)
  1070 00009C3B C605[96DB0000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1071                              <1> 
  1072                              <1> loc_save_FAT_buff_write_err:
  1073 00009C42 5E                  <1> 	pop	esi ; *
  1074 00009C43 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1075                              <1> 	; 23/03/2016
  1076 00009C48 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
  1077 00009C4D 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 00009C4E 66891D[3ADE0000]    <1> 	mov	[CFS_OPType], bx
  1105 00009C55 A3[3CDE0000]        <1> 	mov	[CFS_CC], eax
  1106                              <1> 	
  1107 00009C5A 80FFFF              <1> 	cmp	bh, 0FFh
  1108 00009C5D 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1109                              <1> 
  1110                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1111 00009C5F 31C0                <1> 	xor	eax, eax
  1112 00009C61 88FC                <1>         mov     ah, bh
  1113 00009C63 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1114 00009C68 01C6                <1>         add     esi, eax
  1115                              <1> 
  1116                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1117 00009C6A 08DB                <1> 	or	bl, bl
  1118 00009C6C 7435                <1> 	jz	short loc_reset_fcc
  1119                              <1> 	
  1120                              <1> loc_get_free_sectors:
  1121 00009C6E 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 00009C71 8B4E70              <1> 	mov	ecx, [esi+LD_TotalSectors]
  1130 00009C74 39C1                <1> 	cmp	ecx, eax ; Total sectors must be greater than Free sectors !
  1131 00009C76 7707                <1> 	ja	short loc_get_free_sectors_check_optype
  1132                              <1> 	
  1133 00009C78 31C0                <1> 	xor	eax, eax
  1134 00009C7A 48                  <1> 	dec	eax ; 0FFFFFFFFh  ; recalculation is needed!
  1135 00009C7B 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; reset (for recalculation)
  1136                              <1> 		
  1137                              <1> loc_get_free_sectors_retn:
  1138 00009C7E C3                  <1> 	retn
  1139                              <1> 	
  1140                              <1> loc_get_free_sectors_check_optype:
  1141 00009C7F 80FB03              <1> 	cmp	bl, 3
  1142 00009C82 7203                <1> 	jb	short loc_set_fcc
  1143                              <1> 
  1144 00009C84 29C9                <1> 	sub	ecx, ecx ; 0
  1145                              <1> 
  1146 00009C86 C3                  <1> 	retn	
  1147                              <1> 
  1148                              <1> loc_set_fcc:
  1149 00009C87 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1150 00009C8B 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1151                              <1> 
  1152                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1153 00009C91 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1154 00009C95 29D2                <1> 	sub	edx, edx
  1155 00009C97 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 00009C99 A3[B3DB0000]        <1> 	mov	[FreeClusterCount], eax
  1163 00009C9E E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1164                              <1> 
  1165                              <1> loc_reset_fcc:
  1166 00009CA3 31C0                <1> 	xor	eax, eax
  1167 00009CA5 A3[B3DB0000]        <1> 	mov	[FreeClusterCount], eax ; 0
  1168 00009CAA 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1169 00009CAD 42                  <1> 	inc	edx
  1170 00009CAE 8915[A2DB0000]      <1> 	mov	[LastCluster], edx
  1171                              <1> 
  1172 00009CB4 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1173 00009CB8 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1174                              <1> 
  1175 00009CBA 48                  <1> 	dec	eax ; FFFFFFFFh
  1176 00009CBB A3[44DE0000]        <1> 	mov	[CFS_FAT32FC], eax
  1177                              <1> 
  1178                              <1> 	; 29/02/2016
  1179 00009CC0 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1180 00009CC3 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1181                              <1> 	
  1182 00009CC6 B802000000          <1> 	mov 	eax, 2
  1183                              <1> 
  1184                              <1> loc_count_fc_next_cluster_0:
  1185 00009CCB 50                  <1> 	push	eax
  1186 00009CCC E801F9FFFF          <1> 	call	get_next_cluster
  1187 00009CD1 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1188 00009CD3 09C0                <1> 	or	eax, eax
  1189 00009CD5 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1190                              <1> 
  1191                              <1> loc_put_fcc_unknown_sign:
  1192 00009CD7 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 00009CD8 8B15[44DE0000]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1200                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1201 00009CDE 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1202                              <1> 	
  1203 00009CE1 EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1204                              <1> 
  1205                              <1> loc_check_fat32_ff_cluster:
  1206 00009CE3 09C0                <1> 	or	eax, eax
  1207 00009CE5 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1208 00009CE7 58                  <1> 	pop	eax
  1209 00009CE8 A3[44DE0000]        <1> 	mov	[CFS_FAT32FC], eax
  1210                              <1> 	;mov	dword [FreeClusterCount], 1
  1211 00009CED FF05[B3DB0000]      <1> 	inc	dword [FreeClusterCount]
  1212 00009CF3 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1213                              <1> 
  1214                              <1> pass_inc_cfs_fcc_0:
  1215 00009CF5 58                  <1> 	pop	eax
  1216                              <1> 
  1217                              <1> pass_inc_cfs_fcc_0c:
  1218 00009CF6 40                  <1> 	inc	eax ; add eax, 1
  1219 00009CF7 3B05[A2DB0000]      <1> 	cmp	eax, [LastCluster]
  1220 00009CFD 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1221 00009CFF 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 00009D01 B002                <1> 	mov	al, 2
  1226                              <1> 
  1227                              <1> loc_count_fc_next_cluster:
  1228 00009D03 50                  <1> 	push	eax
  1229 00009D04 E8C9F8FFFF          <1> 	call	get_next_cluster
  1230 00009D09 720C                <1> 	jc	short loc_count_fcc_stc
  1231                              <1> 
  1232                              <1> loc_count_free_clusters_1:
  1233 00009D0B 21C0                <1> 	and	eax, eax
  1234 00009D0D 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1235                              <1> 
  1236 00009D0F FF05[B3DB0000]      <1> 	inc	dword [FreeClusterCount]
  1237 00009D15 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1238                              <1> 
  1239                              <1> loc_count_fcc_stc:
  1240 00009D17 09C0                <1> 	or	eax, eax
  1241 00009D19 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1242                              <1> 
  1243                              <1> pass_inc_cfs_fcc:
  1244 00009D1B 58                  <1> 	pop	eax
  1245                              <1> 
  1246                              <1> pass_inc_cfs_fcc_1:
  1247 00009D1C 40                  <1> 	inc	eax ; add eax, 1
  1248 00009D1D 3B05[A2DB0000]      <1> 	cmp	eax, [LastCluster]
  1249 00009D23 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1250                              <1> 
  1251                              <1> loc_set_free_sectors:
  1252 00009D25 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1253 00009D29 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1254                              <1> 
  1255                              <1> loc_set_free_sectors_FAT12_FAT16:
  1256 00009D2B 803D[3ADE0000]00    <1> 	cmp	byte [CFS_OPType], 0
  1257 00009D32 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1258 00009D34 A1[3CDE0000]        <1> 	mov	eax, [CFS_CC]
  1259 00009D39 803D[3ADE0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1260 00009D40 7708                <1> 	ja	short pass_FAT_add_fcc
  1261 00009D42 0105[B3DB0000]      <1> 	add 	[FreeClusterCount], eax
  1262 00009D48 EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1263                              <1> 
  1264                              <1> pass_FAT_add_fcc:
  1265 00009D4A 2905[B3DB0000]      <1> 	sub	[FreeClusterCount], eax
  1266                              <1> 
  1267                              <1> pass_FAT_add_sub_fcc:
  1268 00009D50 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1269 00009D54 8B15[B3DB0000]      <1> 	mov	edx, [FreeClusterCount]
  1270 00009D5A F7E2                <1> 	mul	edx
  1271                              <1> 
  1272 00009D5C 31C9                <1> 	xor	ecx, ecx 
  1273 00009D5E EB05                <1> 	jmp	short loc_cfs_retn_params
  1274                              <1> 
  1275                              <1> loc_put_fcc_invalid_sign:
  1276 00009D60 29C0                <1>        	sub	eax, eax ; 0
  1277 00009D62 48                  <1> 	dec	eax ; FFFFFFFFh
  1278                              <1> loc_fat32_ffc_recalc_needed:
  1279 00009D63 89C1                <1> 	mov	ecx, eax
  1280                              <1> 
  1281                              <1> loc_cfs_retn_params:
  1282 00009D65 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1283 00009D68 0FB71D[3ADE0000]    <1> 	movzx	ebx, word [CFS_OPType]
  1284 00009D6F 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 00009D70 803D[3ADE0000]01    <1> 	cmp	byte [CFS_OPType], 1
  1292 00009D77 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1293 00009D79 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1294                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1295 00009D7B F71D[3CDE0000]      <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 00009D81 31D2                <1> 	xor	edx, edx ; 0
  1299 00009D83 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1300 00009D84 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1301 00009D87 39D0                <1> 	cmp	eax, edx
  1302 00009D89 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1303 00009D8B 0305[3CDE0000]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1304 00009D91 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1305                              <1> 	
  1306 00009D93 A3[B3DB0000]        <1> 	mov	[FreeClusterCount], eax
  1307 00009D98 EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1308                              <1> 
  1309                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1310 00009D9A 8B15[44DE0000]      <1> 	mov	edx, [CFS_FAT32FC]
  1311 00009DA0 A1[B3DB0000]        <1> 	mov	eax, [FreeClusterCount]
  1312 00009DA5 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1313                              <1> loc_cfs_write_FSINFO_sector:
  1314 00009DA8 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1315                              <1> 	; 01/03/2016
  1316 00009DAB E89A000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1317 00009DB0 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 00009DB2 8B0D[B3DB0000]      <1> 	mov	ecx, [FreeClusterCount]
  1327 00009DB8 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1328 00009DBC F7E1                <1> 	mul	ecx
  1329                              <1> 	; 29/02/2016
  1330 00009DBE 31C9                <1> 	xor	ecx, ecx ; 0
  1331 00009DC0 09D2                <1> 	or	edx, edx ; 0 ?
  1332 00009DC2 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1333 00009DC4 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1334 00009DC7 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1335                              <1> 	;
  1336                              <1> loc_set_FAT32_free_sectors_ok:
  1337 00009DC9 31D2                <1> 	xor	edx, edx ; 0
  1338 00009DCB 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 00009DCD 89C1                <1> 	mov	ecx, eax	
  1357                              <1> 
  1358                              <1> loc_glc_get_next_cluster_1:
  1359 00009DCF 890D[48DE0000]      <1> 	mov	[glc_prevcluster], ecx
  1360                              <1> 
  1361                              <1> loc_glc_get_next_cluster_2:
  1362 00009DD5 E8F8F7FFFF          <1> 	call	get_next_cluster
  1363                              <1> 	; ecx = current/previous cluster 
  1364                              <1> 	; eax = next/last cluster
  1365 00009DDA 73F3                <1> 	jnc	short loc_glc_get_next_cluster_1
  1366                              <1> 
  1367 00009DDC 09C0                <1> 	or	eax, eax
  1368 00009DDE 7509                <1> 	jnz	short loc_glc_stc_retn
  1369                              <1> 
  1370                              <1> 	; ecx = previous cluster
  1371 00009DE0 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 00009DE2 8B0D[48DE0000]      <1> 	mov	ecx, [glc_prevcluster] 
  1378 00009DE8 C3                  <1> 	retn
  1379                              <1> 
  1380                              <1> loc_glc_stc_retn:
  1381 00009DE9 F5                  <1> 	cmc	;stc
  1382 00009DEA 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 00009DEC 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1402                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1403 00009DEE 890D[9EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1404                              <1> 
  1405                              <1> loc_tcc_unlink_clusters:
  1406 00009DF4 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 00009DF9 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1413                              <1> 
  1414                              <1> pass_tcc_unlink_clusters:
  1415 00009DFB A2[4FDE0000]        <1> 	mov	byte [TCC_FATErr], al
  1416 00009E00 803D[96DB0000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1417 00009E07 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1418 00009E09 E8ABFDFFFF          <1> 	call	save_fat_buffer
  1419 00009E0E 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1420 00009E10 A2[4FDE0000]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1421                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1422                              <1> 
  1423                              <1> 	; 01/03/2016
  1424 00009E15 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1425                              <1> 
  1426                              <1> loc_tcc_calculate_FAT_freespace:
  1427 00009E17 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1428 00009E1C 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1429                              <1> 			   ; BL = 1 -> add cluster
  1430 00009E20 E829FEFFFF          <1> 	call	calculate_fat_freespace
  1431 00009E25 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1432 00009E27 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1433                              <1> 
  1434                              <1> loc_tcc_recalculate_FAT_freespace:
  1435 00009E29 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1436 00009E2D 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 00009E32 8B0D[9EDB0000]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1441                              <1> 
  1442 00009E38 803D[4FDE0000]00    <1> 	cmp	byte [TCC_FATErr], 0
  1443 00009E3F 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1444                              <1> 
  1445                              <1> loc_tcc_unlink_clusters_error:
  1446 00009E41 0FB605[4FDE0000]    <1> 	movzx	eax, byte [TCC_FATErr]
  1447 00009E48 F9                  <1> 	stc
  1448                              <1> loc_tcc_unlink_clusters_retn:
  1449 00009E49 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 00009E4A E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1466 00009E4F 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1467                              <1> 
  1468 00009E51 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1469 00009E54 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1470                              <1> 
  1471                              <1>         ;mov	ebx, DOSBootSectorBuff
  1472 00009E57 8983E8010000        <1> 	mov	[ebx+488], eax
  1473 00009E5D 8993EC010000        <1> 	mov	[ebx+492], edx	
  1474                              <1> 
  1475 00009E63 A1[40DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1476 00009E68 B901000000          <1> 	mov	ecx, 1
  1477 00009E6D E8AC1F0000          <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 00009E72 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 00009E73 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1507 00009E77 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1508 00009E7A A3[40DE0000]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1509                              <1> 	
  1510 00009E7F BB[92D90000]        <1>         mov     ebx, DOSBootSectorBuff
  1511 00009E84 B901000000          <1> 	mov	ecx, 1
  1512 00009E89 E89F1F0000          <1> 	call	disk_read
  1513 00009E8E 7232                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1514                              <1> 
  1515 00009E90 BB[92D90000]        <1> 	mov	ebx, DOSBootSectorBuff
  1516                              <1> 
  1517 00009E95 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1518 00009E9B 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1519                              <1> 
  1520 00009E9D 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1520 00009EA6 61                  <1>
  1521 00009EA7 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1522                              <1> 
  1523 00009EA9 A1[40DE0000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1524 00009EAE 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1525 00009EB4 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1526                              <1> 
  1527 00009EBA C3                  <1> 	retn
  1528                              <1> 
  1529                              <1> loc_read_FAT32_fsinfo_sec_stc:
  1530 00009EBB B80B000000          <1> 	mov	eax, 0Bh ; Invalid format!
  1531 00009EC0 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 00009EC2 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
  1536                              <1> 
  1537                              <1> loc_read_FAT32_fsinfo_sec_stc_retn:
  1538 00009EC7 29DB                <1> 	sub	ebx, ebx ; 0
  1539 00009EC9 F9                  <1> 	stc
  1540 00009ECA 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 00009ECB A3[6CDF0000]        <1> 	mov	[FAT_anc_LCluster], eax
  1565                              <1> 	
  1566 00009ED0 E854F9FFFF          <1> 	call	get_first_free_cluster
  1567 00009ED5 720B                <1> 	jc	short loc_add_new_cluster_retn
  1568                              <1> 	; EAX >= 2 and EAX < FFFFFFFFh is valid
  1569                              <1> 
  1570 00009ED7 89C2                <1> 	mov	edx, eax
  1571                              <1> 
  1572 00009ED9 42                  <1> 	inc	edx
  1573                              <1> 	;jnz	short loc_add_new_cluster_check_ffc_eax
  1574 00009EDA 7516                <1> 	jnz	short loc_add_new_cluster_save_fcc
  1575                              <1> 
  1576                              <1> loc_add_new_cluster_no_disk_space_retn:
  1577 00009EDC B827000000          <1> 	mov	eax, 27h ; MSDOS err => insufficient disk space
  1578                              <1> loc_add_new_cluster_stc_retn:
  1579 00009EE1 F9                  <1> 	stc
  1580                              <1> loc_add_new_cluster_retn:
  1581 00009EE2 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1582 00009EE6 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1583                              <1> 	;xor	edx, edx
  1584                              <1> 	;stc
  1585 00009EE9 C3                  <1> 	retn
  1586                              <1> 
  1587                              <1> loc_anc_invalid_format_stc_retn:
  1588 00009EEA F9                  <1> 	stc
  1589                              <1> loc_add_new_cluster_invalid_format_retn:
  1590 00009EEB B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  1591 00009EF0 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 00009EF2 A3[70DF0000]        <1> 	mov	[FAT_anc_FFCluster], eax
  1599                              <1> 
  1600 00009EF7 83E802              <1> 	sub	eax, 2
  1601 00009EFA 0FB65E13            <1>         movzx   ebx, byte [esi+LD_BPB+SecPerClust]
  1602 00009EFE F7E3                <1> 	mul	ebx
  1603 00009F00 09D2                <1> 	or	edx, edx
  1604 00009F02 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 00009F04 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 00009F05 BF00000700          <1> 	mov	edi, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  1621 00009F0A 89D9                <1> 	mov	ecx, ebx ; sector count
  1622 00009F0C C1E107              <1> 	shl	ecx, 7 ; 1 sector = 512 bytes -> 128 double words
  1623                              <1> 	;xor	eax, eax ; 0
  1624 00009F0F 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 00009F11 89D0                <1> 	mov	eax, edx
  1630 00009F13 034668              <1>         add     eax, [esi+LD_DATABegin]
  1631 00009F16 72D3                <1> 	jc	short loc_add_new_cluster_invalid_format_retn 
  1632                              <1> 		
  1633 00009F18 89D9                <1> 	mov	ecx, ebx ; ECX = sectors per cluster (<256)
  1634 00009F1A BB00000700          <1> 	mov	ebx, Cluster_Buffer
  1635 00009F1F E8FA1E0000          <1> 	call	disk_write
  1636 00009F24 7307                <1> 	jnc	short loc_add_new_cluster_update_fat_nlc
  1637                              <1> 	
  1638 00009F26 B81D000000          <1> 	mov	eax, 1Dh ; Write Error
  1639 00009F2B EBB4                <1> 	jmp	short loc_add_new_cluster_stc_retn
  1640                              <1> 
  1641                              <1> loc_add_new_cluster_update_fat_nlc:
  1642 00009F2D A1[70DF0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1643 00009F32 31C9                <1> 	xor	ecx, ecx
  1644 00009F34 890D[9EDB0000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1645 00009F3A 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1646 00009F3B E8BCF9FFFF          <1> 	call	update_cluster
  1647 00009F40 7304                <1> 	jnc	short loc_add_new_cluster_update_fat_plc
  1648 00009F42 09C0                <1> 	or	eax, eax ;EAX = 0 -> cluster value is 0 or eocc
  1649 00009F44 759B                <1> 	jnz	short loc_add_new_cluster_stc_retn
  1650                              <1> 
  1651                              <1> loc_add_new_cluster_update_fat_plc:
  1652 00009F46 A1[6CDF0000]        <1> 	mov	eax, [FAT_anc_LCluster]
  1653 00009F4B 8B0D[70DF0000]      <1> 	mov	ecx, [FAT_anc_FFCluster]
  1654 00009F51 E8A6F9FFFF          <1> 	call	update_cluster
  1655 00009F56 7314                <1> 	jnc	short loc_add_new_cluster_save_fat_buffer
  1656 00009F58 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1657 00009F5A 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 00009F5C 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1664                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1665 00009F60 50                  <1> 	push	eax
  1666 00009F61 E8E8FCFFFF          <1> 	call	calculate_fat_freespace
  1667 00009F66 58                  <1> 	pop	eax
  1668 00009F67 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 00009F6C E848FCFFFF          <1> 	call	save_fat_buffer
  1675 00009F71 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 00009F73 A1[9EDB0000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1680 00009F78 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI -> Dos drv desc. table
  1681                              <1> 		; BL = 1 -> add cluster
  1682 00009F7C 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 00009F7E E8CBFCFFFF          <1>         call    calculate_fat_freespace
  1686                              <1> 	;ECX = 0 -> no error, ECX > 0 -> error or invalid return
  1687 00009F83 21C9                <1> 	and	ecx, ecx ; ECX = 0 -> valid free sector count
  1688 00009F85 7409                <1> 	jz	short loc_add_new_cluster_return_cluster_number
  1689                              <1> 
  1690                              <1> loc_add_new_cluster_recalc_FAT_freespace:
  1691 00009F87 66BB00FF            <1> 	mov	bx, 0FF00h  ; recalculate free space
  1692 00009F8B E8BEFCFFFF          <1>         call    calculate_fat_freespace
  1693                              <1> 	; cf = 0
  1694                              <1> loc_add_new_cluster_return_cluster_number:
  1695 00009F90 89C1                <1> 	mov	ecx, eax ; Free sector count
  1696 00009F92 A1[70DF0000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1697 00009F97 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1698                              <1> 	;mov	edi, Cluster_Buffer
  1699 00009F9B 31D2                <1> 	xor	edx, edx
  1700 00009F9D 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 00009F9E 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 00009FA2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  1723 00009FA6 761C                <1> 	jna	short write_fs_cluster
  1724                              <1> 
  1725                              <1> write_fat_file_sectors: 
  1726 00009FA8 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
  1727 00009FAB 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
  1728 00009FAF F7E2                <1> 	mul	edx
  1729 00009FB1 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 00009FB4 E8651E0000          <1> 	call	disk_write
  1738 00009FB9 7306                <1> 	jnc	short wclust_retn
  1739                              <1> 	
  1740 00009FBB B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  1741 00009FC0 C3                  <1> 	retn
  1742                              <1> 
  1743                              <1> wclust_retn:
  1744 00009FC1 29C0                <1> 	sub	eax, eax ; 0
  1745 00009FC3 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 00009FC4 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
  1760 00009FC9 E801000000          <1> 	call	write_fs_sectors
  1761 00009FCE C3                  <1> 	retn
  1762                              <1> 
  1763                              <1> write_fs_sectors:
  1764                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1765 00009FCF F9                  <1> 	stc
  1766 00009FD0 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 00009FD1 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1783 00009FD5 721E                <1>         jb      get_fs_section_by_index 
  1784                              <1> 
  1785 00009FD7 3B4E78              <1> 	cmp	ecx, [esi+LD_Clusters]
  1786 00009FDA 7207                <1> 	jb	short gcbi_1
  1787                              <1> gcbi_0:
  1788 00009FDC F9                  <1> 	stc
  1789 00009FDD B823000000          <1> 	mov	eax, 23h ; Cluster not available ! 
  1790                              <1> 			 ; MSDOS error code: FCB unavailable
  1791 00009FE2 C3                  <1> 	retn
  1792                              <1> gcbi_1:
  1793 00009FE3 51                  <1> 	push	ecx
  1794 00009FE4 E8E9F5FFFF          <1> 	call	get_next_cluster
  1795 00009FE9 59                  <1> 	pop	ecx
  1796 00009FEA 7203                <1> 	jc	short gcbi_3
  1797 00009FEC E2F5                <1> 	loop	gcbi_1
  1798                              <1> gcbi_2:
  1799 00009FEE C3                  <1> 	retn
  1800                              <1> gcbi_3:
  1801 00009FEF 09C0                <1> 	or	eax, eax
  1802 00009FF1 74E9                <1> 	jz	short gcbi_0
  1803 00009FF3 F5                  <1> 	cmc 	; stc
  1804 00009FF4 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 00009FF5 B8FFFFFFFF          <1> 	mov	eax, 0FFFFFFFFh
  1821 00009FFA C3                  <1> 	retn
  1908                                  %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: 13/06/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> 	; 06/06/2016
    16                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
    17                              <1> 	; 16/04/2015 - 19/10/2015 (Retro UNIX 386 v1)
    18                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
    19                              <1> 	;
    20                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
    21                              <1> 	; The trap type is determined and an indirect jump is made to 
    22                              <1> 	; the appropriate system call handler. If there is a trap inside
    23                              <1> 	; the system a jump to panic is made. All user registers are saved 
    24                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
    25                              <1> 	; instructor is decoded to get the the system code part (see
    26                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
    27                              <1> 	; the indirect jump address is calculated. If a bad system call is
    28                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
    29                              <1> 	; is called. If the call is legitimate control passes to the
    30                              <1> 	; appropriate system routine.
    31                              <1> 	;
    32                              <1> 	; Calling sequence:
    33                              <1> 	;	Through a trap caused by any sys call outside the system.
    34                              <1> 	; Arguments:
    35                              <1> 	;	Arguments of particular system call.	
    36                              <1> 	; ...............................................................
    37                              <1> 	;	
    38                              <1> 	; Retro UNIX 8086 v1 modification: 
    39                              <1> 	;       System call number is in EAX register.
    40                              <1> 	;
    41                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
    42                              <1> 	;	registers depending of function details.
    43                              <1>   	;
    44                              <1> 	; 16/04/2015
    45 00009FFB 368925[78E30000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    46                              <1> 	; save user registers
    47 0000A002 1E                  <1> 	push	ds
    48 0000A003 06                  <1> 	push	es
    49 0000A004 0FA0                <1> 	push	fs
    50 0000A006 0FA8                <1> 	push	gs
    51 0000A008 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
    52                              <1> 	;
    53                              <1> 	; ESPACE = [ss:u.sp] - esp ; 4*12 = 48 ; 17/09/2015 ; 06/06/2016
    54                              <1> 	; 	(ESPACE is size of space in kernel stack 
    55                              <1> 	;	for saving/restoring user registers.)
    56                              <1> 	;
    57 0000A009 50                  <1> 	push	eax ; 01/07/2015
    58 0000A00A 66B81000            <1> 	mov     ax, KDATA
    59 0000A00E 8ED8                <1>         mov     ds, ax
    60 0000A010 8EC0                <1>         mov     es, ax
    61 0000A012 8EE0                <1>         mov     fs, ax
    62 0000A014 8EE8                <1>         mov     gs, ax
    63 0000A016 A1[B8D20000]        <1> 	mov	eax, [k_page_dir]
    64 0000A01B 0F22D8              <1> 	mov	cr3, eax
    65 0000A01E 58                  <1> 	pop	eax ; 01/07/2015
    66                              <1> 	; 19/10/2015
    67 0000A01F FC                  <1> 	cld
    68                              <1> 	;
    69 0000A020 FE05[75E30000]      <1> 	inc	byte [sysflg]
    70                              <1> 		; incb sysflg / indicate a system routine is in progress
    71 0000A026 FB                  <1>         sti 	; 18/01/2014
    72 0000A027 0F8557A0FFFF        <1> 	jnz     panic ; 24/05/2013
    73                              <1> 		; beq 1f
    74                              <1> 		; jmp panic ; / called if trap inside system
    75                              <1> ;1:
    76                              <1> 	; 16/04/2015
    77 0000A02D A3[80E30000]        <1> 	mov	[u.r0], eax
    78 0000A032 8925[7CE30000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
    79                              <1> 	;
    80                              <1> 		; mov $s.syst+2,clockp
    81                              <1> 		; mov r0,-(sp) / save user registers 
    82                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
    83                              <1> 			   ; / in u.r0
    84                              <1> 		; mov r1,-(sp)
    85                              <1> 		; mov r2,-(sp)
    86                              <1> 		; mov r3,-(sp)
    87                              <1> 		; mov r4,-(sp)
    88                              <1> 		; mov r5,-(sp)
    89                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
    90                              <1> 		             ; / arithmetic unit
    91                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
    92                              <1> 		             ; / extended arithmetic unit
    93                              <1> 		; mov sc,-(sp) / "step count" register for the extended
    94                              <1> 		             ; / arithmetic unit
    95                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
    96                              <1> 		; mov 18.(sp),r0 / store pc in r0
    97                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
    98                              <1> 		; sub $sys,r0 / get xxx code
    99 0000A038 C1E002              <1> 	shl	eax, 2
   100                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   101 0000A03B 3DA0000000          <1> 	cmp	eax, end_of_syscalls - syscalls
   102                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
   103                              <1> 	;jnb	short badsys
   104                              <1> 		; bhis badsys / yes, bad system call
   105 0000A040 F5                  <1> 	cmc
   106 0000A041 9C                  <1> 	pushf	
   107 0000A042 50                  <1> 	push	eax
   108 0000A043 8B2D[78E30000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   109 0000A049 B0FE                <1> 	mov	al, 0FEh ; 11111110b
   110 0000A04B 1400                <1> 	adc	al, 0 ; al = al + cf
   111 0000A04D 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
   112                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
   113                              <1> 				 ; / and clear carry bit
   114 0000A050 5D                  <1> 	pop	ebp ; eax
   115 0000A051 9D                  <1> 	popf
   116 0000A052 0F8254010000        <1>         jc      badsys
   117 0000A058 A1[80E30000]        <1> 	mov	eax, [u.r0]
   118                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   119 0000A05D FFA5[63A00000]      <1> 	jmp	dword [ebp+syscalls]
   120                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
   121                              <1> 		            ; / to proper system routine.
   122                              <1> syscalls: ; 1:
   123                              <1> 	; 20/05/2016
   124                              <1> 	; 19/05/2016
   125                              <1> 	; 16/05/2016
   126                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   127                              <1> 	; 21/09/2015
   128                              <1> 	; 01/07/2015
   129                              <1> 	; 16/04/2015 (32 bit address modification) 
   130                              <1> 	;dd sysrele	; / 0
   131 0000A063 [BABC0000]          <1> 	dd sysver	; 0 ; Get TRDOS 386 version number (v2.0)	
   132 0000A067 [0CA20000]          <1> 	dd sysexit 	; / 1
   133 0000A06B [76A30000]          <1> 	dd sysfork 	; / 2
   134 0000A06F [89A40000]          <1> 	dd sysread 	; / 3
   135 0000A073 [A4A40000]          <1> 	dd syswrite 	; / 4
   136 0000A077 [0EA50000]          <1> 	dd sysopen 	; / 5
   137 0000A07B [48A60000]          <1> 	dd sysclose 	; / 6
   138 0000A07F [F8A20000]          <1> 	dd syswait 	; / 7
   139 0000A083 [BEA50000]          <1> 	dd syscreat 	; / 8
   140 0000A087 [87AA0000]          <1> 	dd syslink 	; / 9
   141 0000A08B [49AB0000]          <1> 	dd sysunlink 	; / 10
   142 0000A08F [1CAC0000]          <1> 	dd sysexec 	; / 11
   143 0000A093 [76B00000]          <1> 	dd syschdir 	; / 12
   144 0000A097 [5AB10000]          <1> 	dd systime 	; / 13
   145 0000A09B [FFA50000]          <1> 	dd sysmkdir 	; / 14
   146 0000A09F [C8B00000]          <1> 	dd syschmod 	; / 15
   147 0000A0A3 [2AB10000]          <1> 	dd syschown 	; / 16
   148 0000A0A7 [8DB10000]          <1> 	dd sysbreak 	; / 17
   149 0000A0AB [E7AD0000]          <1> 	dd sysstat 	; / 18
   150 0000A0AF [52B20000]          <1> 	dd sysseek 	; / 19
   151 0000A0B3 [64B20000]          <1> 	dd systell 	; / 20
   152 0000A0B7 [65B30000]          <1> 	dd sysmount 	; / 21
   153 0000A0BB [17B40000]          <1> 	dd sysumount 	; / 22
   154 0000A0BF [E2B20000]          <1> 	dd syssetuid 	; / 23
   155 0000A0C3 [13B30000]          <1> 	dd sysgetuid 	; / 24
   156 0000A0C7 [69B10000]          <1> 	dd sysstime 	; / 25
   157 0000A0CB [D6B20000]          <1> 	dd sysquit 	; / 26
   158 0000A0CF [CAB20000]          <1> 	dd sysintr 	; / 27
   159 0000A0D3 [C3AD0000]          <1> 	dd sysfstat 	; / 28
   160 0000A0D7 [64A60000]          <1> 	dd sysemt 	; / 29
   161 0000A0DB [A9A70000]          <1> 	dd sysmdate 	; / 30
   162                              <1> 	;dd sysstty	; / 31
   163 0000A0DF [F4A70000]          <1> 	dd sysvideo 	; 31 ; TRDOS 386 Video Functions (16/05/2016)
   164                              <1> 	;dd sysgtty	; / 32
   165 0000A0E3 [75AA0000]          <1> 	dd sysaudio 	; 32 ; TRDOS 386 Audio Functions (16/05/2016)
   166                              <1> 	;dd sysilgins	; / 33
   167 0000A0E7 [7DA60000]          <1> 	dd systimer 	; 33 ; TRDOS 386 Timer Functions (18/05/2016)
   168 0000A0EB [72B40000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   169                              <1> 			     ; 11/06/2014
   170 0000A0EF [A1B40000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   171                              <1> 			     ; 01/07/2015
   172 0000A0F3 [77B50000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   173                              <1> 			     ; 21/09/2015 - get last error number
   174 0000A0F7 [C9BC0000]          <1> 	dd sysreserved1 ; 37 ;; TRDOS 386 (19/05/2016)
   175 0000A0FB [D8BC0000]          <1> 	dd syspri 	; 38 ; change priority - TRDOS 386 (20/05/2016)
   176 0000A0FF [76A10000]          <1> 	dd sysrele	; 39 ; TRDOS 386 (19/05/2016) (0 -> 39)
   177                              <1> 
   178                              <1> end_of_syscalls:
   179                              <1> 
   180                              <1> error:
   181                              <1> 	; 18/05/2016
   182                              <1> 	; 13/05/2016
   183                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   184                              <1> 	; 16/04/2015 - 17/09/2015 (Retro UNIX 386 v1)
   185                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
   186                              <1> 	;
   187                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
   188                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
   189                              <1> 	;
   190                              <1> 	; INPUTS -> none
   191                              <1> 	; OUTPUTS ->
   192                              <1> 	;	processor status - carry (c) bit is set (means error)
   193                              <1> 	;
   194                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
   195                              <1> 	; 	      Because, jumps to error procedure
   196                              <1> 	;	      disrupts push-pop nesting balance)
   197                              <1> 	;
   198 0000A103 8B2D[78E30000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   199 0000A109 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
   200                              <1> 				 ; (system call will return with cf = 1)
   201                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
   202                              <1> 		               ; / users stack
   203                              <1> 	; 17/09/2015
   204 0000A10D 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
   205                              <1> 				 ; for saving/restoring user registers	
   206                              <1> 	;cmp	ebp, [u.usp]
   207                              <1> 	;je	short err0	
   208 0000A110 892D[7CE30000]      <1> 	mov	[u.usp], ebp
   209                              <1> ;err0:
   210                              <1> 	; 01/09/2015
   211 0000A116 8B25[7CE30000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
   212                              <1> 				    ; 10/04/2013
   213                              <1> 				    ; (If an I/O error occurs during disk I/O,
   214                              <1> 				    ; related procedures will jump to 'error'
   215                              <1> 				    ; procedure directly without returning to 
   216                              <1> 				    ; the caller procedure. So, stack pointer
   217                              <1>                                     ; must be restored here.)
   218                              <1> 	; 13/05/2016
   219                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
   220                              <1> 	;	'get last error' system call later. 	
   221                              <1> 
   222                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
   223 0000A11C C605[E7E30000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
   224                              <1> 
   225                              <1> sysret: ; < return from system call>
   226                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   227                              <1> 	; 16/04/2015 - 10/09/2015 (Retro UNIX 386 v1)
   228                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
   229                              <1> 	;
   230                              <1> 	; 'sysret' first checks to see if process is about to be 
   231                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
   232                              <1> 	; If not, following happens:	 
   233                              <1> 	; 	1) The user's stack pointer is restored.
   234                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
   235                              <1> 	;	   i-node has been modified. If it has, it is written out
   236                              <1> 	;	   via 'ppoke'.
   237                              <1> 	;	3) If the super block has been modified, it is written out
   238                              <1> 	;	   via 'ppoke'.				
   239                              <1> 	;	4) If the dismountable file system's super block has been
   240                              <1> 	;	   modified, it is written out to the specified device
   241                              <1> 	;	   via 'ppoke'.
   242                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
   243                              <1> 	;	   during his execution. If so, 'tswap' is called to give
   244                              <1> 	;	   another user a chance to run.
   245                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
   246                              <1> 	;	    (See 'sysrele' for conclusion.)		
   247                              <1> 	;
   248                              <1> 	; Calling sequence:
   249                              <1> 	;	jump table or 'br sysret'
   250                              <1> 	; Arguments: 
   251                              <1> 	;	-	
   252                              <1> 	; ...............................................................
   253                              <1> 	;	
   254                              <1> 	; ((AX=r1 for 'iget' input))
   255                              <1> 	;	
   256 0000A123 6631C0              <1> 	xor	ax, ax ; 04/05/2013
   257                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   258 0000A126 FEC0                <1> 	inc	al ; 04/05/2013
   259 0000A128 3805[CEE30000]      <1> 	cmp	[u.bsys], al ; 1
   260                              <1> 		; tstb u.bsys / is a process about to be terminated because
   261 0000A12E 0F83D8000000        <1>         jnb     sysexit ; 04/05/2013
   262                              <1> 		; bne sysexit / of an error? yes, go to sysexit
   263                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
   264                              <1> 		; mov u.sp,sp / no point stack to users stack
   265 0000A134 FEC8                <1> 	dec 	al ; mov ax, 0
   266                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   267 0000A136 E8D01C0000          <1> 	call	iget
   268                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   269                              <1> 		            ; / it is written out
   270 0000A13B 6631C0              <1> 	xor 	ax, ax ; 0
   271 0000A13E 3805[73E30000]      <1> 	cmp	[smod], al ; 0
   272                              <1> 		; tstb	smod / has the super block been modified
   273 0000A144 7614                <1> 	jna	short sysret1
   274                              <1> 		; beq	1f / no, 1f
   275 0000A146 A2[73E30000]        <1> 	mov	[smod], al ; 0
   276                              <1> 		; clrb smod / yes, clear smod
   277 0000A14B BB[2DEC0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
   278 0000A150 66810B0002          <1>    	or	word [ebx], 200h ;;
   279                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
   280                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
   281                              <1> 		      	      ; / output
   282                              <1> 	; AX = 0
   283 0000A155 E8B21C0000          <1> 	call 	poke ; 07/08/2013
   284                              <1> 	; call	ppoke
   285                              <1> 	; AX = 0
   286                              <1> 		; jsr r0,ppoke / write out modified super block to disk
   287                              <1> sysret1: ;1:
   288 0000A15A 3805[74E30000]      <1> 	cmp	[mmod], al ; 0
   289                              <1> 		; tstb	mmod / has the super block for the dismountable file
   290                              <1> 		           ; / system
   291 0000A160 7614                <1> 	jna	short sysrel0
   292                              <1> 		; beq 1f / been modified?  no, 1f
   293 0000A162 A2[74E30000]        <1> 	mov	[mmod], al ; 0	
   294                              <1> 		; clrb	mmod / yes, clear mmod
   295                              <1>         ;mov    ax, [mntd]
   296                              <1>         ;;mov   al, [mdev] ; 26/04/2013
   297 0000A167 BB[35EE0000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
   298                              <1>         ;;mov	[ebx], al
   299                              <1> 	;mov    [sb1], al
   300                              <1> 		; movb	mntd,sb1 / set the I/O queue
   301 0000A16C 66810B0002          <1> 	or	word [ebx], 200h
   302                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
   303                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
   304 0000A171 E8961C0000          <1> 	call	poke ; 07/08/2013
   305                              <1> 	;call	ppoke 
   306                              <1> 		; jsr r0,ppoke / write it out to its device
   307                              <1>         ;xor    al, al ; 26/04/2013       
   308                              <1> ;1:
   309                              <1> 		; tstb uquant / is the time quantum 0?
   310                              <1> 		; bne 1f / no, don't swap it out
   311                              <1> 
   312                              <1> sysrele: ; < release >
   313                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   314                              <1> 	; 16/04/2015 - 14/10/2015 (Retro UNIX 386 v1)
   315                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
   316                              <1> 	;
   317                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
   318                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
   319                              <1> 	; turns off the system flag. It then checked to see if there is
   320                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
   321                              <1> 	; the output gets flashed (see isintr) and interrupt action is
   322                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
   323                              <1> 	; the user, a rti is made.
   324                              <1> 	;
   325                              <1> 	; Calling sequence:
   326                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
   327                              <1> 	; Arguments:
   328                              <1> 	;	-	
   329                              <1> 	; ...............................................................
   330                              <1> 	;	
   331                              <1> 	; 23/02/2014 (swapret)
   332                              <1> 	; 22/09/2013
   333                              <1> sysrel0: ;1:
   334 0000A176 803D[C2E30000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   335                              <1> 		; tstb uquant / is the time quantum 0?
   336 0000A17D 7705                <1>         ja      short swapret
   337                              <1> 		; bne 1f / no, don't swap it out
   338                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
   339 0000A17F E8031A0000          <1> 	call	tswap
   340                              <1> 		; jsr r0,tswap / yes, swap it out
   341                              <1> 	
   342                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
   343                              <1> swapret: ;1:
   344                              <1> 	; 10/09/2015
   345                              <1> 	; 01/09/2015
   346                              <1> 	; 14/05/2015
   347                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
   348                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
   349                              <1> 	; cli
   350                              <1> 	; 24/07/2015
   351                              <1> 	;
   352                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
   353                              <1> 	;; mov	esp, [u.usp]
   354                              <1> 
   355                              <1> 	; 22/09/2013
   356 0000A184 E8841C0000          <1> 	call	isintr
   357                              <1> 	; 20/10/2013
   358 0000A189 7405                <1> 	jz	short sysrel1
   359 0000A18B E865000000          <1> 	call	intract
   360                              <1> 		; jsr r0,isintr / is there an interrupt from the user
   361                              <1> 		;     br intract / yes, output gets flushed, take interrupt
   362                              <1> 		               ; / action
   363                              <1> sysrel1:
   364 0000A190 FA                  <1> 	cli ; 14/10/2015
   365 0000A191 FE0D[75E30000]      <1> 	dec	byte [sysflg]
   366                              <1> 		; decb sysflg / turn system flag off
   367 0000A197 A1[D9E30000]        <1> 	mov     eax, [u.pgdir]
   368 0000A19C 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
   369                              <1> 			  ; (others are different than kernel page tables) 
   370                              <1> 	; 10/09/2015
   371 0000A19F 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   372                              <1> 		; mov (sp)+,sc / restore user registers
   373                              <1> 		; mov (sp)+,mq
   374                              <1> 		; mov (sp)+,ac
   375                              <1> 		; mov (sp)+,r5
   376                              <1> 		; mov (sp)+,r4
   377                              <1> 		; mov (sp)+,r3
   378                              <1> 		; mov (sp)+,r2
   379                              <1> 	;
   380 0000A1A0 A1[80E30000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   381 0000A1A5 0FA9                <1> 	pop	gs
   382 0000A1A7 0FA1                <1> 	pop	fs
   383 0000A1A9 07                  <1> 	pop	es
   384 0000A1AA 1F                  <1> 	pop	ds
   385 0000A1AB CF                  <1> 	iretd	
   386                              <1> 		; rti / no, return from interrupt
   387                              <1> 
   388                              <1> badsys:
   389                              <1> 	; 18/04/2016 (TRDOS 386 = TRDOS v2.0)
   390                              <1> 	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
   391                              <1> 	; 03/02/2011 ('trdos_ifc_routine')
   392                              <1> 	;
   393                              <1> 	; 16/04/2015 (Retro UNIX 386 v1, 'badsys')
   394                              <1> 	; (EIP, EAX values will be shown on screen with error message)
   395                              <1> 	; (EIP = 'CD 40h' instruction address -INT 40h-)
   396                              <1> 	; (EAX = Function number)  
   397                              <1> 	;
   398 0000A1AC FE05[CEE30000]      <1> 	inc	byte [u.bsys]
   399                              <1> 	;
   400 0000A1B2 8B1D[78E30000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   401 0000A1B8 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   402 0000A1BA 83E802              <1> 	sub	eax, 2 ; CDh, ##h
   403 0000A1BD E86677FFFF          <1> 	call	dwordtohex
   404 0000A1C2 8915[2DC90000]      <1> 	mov	[eip_str], edx
   405 0000A1C8 A3[31C90000]        <1> 	mov	[eip_str+4], eax
   406 0000A1CD A1[80E30000]        <1> 	mov	eax, [u.r0]
   407 0000A1D2 E85177FFFF          <1> 	call	dwordtohex
   408 0000A1D7 8915[1CC90000]      <1> 	mov	[eax_str], edx
   409 0000A1DD A3[20C90000]        <1> 	mov	[eax_str+4], eax
   410                              <1> 
   411 0000A1E2 C605[11C90000]40    <1> 	mov	byte [int_num_str], 40h
   412                              <1> 
   413 0000A1E9 BE[E3C80000]        <1> 	mov	esi, ifc_msg ; "invalid funtion call !" msg (trdosk9.s)
   414 0000A1EE E83D9EFFFF          <1> 	call	print_msg
   415                              <1> 
   416 0000A1F3 EB17                <1> 	jmp	sysexit
   417                              <1> 
   418                              <1> intract: ; / interrupt action
   419                              <1> 	; 14/10/2015
   420                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   421                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
   422                              <1> 	;
   423                              <1> 	; Retro UNIX 8086 v1 modification !
   424                              <1> 	; (Process/task switching and quit routine by using
   425                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
   426                              <1> 	;
   427                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
   428                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
   429                              <1> 	;		'intract' will jump to 'sysexit'.
   430                              <1> 	;	    Intract will return to the caller 
   431                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
   432                              <1> 	; 14/10/2015
   433 0000A1F5 FB                  <1> 	sti
   434                              <1> 	; 07/12/2013	
   435 0000A1F6 66FF05[C6E30000]    <1> 	inc 	word [u.quit]
   436 0000A1FD 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   437 0000A1FF 66FF0D[C6E30000]    <1> 	dec	word [u.quit]
   438                              <1> 	; 16/04/2015
   439 0000A206 C3                  <1> 	retn
   440                              <1> intrct0:	
   441 0000A207 58                  <1> 	pop	eax ; call intract -> retn
   442                              <1> 	;
   443 0000A208 31C0                <1> 	xor 	eax, eax
   444 0000A20A FEC0                <1> 	inc	al  ; mov ax, 1
   445                              <1> ;;;
   446                              <1> 	; UNIX v1 original 'intract' routine... 
   447                              <1> 	; / interrupt action
   448                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
   449                              <1> 		; bne 1f / no, 1f
   450                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
   451                              <1> 	; 1: / now in user area
   452                              <1> 		; mov r1,-(sp) / save r1
   453                              <1> 		; mov u.ttyp,r1 
   454                              <1> 			; / pointer to tty buffer in control-to r1
   455                              <1> 		; cmpb 6(r1),$177
   456                              <1> 			; / is the interrupt char equal to "del"
   457                              <1> 		; beq 1f / yes, 1f
   458                              <1> 		; clrb 6(r1) 
   459                              <1> 		        ; / no, clear the byte 
   460                              <1> 			; / (must be a quit character)
   461                              <1> 		; mov (sp)+,r1 / restore r1
   462                              <1> 		; clr u.quit / clear quit flag
   463                              <1> 		; bis $20,2(sp) 
   464                              <1> 		    	; / set trace for quit (sets t bit of 
   465                              <1> 			; / ps-trace trap)
   466                              <1> 		; rti   ;  / return from interrupt
   467                              <1> 	; 1: / interrupt char = del
   468                              <1> 		; clrb 6(r1) / clear the interrupt byte 
   469                              <1> 			   ; / in the buffer
   470                              <1> 		; mov (sp)+,r1 / restore r1
   471                              <1> 		; cmp u.intr,$core / should control be 
   472                              <1> 				; / transferred to loc core?
   473                              <1> 		; blo 1f
   474                              <1> 		; jmp *u.intr / user to do rti yes, 
   475                              <1> 				; / transfer to loc core
   476                              <1> 	; 1:
   477                              <1> 		; sys 1 / exit
   478                              <1> 
   479                              <1> sysexit: ; <terminate process>
   480                              <1> 	; 10/06/2016
   481                              <1> 	; 06/06/2016
   482                              <1> 	; 23/05/2016
   483                              <1> 	; 19/05/2016
   484                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   485                              <1> 	; 16/04/2015 - 01/09/2015 (Retro UNIX 386 v1)
   486                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   487                              <1> 	;
   488                              <1> 	; 'sysexit' terminates a process. First each file that
   489                              <1> 	; the process has opened is closed by 'flose'. The process
   490                              <1> 	; status is then set to unused. The 'p.pid' table is then
   491                              <1> 	; searched to find children of the dying process. If any of
   492                              <1> 	; children are zombies (died by not waited for), they are
   493                              <1> 	; set free. The 'p.pid' table is then searched to find the
   494                              <1> 	; dying process's parent. When the parent is found, it is
   495                              <1> 	; checked to see if it is free or it is a zombie. If it is
   496                              <1> 	; one of these, the dying process just dies. If it is waiting
   497                              <1> 	; for a child process to die, it notified that it doesn't 
   498                              <1> 	; have to wait anymore by setting it's status from 2 to 1
   499                              <1> 	; (waiting to active). It is awakened and put on runq by
   500                              <1> 	; 'putlu'. The dying process enters a zombie state in which
   501                              <1> 	; it will never be run again but stays around until a 'wait'
   502                              <1> 	; is completed by it's parent process. If the parent is not
   503                              <1> 	; found, process just dies. This means 'swap' is called with
   504                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
   505                              <1> 	; to write out the process and 'rswap' reads the new process
   506                              <1> 	; over the one that dies..i.e., the dying process is 
   507                              <1> 	; overwritten and destroyed.	
   508                              <1>  	;
   509                              <1> 	; Calling sequence:
   510                              <1> 	;	sysexit or conditional branch.
   511                              <1> 	; Arguments:
   512                              <1> 	;	-	
   513                              <1> 	; ...............................................................
   514                              <1> 	;	
   515                              <1> 	; Retro UNIX 8086 v1 modification: 
   516                              <1> 	;       System call number (=1) is in EAX register.
   517                              <1> 	;
   518                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
   519                              <1> 	;       registers depending of function details.
   520                              <1> 	;
   521                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
   522                              <1> 	;
   523                              <1> ; / terminate process
   524                              <1> 	; AX = 1
   525 0000A20C 6648                <1> 	dec 	ax ; 0
   526 0000A20E 66A3[C4E30000]      <1> 	mov	[u.intr], ax ; 0
   527                              <1> 		; clr u.intr / clear interrupt control word
   528                              <1> 		; clr r1 / clear r1
   529                              <1> 	; AX = 0
   530                              <1> sysexit_1: ; 1:
   531                              <1> 	; AX = File descriptor
   532                              <1> 		; / r1 has file descriptor (index to u.fp list)
   533                              <1> 		; / Search the whole list
   534 0000A214 E8640C0000          <1> 	call	fclose
   535                              <1> 		; jsr r0,fclose / close all files the process opened
   536                              <1> 	;; ignore error return
   537                              <1> 		; br .+2 / ignore error return
   538                              <1> 	;inc	ax
   539 0000A219 FEC0                <1> 	inc	al
   540                              <1> 		; inc r1 / increment file descriptor
   541                              <1> 	;cmp	ax, 10
   542 0000A21B 3C0A                <1> 	cmp	al, 10
   543                              <1> 		; cmp r1,$10. / end of u.fp list?
   544 0000A21D 72F5                <1> 	jb	short sysexit_1
   545                              <1> 		; blt 1b / no, go back
   546 0000A21F 0FB61D[CFE30000]    <1> 	movzx	ebx, byte [u.uno]
   547                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   548 0000A226 88A3[F1E00000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   549                              <1> 		; clrb p.stat-1(r1) / free the process
   550                              <1> 	;shl	bx, 1
   551 0000A22C D0E3                <1> 	shl	bl, 1
   552                              <1> 		; asl r1 / use r1 for index into the below tables
   553 0000A22E 668B8B[60E00000]    <1> 	mov	cx, [ebx+p.pid-2]
   554                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   555 0000A235 668B93[80E00000]    <1> 	mov	dx, [ebx+p.ppid-2]
   556                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
   557                              <1> 	; xor 	bx, bx ; 0
   558 0000A23C 30DB                <1> 	xor	bl, bl ; 0
   559                              <1> 		; clr r2
   560 0000A23E 31F6                <1> 	xor	esi, esi ; 0
   561                              <1> 		; clr r5 / initialize reg
   562                              <1> sysexit_2: ; 1:
   563                              <1> 	        ; / find children of this dying process, 
   564                              <1> 		; / if they are zombies, free them
   565                              <1> 	;add	bx, 2
   566 0000A240 80C302              <1> 	add	bl, 2
   567                              <1> 		; add $2,r2 / search parent process table 
   568                              <1> 		          ; / for dying process's name
   569 0000A243 66398B[80E00000]    <1> 	cmp	[ebx+p.ppid-2], cx
   570                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   571 0000A24A 7513                <1> 	jne	short sysexit_4
   572                              <1> 		; bne 3f / no
   573                              <1> 	;shr	bx, 1
   574 0000A24C D0EB                <1> 	shr	bl, 1
   575                              <1> 		; asr r2 / yes, it is a parent
   576 0000A24E 80BB[F1E00000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB
   577                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
   578                              <1> 				     ; / dying process a zombie
   579 0000A255 7506                <1> 	jne	short sysexit_3 
   580                              <1> 		; bne 2f / no
   581 0000A257 88A3[F1E00000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   582                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
   583                              <1> sysexit_3: ; 2:
   584                              <1> 	;shr	bx, 1
   585 0000A25D D0E3                <1> 	shl	bl, 1
   586                              <1> 		; asl r2
   587                              <1> sysexit_4: ; 3:
   588                              <1> 		; / search the process name table 
   589                              <1> 		; / for the dying process's parent
   590 0000A25F 663993[60E00000]    <1> 	cmp	[ebx+p.pid-2], dx
   591                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   592 0000A266 7502                <1> 	jne	short sysexit_5
   593                              <1> 		; bne 3f / no
   594 0000A268 89DE                <1> 	mov	esi, ebx
   595                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
   596                              <1> 		          ; / process # x2) in r5
   597                              <1> sysexit_5: ; 3:
   598                              <1> 	;cmp	bx, nproc + nproc
   599 0000A26A 80FB20              <1> 	cmp	bl, nproc + nproc
   600                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   601 0000A26D 72D1                <1> 	jb	short sysexit_2
   602                              <1> 		; blt 1b / no, go back
   603                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
   604 0000A26F 21F6                <1> 	and	esi, esi ; r5=r1
   605 0000A271 7431                <1> 	jz	short sysexit_6
   606                              <1> 		; beq 2f / no parent has been found. 
   607                              <1> 		       ; / The process just dies
   608 0000A273 66D1EE              <1> 	shr	si, 1
   609                              <1> 		; asr r1 / set up index to p.stat
   610 0000A276 8A86[F1E00000]      <1> 	mov	al, [esi+p.stat-1]
   611                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   612 0000A27C 20C0                <1> 	and	al, al
   613 0000A27E 7424                <1> 	jz	short sysexit_6
   614                              <1> 		; beq 2f / if its been freed, 2f
   615 0000A280 3C03                <1> 	cmp	al, 3
   616                              <1> 		; cmp r2,$3 / is parent a zombie?
   617 0000A282 7420                <1> 	je	short sysexit_6
   618                              <1> 		; beq 2f / yes, 2f
   619                              <1> 	; BH = 0
   620 0000A284 8A1D[CFE30000]      <1> 	mov	bl, [u.uno]
   621                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   622 0000A28A C683[F1E00000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB
   623                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   624 0000A291 3C01                <1> 	cmp	al, 1 ; SRUN
   625 0000A293 740F                <1> 	je	short sysexit_6
   626                              <1> 	;cmp	al, 2
   627                              <1> 		; cmp r2,$2 / is the parent waiting for 
   628                              <1> 			  ; / this child to die
   629                              <1> 	;jne	short sysexit_6	
   630                              <1> 		; bne 2f / yes, notify parent not to wait any more
   631                              <1> 	; p.stat = 2 --> waiting
   632                              <1> 	; p.stat = 4 --> sleeping
   633 0000A295 C686[F1E00000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN
   634                              <1> 	;dec	byte [esi+p.stat-1]
   635                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
   636 0000A29C 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
   637                              <1> 	; 
   638                              <1> 	;mov	ebx, runq + 4
   639                              <1> 		; mov $runq+4,r2 / on the runq
   640 0000A29F E8F6190000          <1> 	call	putlu
   641                              <1> 		; jsr r0, putlu
   642                              <1> sysexit_6: 
   643                              <1> 	; 10/06/2016
   644                              <1> 	; 06/06/2016
   645                              <1> 	; 23/05/2016
   646                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   647                              <1> 	; Check and stop/clear timer event(s) of this (dying) process
   648                              <1> 	; if there is.
   649 0000A2A4 8A86[41E10000]      <1> 	mov 	al, [esi+p.timer-1]
   650 0000A2AA 20C0                <1> 	and	al, al
   651 0000A2AC 743C                <1> 	jz	short sysexit_12 ; no timer events for this process
   652 0000A2AE C686[41E10000]00    <1> 	mov	byte [esi+p.timer-1], 0 ; reset
   653 0000A2B5 A0[40E00000]        <1> 	mov	al, [timer_events]
   654                              <1> 	;or	al, al
   655                              <1>  	;jz	short sysexit_12 ; no timer events
   656 0000A2BA 88C1                <1> 	mov	cl, al
   657 0000A2BC 8A25[CFE30000]      <1> 	mov	ah, [u.uno]
   658 0000A2C2 FA                  <1> 	cli	; disable interrupts 
   659 0000A2C3 B310                <1> 	mov	bl, 16
   660 0000A2C5 BE[44F00000]        <1> 	mov	esi, timer_set ; beginning address of timer events
   661                              <1> sysexit_7:
   662 0000A2CA 8A06                <1> 	mov	al, [esi] ; process number (of timer event)
   663 0000A2CC 38E0                <1> 	cmp	al, ah ; process number comparison
   664 0000A2CE 7411                <1> 	je	short sysexit_10
   665 0000A2D0 20C0                <1> 	and	al, al
   666 0000A2D2 7404                <1> 	jz	short sysexit_9
   667                              <1> sysexit_8:
   668 0000A2D4 FEC9                <1> 	dec	cl
   669 0000A2D6 7410                <1> 	jz	short sysexit_11
   670                              <1> sysexit_9:
   671 0000A2D8 FECB                <1> 	dec	bl
   672 0000A2DA 740C                <1> 	jz	short sysexit_11
   673 0000A2DC 83C610              <1> 	add	esi, 16
   674 0000A2DF EBE9                <1> 	jmp	short sysexit_7
   675                              <1> 
   676                              <1> sysexit_10:
   677                              <1> 	;mov	byte [esi], 0
   678 0000A2E1 66C7060000          <1> 	mov	word [esi], 0
   679                              <1> 	;mov	dword [esi+12], 0
   680 0000A2E6 EBEC                <1> 	jmp	short sysexit_8
   681                              <1> 
   682                              <1> sysexit_11:
   683 0000A2E8 30C0                <1> 	xor	al, al
   684                              <1> sysexit_12: ; 2:
   685 0000A2EA FB                  <1> 	sti	; enable interrupts 
   686                              <1> 	;
   687 0000A2EB A2[CFE30000]        <1> 	mov	[u.uno], al ; 0
   688                              <1> 		; / the process dies
   689                              <1> 	;mov	byte [u.uno], 0
   690                              <1> 		; clrb u.uno / put zero as the process number, 
   691                              <1> 	           ; / so "swap" will
   692 0000A2F0 E8B5180000          <1> 	call	swap
   693                              <1> 		; jsr r0,swap / overwrite process with another process
   694                              <1> hlt_sys:
   695                              <1> 	;sti
   696                              <1> hlts0:
   697 0000A2F5 F4                  <1> 	hlt
   698 0000A2F6 EBFD                <1> 	jmp	short hlts0
   699                              <1> 		; 0 / and thereby kill it; halt?
   700                              <1> 
   701                              <1> syswait: ; < wait for a processs to die >
   702                              <1> 	; 17/09/2015
   703                              <1> 	; 02/09/2015
   704                              <1> 	; 01/09/2015
   705                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   706                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
   707                              <1> 	;
   708                              <1> 	; 'syswait' waits for a process die. 
   709                              <1> 	; It works in following way:
   710                              <1> 	;    1) From the parent process number, the parent's 
   711                              <1> 	; 	process name is found. The p.ppid table of parent
   712                              <1> 	;	names is then searched for this process name.
   713                              <1> 	;	If a match occurs, r2 contains child's process
   714                              <1> 	;	number. The child status is checked to see if it is
   715                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
   716                              <1> 	;	If it is, the child process is freed and it's name
   717                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
   718                              <1> 	;	If the child is not a zombie, nothing happens and
   719                              <1> 	;	the search goes on through the p.ppid table until
   720                              <1> 	;	all processes are checked or a zombie is found.
   721                              <1> 	;    2) If no zombies are found, a check is made to see if
   722                              <1> 	;	there are any children at all. If there are none,
   723                              <1> 	;	an error return is made. If there are, the parent's
   724                              <1> 	;	status is set to 2 (waiting for child to die),
   725                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
   726                              <1> 	;	is made to wait on the next process.
   727                              <1> 	;
   728                              <1> 	; Calling sequence:
   729                              <1> 	;	?
   730                              <1> 	; Arguments:
   731                              <1> 	;	-
   732                              <1> 	; Inputs: - 
   733                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
   734                              <1> 	; ...............................................................
   735                              <1> 	;				
   736                              <1> 	
   737                              <1> ; / wait for a process to die
   738                              <1> 
   739                              <1> syswait_0:
   740 0000A2F8 0FB61D[CFE30000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   741                              <1> 		; movb u.uno,r1 / put parents process number in r1
   742 0000A2FF D0E3                <1> 	shl	bl, 1
   743                              <1> 	;shl	bx, 1
   744                              <1> 		; asl r1 / x2 to get index into p.pid table
   745 0000A301 668B83[60E00000]    <1> 	mov	ax, [ebx+p.pid-2]
   746                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   747 0000A308 31F6                <1> 	xor	esi, esi
   748                              <1> 		; clr r2
   749 0000A30A 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
   750                              <1> 	;xor 	cl, cl
   751                              <1> 		; clr r3 / initialize reg 3
   752                              <1> syswait_1: ; 1:
   753 0000A30C 6683C602            <1> 	add	si, 2
   754                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
   755                              <1> 			  ; / search table of parent processes 
   756                              <1> 			  ; / for this process name
   757 0000A310 663B86[80E00000]    <1> 	cmp	ax, [esi+p.ppid-2]
   758                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
   759                              <1> 			            ; / process number
   760 0000A317 7535                <1> 	jne	short syswait_3
   761                              <1> 		;bne 3f / branch if no match of parent process name
   762                              <1> 	;inc	cx
   763 0000A319 FEC1                <1> 	inc	cl
   764                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   765 0000A31B 66D1EE              <1> 	shr	si, 1
   766                              <1> 		; asr r2 / r2/2 to get index to p.stat table
   767                              <1> 	; The possible states ('p.stat' values) of a process are:
   768                              <1> 	;	0 = free or unused
   769                              <1> 	;	1 = active
   770                              <1> 	;	2 = waiting for a child process to die
   771                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
   772 0000A31E 80BE[F1E00000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
   773                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
   774 0000A325 7524                <1> 	jne	short syswait_2
   775                              <1> 		; bne 2f / no, skip it
   776 0000A327 88BE[F1E00000]      <1> 	mov	[esi+p.stat-1], bh ; 0
   777                              <1> 		; clrb p.stat-1(r2) / yes, free it
   778 0000A32D 66D1E6              <1> 	shl	si, 1
   779                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   780 0000A330 0FB786[60E00000]    <1> 	movzx	eax, word [esi+p.pid-2]
   781 0000A337 A3[80E30000]        <1> 	mov	[u.r0], eax
   782                              <1> 		; mov p.pid-2(r2),*u.r0 
   783                              <1> 			      ; / put childs process name in (u.r0)
   784                              <1> 	;
   785                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
   786                              <1> 	;
   787                              <1> 	; Parent process ID -p.ppid- field (of the child process)
   788                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
   789                              <1> 	; system call loop from the application/program if it calls
   790                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
   791                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
   792                              <1> 	;
   793                              <1> 	; Note: syswait will return with error if there is not a
   794                              <1> 	;       zombie or running process to wait.	
   795                              <1> 	;
   796 0000A33C 6629C0              <1> 	sub	ax, ax
   797 0000A33F 668986[80E00000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   798 0000A346 E9DBFDFFFF          <1> 	jmp	sysret0 ; ax = 0
   799                              <1> 	;
   800                              <1> 	;jmp	sysret
   801                              <1> 		; br sysret1 / return cause child is dead
   802                              <1> syswait_2: ; 2:
   803 0000A34B 66D1E6              <1> 	shl	si, 1
   804                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   805                              <1> syswait_3: ; 3:
   806 0000A34E 6683FE20            <1> 	cmp	si, nproc+nproc
   807                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   808 0000A352 72B8                <1> 	jb	short syswait_1
   809                              <1> 		; blt 1b / no, continue search
   810                              <1> 	;and	cx, cx
   811 0000A354 20C9                <1> 	and	cl, cl
   812                              <1> 		; tst r3 / one gets here if there are no children 
   813                              <1> 		       ; / or children that are still active
   814                              <1> 	; 30/10/2013
   815 0000A356 750B                <1> 	jnz	short syswait_4
   816                              <1> 	;jz	error
   817                              <1> 		; beq error1 / there are no children, error
   818 0000A358 890D[80E30000]      <1> 	mov	[u.r0], ecx ; 0
   819 0000A35E E9A0FDFFFF          <1> 	jmp	error
   820                              <1> syswait_4:
   821 0000A363 8A1D[CFE30000]      <1> 	mov	bl, [u.uno]
   822                              <1> 		; movb u.uno,r1 / there are children so put 
   823                              <1> 			      ; / parent process number in r1
   824 0000A369 FE83[F1E00000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
   825                              <1> 		; incb p.stat-1(r1) / it is waiting for 
   826                              <1> 				  ; / other children to die
   827                              <1> 	; 04/11/2013
   828 0000A36F E836180000          <1> 	call	swap
   829                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   830 0000A374 EB82                <1> 	jmp	syswait_0
   831                              <1> 		; br syswait / wait on next process
   832                              <1> 
   833                              <1> sysfork: ; < create a new process >
   834                              <1> 	; 18/09/2015
   835                              <1> 	; 04/09/2015
   836                              <1> 	; 02/09/2015
   837                              <1> 	; 01/09/2015
   838                              <1> 	; 28/08/2015
   839                              <1> 	; 14/05/2015
   840                              <1> 	; 10/05/2015
   841                              <1> 	; 09/05/2015
   842                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
   843                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   844                              <1> 	;
   845                              <1> 	; 'sysfork' creates a new process. This process is referred
   846                              <1> 	; to as the child process. This new process core image is
   847                              <1> 	; a copy of that of the caller of 'sysfork'. The only
   848                              <1> 	; distinction is the return location and the fact that (u.r0)
   849                              <1> 	; in the old process (parent) contains the process id (p.pid)
   850                              <1> 	; of the new process (child). This id is used by 'syswait'.
   851                              <1> 	; 'sysfork' works in the following manner: 	
   852                              <1> 	;    1) The process status table (p.stat) is searched to find
   853                              <1> 	;	a process number that is unused. If none are found
   854                              <1> 	;	an error occurs.
   855                              <1> 	;    2) when one is found, it becomes the child process number
   856                              <1> 	;	and it's status (p.stat) is set to active.
   857                              <1> 	;    3) If the parent had a control tty, the interrupt 
   858                              <1> 	;	character in that tty buffer is cleared.
   859                              <1> 	;    4) The child process is put on the lowest priority run 
   860                              <1> 	;	queue via 'putlu'.
   861                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
   862                              <1> 	;	it is a unique number) and is put in the child's unique
   863                              <1> 	;	identifier; process id (p.pid).
   864                              <1> 	;    6) The process name of the parent is then obtained and
   865                              <1> 	;	placed in the unique identifier of the parent process
   866                              <1> 	;	name is then put in 'u.r0'.	
   867                              <1> 	;    7) The child process is then written out on disk by
   868                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
   869                              <1> 	;	and the child is born. (The child process is written 
   870                              <1> 	;	out on disk/drum with 'u.uno' being the child process
   871                              <1> 	;	number.)
   872                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
   873                              <1> 	;    9) The child process name is put in 'u.r0'.
   874                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
   875                              <1> 	;	create the return address for the parent process.
   876                              <1> 	;   11) The 'u.fp' list as then searched to see what files
   877                              <1> 	;	the parent has opened. For each file the parent has
   878                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
   879                              <1> 	;	to indicate that the child process also has opened
   880                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
   881                              <1> 	;
   882                              <1> 	; Calling sequence:
   883                              <1> 	;	from shell ?
   884                              <1> 	; Arguments:
   885                              <1> 	;	-
   886                              <1> 	; Inputs: -
   887                              <1> 	; Outputs: *u.r0 - child process name
   888                              <1> 	; ...............................................................
   889                              <1> 	;	
   890                              <1> 	; Retro UNIX 8086 v1 modification: 
   891                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
   892                              <1> 	;	= process id of child a parent process returns
   893                              <1> 	;	= process id of parent when a child process returns
   894                              <1> 	;
   895                              <1> 	;       In original UNIX v1, sysfork is called and returns as
   896                              <1> 	;	in following manner: (with an example: c library, fork)
   897                              <1> 	;	
   898                              <1> 	;	1:
   899                              <1> 	;		sys	fork
   900                              <1> 	;			br 1f  / child process returns here
   901                              <1> 	;		bes	2f     / parent process returns here
   902                              <1> 	;		/ pid of new process in r0
   903                              <1> 	;		rts	pc
   904                              <1> 	;	2: / parent process condionally branches here
   905                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
   906                              <1> 	;		rts	pc
   907                              <1> 	;
   908                              <1> 	;	1: / child process brances here
   909                              <1> 	;		clr	r0   / pid = 0 in child process
   910                              <1> 	;		rts	pc
   911                              <1> 	;
   912                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
   913                              <1> 	;		// pid = fork();
   914                              <1> 	;		//
   915                              <1> 	;		// pid == 0 in child process; 
   916                              <1> 	;		// pid == -1 means error return
   917                              <1> 	;		// in child, 
   918                              <1> 	;		//	parents id is in par_uid if needed
   919                              <1> 	;		
   920                              <1> 	;		_fork:
   921                              <1> 	;			mov	$.fork,eax
   922                              <1> 	;			int	$0x30
   923                              <1> 	;			jmp	1f
   924                              <1> 	;			jnc	2f
   925                              <1> 	;			jmp	cerror
   926                              <1> 	;		1:
   927                              <1> 	;			mov	eax,_par_uid
   928                              <1> 	;			xor	eax,eax
   929                              <1> 	;		2:
   930                              <1> 	;			ret
   931                              <1> 	;
   932                              <1> 	;	In Retro UNIX 8086 v1,
   933                              <1> 	;	'sysfork' returns in following manner:
   934                              <1> 	;	
   935                              <1> 	;		mov	ax, sys_fork
   936                              <1> 	;		mov	bx, offset @f ; routine for child
   937                              <1> 	;		int	20h
   938                              <1> 	;		jc	error
   939                              <1> 	;		
   940                              <1> 	;	; Routine for parent process here (just after 'jc')
   941                              <1> 	;		mov	word ptr [pid_of_child], ax
   942                              <1> 	;		jmp	next_routine_for_parent	
   943                              <1> 	;
   944                              <1> 	;	@@: ; routine for child process here				
   945                              <1> 	;		....	
   946                              <1> 	;	NOTE: 'sysfork' returns to specified offset
   947                              <1> 	;	       for child process by using BX input.
   948                              <1> 	;	      (at first, parent process will return then 
   949                              <1> 	;	      child process will return -after swapped in-
   950                              <1> 	;	      'syswait' is needed in parent process
   951                              <1> 	;	      if return from child process will be waited for.)
   952                              <1> 	;	  				
   953                              <1> 	
   954                              <1> ; / create a new process
   955                              <1> 	; EBX = return address for child process 
   956                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
   957 0000A376 31F6                <1> 	xor 	esi, esi
   958                              <1> 		; clr r1
   959                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
   960 0000A378 46                  <1> 	inc	esi
   961                              <1> 		; inc r1
   962 0000A379 80BE[F1E00000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
   963                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
   964 0000A380 760B                <1> 	jna	short sysfork_2	
   965                              <1> 		; beq 1f / it's unused so branch
   966 0000A382 6683FE10            <1> 	cmp	si, nproc
   967                              <1> 		; cmp r1,$nproc / all processes checked
   968 0000A386 72F0                <1> 	jb	short sysfork_1
   969                              <1> 		; blt 1b / no, branch back
   970                              <1> 	;
   971                              <1> 	; Retro UNIX 8086 v1. modification:
   972                              <1> 	;	Parent process returns from 'sysfork' to address 
   973                              <1> 	;	which is just after 'sysfork' system call in parent
   974                              <1> 	;	process. Child process returns to address which is put
   975                              <1> 	;	in BX register by parent process for 'sysfork'. 
   976                              <1> 	;
   977                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
   978                              <1> 		             ; / to old process return
   979                              <1> 		; br error1 / no room for a new process
   980 0000A388 E976FDFFFF          <1> 	jmp	error
   981                              <1> sysfork_2: ; 1:
   982 0000A38D E8048EFFFF          <1> 	call	allocate_page
   983 0000A392 0F826BFDFFFF        <1> 	jc	error
   984 0000A398 50                  <1> 	push	eax   ; UPAGE (user structure page) address
   985                              <1> 	; Retro UNIX 386 v1 modification!
   986 0000A399 E80190FFFF          <1> 	call	duplicate_page_dir
   987                              <1> 		; EAX = New page directory 
   988 0000A39E 730B                <1> 	jnc	short sysfork_3
   989 0000A3A0 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
   990 0000A3A1 E8C88FFFFF          <1> 	call 	deallocate_page
   991 0000A3A6 E958FDFFFF          <1> 	jmp	error
   992                              <1> sysfork_3:
   993                              <1> 	; Retro UNIX 386 v1 modification !
   994 0000A3AB 56                  <1> 	push	esi
   995 0000A3AC E887180000          <1> 	call	wswap ; save current user (u) structure, user registers
   996                              <1> 		      ; and interrupt return components (for IRET)
   997 0000A3B1 8705[D9E30000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
   998 0000A3B7 A3[DDE30000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
   999 0000A3BC 5E                  <1> 	pop	esi
  1000 0000A3BD 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1001                              <1> 		; [u.usp] = esp
  1002 0000A3BE 89F7                <1> 	mov	edi, esi
  1003 0000A3C0 66C1E702            <1> 	shl	di, 2
  1004 0000A3C4 8987[FEE00000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  1005 0000A3CA A3[D0E30000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  1006                              <1> 	; 28/08/2015
  1007 0000A3CF 0FB605[CFE30000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  1008                              <1> 		; movb u.uno,-(sp) / save parent process number
  1009 0000A3D6 89C7                <1> 	mov	edi, eax
  1010 0000A3D8 50                  <1>         push	eax ; ** 
  1011 0000A3D9 8A87[C1E00000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
  1012                              <1> 	; 18/09/2015
  1013                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
  1014                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
  1015 0000A3DF 668986[C1E00000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  1016                              <1> 				   ; ah - reset child's wait channel	
  1017 0000A3E6 89F0                <1> 	mov	eax, esi
  1018 0000A3E8 A2[CFE30000]        <1> 	mov	[u.uno], al ; child process number
  1019                              <1> 		;movb r1,u.uno / set child process number to r1
  1020 0000A3ED FE86[F1E00000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
  1021                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
  1022                              <1> 				; / process to active status
  1023                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
  1024                              <1> 			      ; / control tty buffer in r2
  1025                              <1>                 ; beq 2f / branch, if no such tty assigned
  1026                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
  1027                              <1> 	; 2:
  1028 0000A3F3 53                  <1> 	push	ebx  ; * return address for the child process
  1029                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1030                              <1> 	; (Retro UNIX 8086 v1 modification!)
  1031                              <1> 		; mov $runq+4,r2
  1032 0000A3F4 E8A1180000          <1> 	call	putlu 
  1033                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  1034                              <1> 			   ; / run queue
  1035 0000A3F9 66D1E6              <1> 	shl	si, 1
  1036                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  1037                              <1> 		       ; / into p.pid table
  1038 0000A3FC 66FF05[68E30000]    <1> 	inc	word [mpid]
  1039                              <1> 		; inc mpid / increment m.pid; get a new process name
  1040 0000A403 66A1[68E30000]      <1> 	mov	ax, [mpid]
  1041 0000A409 668986[60E00000]    <1> 	mov	[esi+p.pid-2], ax
  1042                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
  1043                              <1> 				    ; / in child process' name slot
  1044 0000A410 5A                  <1> 	pop	edx  ; * return address for the child process
  1045                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1046 0000A411 5B                  <1>   	pop	ebx  ; **
  1047                              <1> 	;mov	ebx, [esp] ; ** parent process number
  1048                              <1> 		; movb (sp),r2 / put parent process number in r2
  1049 0000A412 66D1E3              <1> 	shl 	bx, 1
  1050                              <1> 		;asl r2 / multiply by 2 to get index into below tables
  1051                              <1> 	;movzx eax, word [ebx+p.pid-2]
  1052 0000A415 668B83[60E00000]    <1> 	mov	ax, [ebx+p.pid-2]
  1053                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  1054                              <1> 				   ; / process
  1055 0000A41C 668986[80E00000]    <1> 	mov	[esi+p.ppid-2], ax
  1056                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  1057                              <1> 			  ; / in parent process slot for child
  1058 0000A423 A3[80E30000]        <1> 	mov	[u.r0], eax	
  1059                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  1060                              <1> 			     ; / at location where r0 was saved
  1061 0000A428 8B2D[78E30000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1062 0000A42E 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  1063                              <1> 			   ; * return address for the child process
  1064                              <1> 		; mov $sysret1,-(sp) /
  1065                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  1066                              <1> 			      ; / user is swapped out
  1067                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  1068                              <1> 	; 04/09/2015 - 01/09/2015
  1069                              <1> 	; [u.usp] = esp
  1070 0000A431 68[23A10000]        <1> 	push	sysret ; ***
  1071 0000A436 8925[7CE30000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1072                              <1> 			     ; (for child process)	
  1073 0000A43C 31C0                <1> 	xor 	eax, eax
  1074 0000A43E 66A3[B0E30000]      <1> 	mov 	[u.ttyp], ax ; 0
  1075                              <1> 	;
  1076 0000A444 E8EF170000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  1077                              <1> 		;jsr r0,wswap / put child process out on drum
  1078                              <1> 		;jsr r0,unpack / unpack user stack
  1079                              <1> 		;mov u.usp,sp / restore user stack pointer
  1080                              <1> 		; tst (sp)+ / bump stack pointer
  1081                              <1> 	; Retro UNIX 386 v1 modification !
  1082 0000A449 58                  <1> 	pop	eax ; ***
  1083 0000A44A 66D1E3              <1> 	shl	bx, 1
  1084 0000A44D 8B83[FEE00000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1085 0000A453 E809180000          <1> 	call	rswap ; restore parent process 'u' structure, 
  1086                              <1> 		      ; registers and return address (for IRET)
  1087                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  1088 0000A458 0FB705[68E30000]    <1>         movzx   eax, word [mpid]
  1089 0000A45F A3[80E30000]        <1> 	mov	[u.r0], eax
  1090                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  1091                              <1> 			       ; / where r0 was saved
  1092                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  1093                              <1> 			          ; / process return
  1094                              <1> 	;xor	ebx, ebx
  1095 0000A464 31F6                <1> 	xor     esi, esi
  1096                              <1> 		;clr r1
  1097                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  1098                              <1> 	      ; / opened by the parent process
  1099                              <1> 	; 01/09/2015
  1100                              <1> 	;xor	bh, bh
  1101                              <1> 	;mov 	bl, [esi+u.fp]
  1102 0000A466 8A86[86E30000]      <1> 	mov 	al, [esi+u.fp]
  1103                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  1104                              <1>         ;or      bl, bl
  1105 0000A46C 08C0                <1> 	or	al, al
  1106 0000A46E 740D                <1> 	jz	short sysfork_5	
  1107                              <1> 		; beq 2f / file has not been opened by parent, 
  1108                              <1> 		       ; / so branch
  1109 0000A470 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1110 0000A472 F6E4                <1> 	mul	ah
  1111                              <1> 	;movzx	ebx, ax
  1112 0000A474 6689C3              <1> 	mov	bx, ax
  1113                              <1> 	;shl     bx, 3
  1114                              <1> 		; asl r2 / multiply by 8
  1115                              <1>        		; asl r2 / to get index into fsp table
  1116                              <1>        		; asl r2
  1117 0000A477 FE83[50E10000]      <1>   	inc     byte [ebx+fsp-2]
  1118                              <1> 		; incb fsp-2(r2) / increment number of processes
  1119                              <1> 			     ; / using file, because child will now be
  1120                              <1> 			     ; / using this file
  1121                              <1> sysfork_5: ; 2:
  1122 0000A47D 46                  <1>         inc     esi
  1123                              <1> 		; inc r1 / get next open file
  1124 0000A47E 6683FE0A            <1>         cmp     si, 10
  1125                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1126                              <1> 			  ; / can be opened
  1127 0000A482 72E2                <1> 	jb	short sysfork_4	
  1128                              <1> 		; blt 1b / check next entry
  1129 0000A484 E99AFCFFFF          <1> 	jmp	sysret
  1130                              <1> 		; br sysret1
  1131                              <1> 
  1132                              <1> sysread: ; < read from file >
  1133                              <1> 	; 13/05/2015
  1134                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1135                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1136                              <1> 	;
  1137                              <1> 	; 'sysread' is given a buffer to read into and the number of
  1138                              <1> 	; characters to be read. If finds the file from the file
  1139                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  1140                              <1> 	; is returned from a successful open call (sysopen).
  1141                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  1142                              <1> 	; is read into core via 'readi'.
  1143                              <1> 	;
  1144                              <1> 	; Calling sequence:
  1145                              <1> 	;	sysread; buffer; nchars
  1146                              <1> 	; Arguments:
  1147                              <1> 	;	buffer - location of contiguous bytes where 
  1148                              <1> 	;		 input will be placed.
  1149                              <1> 	;	nchars - number of bytes or characters to be read.
  1150                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1151                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  1152                              <1> 	; ...............................................................
  1153                              <1> 	;				
  1154                              <1> 	; Retro UNIX 8086 v1 modification: 
  1155                              <1> 	;       'sysread' system call has three arguments; so,
  1156                              <1> 	;	* 1st argument, file descriptor is in BX register
  1157                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1158                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1159                              <1> 	;
  1160                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1161                              <1> 	;	to the user with number of bytes read. 
  1162                              <1> 	;
  1163 0000A489 E83D000000          <1> 	call	rw1
  1164 0000A48E 0F826FFCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1165                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
  1166 0000A494 F6C480              <1> 	test	ah, 80h
  1167                              <1> 		; tst r1 / negative i-number?
  1168 0000A497 0F8566FCFFFF        <1> 	jnz	error
  1169                              <1> 		; ble error1 / yes, error 1 to read
  1170                              <1> 			   ; / it should be positive
  1171 0000A49D E813140000          <1> 	call	readi
  1172                              <1> 		; jsr r0,readi / read data into core
  1173 0000A4A2 EB18                <1> 	jmp	short rw0
  1174                              <1> 		; br 1f
  1175                              <1> syswrite: ; < write to file >
  1176                              <1> 	; 13/05/2015
  1177                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1178                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1179                              <1> 	;
  1180                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  1181                              <1> 	; and the number of characters to write. If finds the file
  1182                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  1183                              <1> 	; descriptor is returned from a successful open or create call
  1184                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  1185                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  1186                              <1> 	;
  1187                              <1> 	; Calling sequence:
  1188                              <1> 	;	syswrite; buffer; nchars
  1189                              <1> 	; Arguments:
  1190                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  1191                              <1> 	;	nchars - number of characters to be written.
  1192                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1193                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  1194                              <1> 	; ...............................................................
  1195                              <1> 	;				
  1196                              <1> 	; Retro UNIX 8086 v1 modification: 
  1197                              <1> 	;       'syswrite' system call has three arguments; so,
  1198                              <1> 	;	* 1st argument, file descriptor is in BX register
  1199                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1200                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1201                              <1> 	;
  1202                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1203                              <1> 	;	to the user with number of bytes written. 
  1204                              <1> 	;
  1205 0000A4A4 E822000000          <1> 	call	rw1
  1206 0000A4A9 0F8254FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1207                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
  1208 0000A4AF F6C480              <1>         test	ah, 80h
  1209                              <1> 		; tst r1 / positive i-number ?
  1210 0000A4B2 744E                <1>         jz	short rw3 ; 13/05/2015
  1211                              <1> 	;jz	error
  1212                              <1> 		; bge error1 / yes, error 1 
  1213                              <1> 			   ; / negative i-number means write
  1214 0000A4B4 66F7D8              <1>         neg	ax
  1215                              <1> 		; neg r1 / make it positive
  1216 0000A4B7 E852190000          <1> 	call	writei
  1217                              <1>         	; jsr r0,writei / write data
  1218                              <1> rw0: ; 1:
  1219 0000A4BC A1[A8E30000]        <1>         mov	eax, [u.nread]
  1220 0000A4C1 A3[80E30000]        <1> 	mov	[u.r0], eax
  1221                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  1222                              <1> 				  ; / into (u.r0)
  1223 0000A4C6 E958FCFFFF          <1> 	jmp	sysret
  1224                              <1>         	; br sysret1
  1225                              <1> rw1:	
  1226                              <1> 	; 14/05/2015
  1227                              <1> 	; 13/05/2015
  1228                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1229                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  1230                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
  1231                              <1> 	;
  1232                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
  1233                              <1> 				;(in the user's virtual memory space)
  1234                              <1> 	;mov	[u.count], edx 
  1235                              <1> 		; jsr r0,arg; u.base / get buffer pointer
  1236                              <1>         	; jsr r0,arg; u.count / get no. of characters
  1237                              <1> 	;;mov	eax, ebx ; file descriptor
  1238                              <1> 		; mov *u.r0,r1 / put file descriptor 
  1239                              <1> 		             ; / (index to u.fp table) in r1
  1240                              <1> 	; 13/05/2015
  1241 0000A4CB C705[80E30000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  1241 0000A4D3 0000                <1>
  1242                              <1> 	;
  1243                              <1> 	;; call	getf
  1244                              <1>         ; eBX = File descriptor
  1245 0000A4D5 E8EE090000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
  1246                              <1> 		; jsr r0,getf / get i-number of the file in r1
  1247                              <1> 	; AX = I-number of the file ; negative i-number means write
  1248                              <1> 	; 13/05/2015
  1249 0000A4DA 6683F801            <1> 	cmp 	ax, 1
  1250 0000A4DE 7217                <1> 	jb	short rw2
  1251                              <1> 	;
  1252 0000A4E0 890D[A0E30000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  1253                              <1> 				;(in the user's virtual memory space)
  1254 0000A4E6 8915[A4E30000]      <1> 	mov	[u.count], edx 
  1255                              <1> 	; 14/05/2015
  1256 0000A4EC C705[D5E30000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  1256 0000A4F4 0000                <1>
  1257 0000A4F6 C3                  <1> 	retn
  1258                              <1>         	; rts r0
  1259                              <1> rw2:
  1260                              <1> 	; 13/05/2015
  1261 0000A4F7 C705[D5E30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1261 0000A4FF 0000                <1>
  1262 0000A501 C3                  <1> 	retn
  1263                              <1> rw3: 
  1264                              <1> 	; 13/05/2015
  1265 0000A502 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1265 0000A50A 0000                <1>
  1266 0000A50C F9                  <1> 	stc
  1267 0000A50D C3                  <1> 	retn
  1268                              <1> 
  1269                              <1> sysopen: ;<open file>
  1270                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1271                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  1272                              <1> 	;
  1273                              <1> 	; 'sysopen' opens a file in following manner:
  1274                              <1> 	;    1) The second argument in a sysopen says whether to
  1275                              <1> 	;	open the file ro read (0) or write (>0).
  1276                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  1277                              <1> 	;    3) The file is opened by 'iopen'.
  1278                              <1> 	;    4) Next housekeeping is performed on the fsp table
  1279                              <1> 	;	and the user's open file list - u.fp.
  1280                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  1281                              <1> 	;	b) An entry for the file is created in the fsp table.
  1282                              <1> 	;	c) The number of this entry is put on u.fp list.
  1283                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  1284                              <1> 	;	   to by u.r0.
  1285                              <1> 	;
  1286                              <1> 	; Calling sequence:
  1287                              <1> 	;	sysopen; name; mode
  1288                              <1> 	; Arguments:
  1289                              <1> 	;	name - file name or path name
  1290                              <1> 	;	mode - 0 to open for reading
  1291                              <1> 	;	       1 to open for writing
  1292                              <1> 	; Inputs: (arguments)
  1293                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  1294                              <1> 	;		  is put into r0's location on the stack.	
  1295                              <1> 	; ...............................................................
  1296                              <1> 	;				
  1297                              <1> 	; Retro UNIX 8086 v1 modification: 
  1298                              <1> 	;       'sysopen' system call has two arguments; so,
  1299                              <1> 	;	* 1st argument, name is pointed to by BX register
  1300                              <1> 	;	* 2nd argument, mode is in CX register
  1301                              <1> 	;
  1302                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1303                              <1> 	;	to the user with the file descriptor/number 
  1304                              <1> 	;	(index to u.fp list).
  1305                              <1> 	;
  1306                              <1> 	;call	arg2
  1307                              <1> 	; * name - 'u.namep' points to address of file/path name
  1308                              <1> 	;          in the user's program segment ('u.segmnt')
  1309                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1310                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1311                              <1> 	;          which is on top of stack.
  1312                              <1> 	;
  1313                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  1314                              <1> 	;
  1315                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  1316                              <1> 
  1317 0000A50E 891D[98E30000]      <1> 	mov	[u.namep], ebx
  1318 0000A514 6651                <1> 	push	cx
  1319 0000A516 E8E4090000          <1> 	call	namei
  1320                              <1> 		; jsr r0,namei / i-number of file in r1
  1321                              <1>      	;and	ax, ax
  1322                              <1> 	;jz	error ; File not found
  1323 0000A51B 723B                <1> 	jc	short fnotfound ; 14/05/2015
  1324                              <1> 	;jc	error ; 27/05/2013
  1325                              <1> 		; br  error2 / file not found
  1326 0000A51D 665A                <1>    	pop	dx ; mode
  1327 0000A51F 6652                <1> 	push	dx
  1328                              <1> 	;or	dx, dx
  1329 0000A521 08D2                <1> 	or	dl, dl
  1330                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
  1331                              <1> 		         ; / 0 means, open for read)
  1332 0000A523 7403                <1> 	jz	short sysopen_0
  1333                              <1> 		; beq 1f / yes, leave i-number positive
  1334                              <1> syscreat_0: ; 27/12/2015
  1335 0000A525 66F7D8              <1> 	neg	ax
  1336                              <1>         	; neg r1 / open for writing so make i-number negative
  1337                              <1> sysopen_0: ;1:
  1338 0000A528 E8E2180000          <1> 	call	iopen
  1339                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
  1340 0000A52D 665A                <1> 	pop	dx
  1341                              <1> 	;and	dx, dx
  1342 0000A52F 20D2                <1> 	and	dl, dl
  1343                              <1>         	; tst (sp)+ / pop the stack and test the mode
  1344 0000A531 7403                <1> 	jz	short sysopen_2
  1345                              <1>         	; beq op1 / is open for read op1
  1346                              <1> sysopen_1: ;op0:
  1347 0000A533 66F7D8              <1> 	neg	ax
  1348                              <1>         	; neg r1 
  1349                              <1> 		     ;/ make i-number positive if open for writing [???]
  1350                              <1> 	;; NOTE: iopen always make i-number positive.
  1351                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
  1352                              <1> sysopen_2: ;op1:
  1353 0000A536 31F6                <1>         xor     esi, esi
  1354                              <1>         	; clr r2 / clear registers
  1355 0000A538 31DB                <1>         xor     ebx, ebx
  1356                              <1> 		; clr r3
  1357                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  1358 0000A53A 389E[86E30000]      <1>         cmp     [esi+u.fp], bl ; 0
  1359                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  1360 0000A540 7625                <1>         jna      short sysopen_4
  1361                              <1> 		; beq 1f / if byte in list is 0 branch
  1362 0000A542 46                  <1>         inc     esi
  1363                              <1> 		; inc r2 / bump r2 so next byte can be checked
  1364 0000A543 6683FE0A            <1>         cmp     si, 10
  1365                              <1> 		; cmp r2,$10. / reached end of list?
  1366 0000A547 72F1                <1> 	jb	short sysopen_3
  1367                              <1> 		; blt 1b / no, go back
  1368                              <1> toomanyf:
  1369                              <1> 	; 14/05/2015
  1370 0000A549 C705[D5E30000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  1370 0000A551 0000                <1>
  1371 0000A553 E9ABFBFFFF          <1> 	jmp	error
  1372                              <1>         	; br error2 / yes, error (no files open)
  1373                              <1> fnotfound: 
  1374                              <1> 	; 14/05/2015
  1375 0000A558 C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  1375 0000A560 0000                <1>
  1376 0000A562 E99CFBFFFF          <1> 	jmp	error
  1377                              <1> 
  1378                              <1> sysopen_4: ; 1:
  1379 0000A567 6683BB[52E10000]00  <1>         cmp     word [ebx+fsp], 0
  1380                              <1> 		; tst fsp(r3) / scan fsp entries
  1381 0000A56F 7610                <1>         jna     short sysopen_5
  1382                              <1> 		; beq 1f / if 0 branch
  1383                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
  1384 0000A571 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
  1385                              <1> 		; add $8.,r3 / add 8 to r3 
  1386                              <1> 			; / to bump it to next entry mfsp table
  1387 0000A575 6681FBF401          <1>         cmp     bx, nfiles*10
  1388                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  1389 0000A57A 72EB                <1> 	jb	short sysopen_4
  1390                              <1>        		; blt 1b / no, back
  1391 0000A57C E982FBFFFF          <1> 	jmp	error
  1392                              <1>         	; br error2 / yes, error
  1393                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
  1394 0000A581 668983[52E10000]    <1>         mov     [ebx+fsp], ax
  1395                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
  1396                              <1> 			; / into next available entry in fsp table,
  1397 0000A588 668B3D[60E30000]    <1> 	mov	di, [cdev] ; word ? byte ?
  1398 0000A58F 6689BB[54E10000]    <1>         mov     [ebx+fsp+2], di ; device number
  1399                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
  1400 0000A596 31FF                <1>         xor	edi, edi
  1401 0000A598 89BB[56E10000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
  1402                              <1> 		; clr fsp+4(r3)
  1403 0000A59E 6689BB[5AE10000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
  1404                              <1>        		; clr fsp+6(r3) / clear the next two words
  1405 0000A5A5 89D8                <1>   	mov	eax, ebx
  1406 0000A5A7 B30A                <1> 	mov	bl, 10
  1407 0000A5A9 F6F3                <1> 	div	bl 
  1408                              <1> 		; asr r3
  1409                              <1> 		; asr r3 / divide by 8 
  1410                              <1> 		; asr r3 ; / to get number of the fsp entry-1
  1411 0000A5AB FEC0                <1> 	inc	al
  1412                              <1>         	; inc r3 / add 1 to get fsp entry number
  1413 0000A5AD 8886[86E30000]      <1>         mov     [esi+u.fp], al
  1414                              <1> 		; movb r3,u.fp(r2) / move entry number into 
  1415                              <1> 			; / next available slot in u.fp list
  1416 0000A5B3 8935[80E30000]      <1>         mov     [u.r0], esi
  1417                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
  1418                              <1> 			     ; / into r0 loc on stack
  1419 0000A5B9 E965FBFFFF          <1>         jmp	sysret
  1420                              <1> 		; br sysret2
  1421                              <1> 
  1422                              <1> 	;
  1423                              <1> 	; 'fsp' table (10 bytes/entry)
  1424                              <1> 	; bit 15				   bit 0
  1425                              <1> 	; ---|-------------------------------------------
  1426                              <1> 	; r/w|		i-number of open file
  1427                              <1> 	; ---|-------------------------------------------
  1428                              <1> 	;		   device number
  1429                              <1> 	; -----------------------------------------------
  1430                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  1431                              <1> 	; -----------------------------------------------
  1432                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  1433                              <1> 	; ----------------------|------------------------
  1434                              <1> 	;  flag that says file 	| number of processes
  1435                              <1> 	;   has been deleted	| that have file open 
  1436                              <1> 	; ----------------------|------------------------
  1437                              <1> 	;
  1438                              <1> 
  1439                              <1> syscreat: ; < create file >
  1440                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  1441                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1442                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  1443                              <1> 	;
  1444                              <1> 	; 'syscreat' called with two arguments; name and mode.
  1445                              <1> 	; u.namep points to name of the file and mode is put
  1446                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  1447                              <1> 	; If the file aready exists, it's mode and owner remain 
  1448                              <1> 	; unchanged, but it is truncated to zero length. If the file
  1449                              <1> 	; did not exist, an i-node is created with the new mode via
  1450                              <1> 	; 'maknod' whether or not the file already existed, it is
  1451                              <1> 	; open for writing. The fsp table is then searched for a free
  1452                              <1> 	; entry. When a free entry is found, proper data is placed
  1453                              <1> 	; in it and the number of this entry is put in the u.fp list.
  1454                              <1> 	; The index to the u.fp (also know as the file descriptor)
  1455                              <1> 	; is put in the user's r0. 			
  1456                              <1> 	;
  1457                              <1> 	; Calling sequence:
  1458                              <1> 	;	syscreate; name; mode
  1459                              <1> 	; Arguments:
  1460                              <1> 	;	name - name of the file to be created
  1461                              <1> 	;	mode - mode of the file to be created
  1462                              <1> 	; Inputs: (arguments)
  1463                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  1464                              <1> 	;		   (the file descriptor of new file)
  1465                              <1> 	; ...............................................................
  1466                              <1> 	;				
  1467                              <1> 	; Retro UNIX 8086 v1 modification: 
  1468                              <1> 	;       'syscreate' system call has two arguments; so,
  1469                              <1> 	;	* 1st argument, name is pointed to by BX register
  1470                              <1> 	;	* 2nd argument, mode is in CX register
  1471                              <1> 	;
  1472                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1473                              <1> 	;	to the user with the file descriptor/number 
  1474                              <1> 	;	(index to u.fp list).
  1475                              <1> 	;
  1476                              <1> 	;call	arg2
  1477                              <1> 	; * name - 'u.namep' points to address of file/path name
  1478                              <1> 	;          in the user's program segment ('u.segmnt')
  1479                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1480                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1481                              <1> 	;          which is on top of stack.
  1482                              <1> 	;
  1483                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
  1484                              <1> 			    ; / on stack
  1485 0000A5BE 891D[98E30000]      <1> 	mov	[u.namep], ebx ; file name address
  1486 0000A5C4 6651                <1> 	push	cx ; mode
  1487 0000A5C6 E834090000          <1> 	call 	namei        	
  1488                              <1> 		; jsr r0,namei / get the i-number
  1489                              <1>         ;and	ax, ax
  1490                              <1> 	;jz	short syscreat_1	       	
  1491 0000A5CB 721E                <1> 	jc	short syscreat_1
  1492                              <1> 		; br  2f / if file doesn't exist 2f
  1493                              <1> 	; 27/12/2015
  1494 0000A5CD 6683F829            <1> 	cmp	ax, 41 ; device inode ?
  1495 0000A5D1 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
  1496                              <1> 	;
  1497 0000A5D7 66F7D8              <1> 	neg 	ax
  1498                              <1>         	; neg r1 / if file already exists make i-number 
  1499                              <1> 		       ; / negative (open for writing)
  1500 0000A5DA E830180000          <1> 	call	iopen
  1501                              <1>         	; jsr r0,iopen /
  1502 0000A5DF E82D180000          <1> 	call	itrunc
  1503                              <1>         	; jsr r0,itrunc / truncate to 0 length
  1504 0000A5E4 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
  1505 0000A5E6 E948FFFFFF          <1>         jmp     sysopen_1
  1506                              <1>         	; br op0
  1507                              <1> syscreat_1: ; 2: / file doesn't exist
  1508 0000A5EB 6658                <1> 	pop	ax
  1509                              <1>         	; mov (sp)+,r1 / put the mode in r1
  1510 0000A5ED 30E4                <1> 	xor	ah, ah	
  1511                              <1>         	; bic $!377,r1 / clear upper byte
  1512 0000A5EF E8DE0B0000          <1> 	call 	maknod
  1513                              <1>         	; jsr r0,maknod / make an i-node for this file
  1514 0000A5F4 66A1[B2E30000]      <1> 	mov	ax, [u.dirbuf]
  1515                              <1>         	; mov u.dirbuf,r1 / put i-number 
  1516                              <1> 			        ; / for this new file in r1
  1517 0000A5FA E934FFFFFF          <1>         jmp     sysopen_1
  1518                              <1>         	; br op0 / open the file
  1519                              <1> 
  1520                              <1> sysmkdir: ; < make directory >
  1521                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1522                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1523                              <1> 	;
  1524                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  1525                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  1526                              <1> 	; The special entries '.' and '..' are not present.
  1527                              <1> 	; Errors are indicated if the directory already exists or		
  1528                              <1> 	; user is not the super user. 
  1529                              <1> 	;
  1530                              <1> 	; Calling sequence:
  1531                              <1> 	;	sysmkdir; name; mode
  1532                              <1> 	; Arguments:
  1533                              <1> 	;	name - points to the name of the directory
  1534                              <1> 	;	mode - mode of the directory
  1535                              <1> 	; Inputs: (arguments)
  1536                              <1> 	; Outputs: -
  1537                              <1> 	;    (sets 'directory' flag to 1; 
  1538                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  1539                              <1> 	; ...............................................................
  1540                              <1> 	;				
  1541                              <1> 	; Retro UNIX 8086 v1 modification: 
  1542                              <1> 	;       'sysmkdir' system call has two arguments; so,
  1543                              <1> 	;	* 1st argument, name is pointed to by BX register
  1544                              <1> 	;	* 2nd argument, mode is in CX register
  1545                              <1> 	;
  1546                              <1> 		
  1547                              <1> ; / make a directory
  1548                              <1> 
  1549                              <1> 	;call	arg2
  1550                              <1> 	; * name - 'u.namep' points to address of file/path name
  1551                              <1> 	;          in the user's program segment ('u.segmnt')
  1552                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1553                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1554                              <1> 	;          which is on top of stack.
  1555                              <1> 
  1556                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
  1557                              <1> 			    ; / on stack
  1558 0000A5FF 891D[98E30000]      <1> 	mov	[u.namep], ebx
  1559 0000A605 6651                <1> 	push	cx ; mode
  1560 0000A607 E8F3080000          <1> 	call	namei
  1561                              <1>         	; jsr r0,namei / get the i-number
  1562                              <1>         	;     br .+4 / if file not found branch around error
  1563                              <1>         ;xor 	ax, ax
  1564                              <1> 	;jnz	error
  1565 0000A60C 731C                <1> 	jnc	short dir_exists ; 14/05/2015
  1566                              <1> 	;jnc	error	
  1567                              <1> 		; br  error2 / directory already exists (error)
  1568 0000A60E 803D[CCE30000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  1569                              <1>         	;tstb u.uid / is user the super user
  1570 0000A615 7622                <1> 	jna	short dir_access_err ; 14/05/2015
  1571                              <1> 	;jna	error
  1572                              <1>         	;bne error2 / no, not allowed
  1573 0000A617 6658                <1> 	pop	ax
  1574                              <1>         	;mov (sp)+,r1 / put the mode in r1
  1575 0000A619 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
  1576                              <1>         	;bic $!317,r1 / all but su and ex
  1577                              <1> 	;or	ax , 4000h ; 1011111111111111b
  1578 0000A61D 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
  1579                              <1>         	;bis $40000,r1 / directory flag
  1580 0000A620 E8AD0B0000          <1> 	call	maknod
  1581                              <1>         	;jsr r0,maknod / make the i-node for the directory
  1582 0000A625 E9F9FAFFFF          <1> 	jmp	sysret
  1583                              <1>         	;br sysret2 /
  1584                              <1> dir_exists:
  1585                              <1> 	; 14/05/2015
  1586 0000A62A C705[D5E30000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
  1586 0000A632 0000                <1>
  1587 0000A634 E9CAFAFFFF          <1> 	jmp	error
  1588                              <1> dir_access_err:
  1589                              <1> 	; 14/05/2015
  1590 0000A639 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  1590 0000A641 0000                <1>
  1591 0000A643 E9BBFAFFFF          <1> 	jmp	error
  1592                              <1> 
  1593                              <1> sysclose: ;<close file>
  1594                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1595                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  1596                              <1> 	;
  1597                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  1598                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  1599                              <1> 	; is put in r1 and 'fclose' is called.
  1600                              <1> 	;
  1601                              <1> 	; Calling sequence:
  1602                              <1> 	;	sysclose
  1603                              <1> 	; Arguments:
  1604                              <1> 	;	-  
  1605                              <1> 	; Inputs: *u.r0 - file descriptor
  1606                              <1> 	; Outputs: -
  1607                              <1> 	; ...............................................................
  1608                              <1> 	;				
  1609                              <1> 	; Retro UNIX 8086 v1 modification:
  1610                              <1> 	;	 The user/application program puts file descriptor
  1611                              <1> 	;        in BX register as 'sysclose' system call argument.
  1612                              <1> 	; 	 (argument transfer method 1)
  1613                              <1> 
  1614                              <1> 	; / close the file
  1615                              <1> 	
  1616 0000A648 89D8                <1> 	mov 	eax, ebx
  1617 0000A64A E82E080000          <1> 	call 	fclose
  1618                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
  1619                              <1> 		; jsr r0,fclose / close the file
  1620                              <1>                	; br error2 / unknown file descriptor
  1621                              <1> 		; br sysret2
  1622                              <1> 	; 14/05/2015
  1623 0000A64F 0F83CEFAFFFF        <1> 	jnc	sysret
  1624 0000A655 C705[D5E30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1624 0000A65D 0000                <1>
  1625 0000A65F E99FFAFFFF          <1> 	jmp	error
  1626                              <1> 
  1627                              <1> sysemt: ; enable (or disable) multi tasking -time sharing-
  1628                              <1> 	;
  1629                              <1> 	; 23/05/2016 - TRDOS 386 (TRDOS v2.0)
  1630                              <1> 	; 14/05/2015 (Retro UNIX 386 v1)
  1631                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  1632                              <1> 	;
  1633                              <1> 	; Retro UNIX 8086 v1 modification: 
  1634                              <1> 	;	'Enable Multi Tasking'  system call instead 
  1635                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  1636                              <1> 	;
  1637                              <1> 	; Retro UNIX 8086 v1 feature only!
  1638                              <1> 	;	Using purpose: Kernel will start without time-out
  1639                              <1> 	;	(internal clock/timer) functionality.
  1640                              <1> 	;	Then etc/init will enable clock/timer for
  1641                              <1> 	;	multi tasking. 
  1642                              <1> 	;
  1643                              <1> 	; INPUT ->
  1644                              <1> 	;	BL = 0 -> disable multi tasking
  1645                              <1> 	;	BL > 1 -> enable multi tasking (time sharing) 
  1646                              <1> 	; OUTPUT ->
  1647                              <1> 	;	none	
  1648                              <1> 	;
  1649                              <1> 	;  Note: Multi tasking is disabled during system
  1650                              <1> 	;	 initialization, it must be enabled by using
  1651                              <1> 	;	 this system call. (Otherwise, running proces 
  1652                              <1> 	;	 will not be changed by another process within
  1653                              <1> 	;	 run time sequence/schedule, if running process
  1654                              <1> 	;	 will not 'release' itself. Only 'wakeup' procedure
  1655                              <1> 	;	 for waiting processes and programmed timer events
  1656                              <1> 	;	 for other processes can change running process 
  1657                              <1> 	;	 while multi tasking is disabled.) ** 23/05/2016 **
  1658                              <1> 
  1659 0000A664 803D[CCE30000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  1660                              <1> 	;ja	error
  1661 0000A66B 0F873BFBFFFF        <1> 	ja	badsys ; 14/05/2015
  1662                              <1> 	;
  1663 0000A671 FA                  <1> 	cli
  1664 0000A672 881D[3AE00000]      <1> 	mov	[multi_tasking], bl ; 0 to disable, >0 to enable
  1665 0000A678 E9A6FAFFFF          <1> 	jmp	sysret
  1666                              <1> 
  1667                              <1> systimer:
  1668                              <1> 	; 10/06/2016
  1669                              <1> 	; 07/06/2016
  1670                              <1> 	; 06/06/2016
  1671                              <1> 	; 21/05/2016
  1672                              <1> 	; 19/05/2016
  1673                              <1> 	; 18/05/2016 - TRDOS 386 (TRDOS v2.0)
  1674                              <1> 	; (TRDOS 386 feature only!)
  1675                              <1> 	;
  1676                              <1> 	; (start or stop timer event(s))	
  1677                              <1> 	;
  1678                              <1> 	; INPUT ->
  1679                              <1> 	;	BL = Signal return byte (response byte)
  1680                              <1> 	;	     (Any requested value between 0 and 255)
  1681                              <1> 	;	     (Kernel will put it at the requested address)    	
  1682                              <1> 	;	BH = Time count unit
  1683                              <1> 	;	     0 = Stop timer event
  1684                              <1> 	;	     1 = 18.2 ticks per second
  1685                              <1> 	;	     2 = 10 milliseconds  		
  1686                              <1> 	;	     3 = 1 second (for real time clock interrupt) 	 
  1687                              <1> 	;	     4 to 255 = undefined
  1688                              <1> 	;	BH = 0 -> Stop timer event
  1689                              <1> 	;	BL = Timer event number (1 to 255) if BH = 0     	
  1690                              <1> 	;	     If BL = 0, all timer events (which are belongs
  1691                              <1> 	;	      to running process) will be stopped 		    
  1692                              <1> 	;	ECX = Time/Tick count (depending on time count unit)
  1693                              <1> 	;	EDX = Signal return (Response) byte address
  1694                              <1> 	;	      (virtual address in user's memory space)
  1695                              <1> 	; OUTPUT ->
  1696                              <1> 	;	AL = Timer event number	(1 to 255) (max. value = 16)
  1697                              <1> 	;	IF BH Input = 0 & CF = 0 & AL = 0 -> 
  1698                              <1> 	;	     timer event(s) has/have been stopped/finished
  1699                              <1> 	;	CF = 1 & AL = 0 -> no timer setting space to set
  1700                              <1> 	;	CF = 1 & AL > 0 -> timer count unit is not usable
  1701                              <1> 	;
  1702                              <1> 	;	NOTE: To modify a time count for a user function,
  1703                              <1> 	;	      at first, current timer event must be stopped
  1704                              <1> 	;	      then a new timer event (which is related with
  1705                              <1> 	;	      same user function) must be started.
  1706                              <1> 	;		
  1707                              <1> 	;	      Signal return (response) byte may be used for 
  1708                              <1> 	;	      several purposes. Kernel will put this value 
  1709                              <1> 	;	      to requested address during timer interrupt,
  1710                              <1> 	;	      program/user can check this value to understand
  1711                              <1> 	;	      which event has been occurred and what is changed.
  1712                              <1> 	;	      (Multi timer events can share same signal address)
  1713                              <1> 	;	
  1714                              <1> 	;	NOTE: If the process is running while the time count
  1715                              <1> 	;	      is reached, kernel will put signal return (response)
  1716                              <1> 	;	      byte value at requested address during timer
  1717                              <1> 	;	      interrupt and the process will continue to run.
  1718                              <1> 	;	      Program/process must call (jump to) it's timer event
  1719                              <1> 	;	      function as required, for checking the timer event
  1720                              <1> 	;	      status via signal return (response) byte address. 
  1721                              <1> 	;
  1722                              <1> 	;	      If the process is not running (waiting or sleeping
  1723                              <1> 	;	      or released) while the time count is reached,
  1724                              <1> 	;	      it is restarted from where it left, to ensure
  1725                              <1> 	;	      proper multi media (video, audio, clock, timer)
  1726                              <1> 	;	      functionality.
  1727                              <1> 	;
  1728                              <1> 	;	      (It is better to use 'syswait' or 'syssleep',
  1729                              <1> 	;	      or 'sysrele' system call just after the timer
  1730                              <1> 	;	      function. Otherwise, timer events may block other
  1731                              <1> 	;	      processes which are not using timer events.)  	 		 			 		 	
  1732                              <1> 	;	     	      		 			
  1733                              <1> 	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  1734                              <1> 	;       Owner:	        resb 1 ; 0 = free
  1735                              <1> 	;		  	       ;>0 = process number (u.uno)
  1736                              <1> 	;	Reserved:	resb 1 ; 0
  1737                              <1> 	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  1738                              <1> 	;		   	       ; 1 = Real Time Clock interrupt 
  1739                              <1> 	;	Response:       resb 1 ; 0 to 255, signal return value
  1740                              <1> 	;	Count Limit:	resd 1 ; count of ticks (total/set)
  1741                              <1> 	;	Current Count: 	resd 1 ; count of ticks (current)
  1742                              <1> 	;	Response Addr:  resd 1 ; response byte (pointer) address
  1743                              <1> 	;
  1744                              <1> 
  1745 0000A67D 80FF02              <1> 	cmp	bh, 2
  1746 0000A680 7445                <1>         je      short systimer_5  ; only 18.2 ticks per second is usable
  1747                              <1> 				  ; 10 milliseconds (100 Hertz) timer 
  1748                              <1> 				  ; will be set later (18/05/2016)
  1749 0000A682 774B                <1>         ja      short systimer_6 
  1750                              <1> 
  1751 0000A684 20FF                <1> 	and	bh, bh
  1752 0000A686 0F8490000000        <1>         jz      systimer_9        ; stop timer event(s)
  1753                              <1> 
  1754                              <1> 	; bh = 1 (timer interrupt, 18.2 Hz, IBM PC/AT ROMBIOS default)
  1755                              <1> 
  1756 0000A68C B00A                <1> 	mov	al, 10 ; (*)
  1757                              <1> 
  1758                              <1> systimer_0:
  1759 0000A68E B710                <1> 	mov	bh, 16
  1760                              <1> 	;
  1761 0000A690 383D[40E00000]      <1> 	cmp	[timer_events], bh ; 16 ; 07/06/2016
  1762 0000A696 7319                <1> 	jnb 	short systimer_3  ; max. 16 timer events
  1763                              <1> 	;
  1764 0000A698 50                  <1> 	push	eax ; (*)
  1765                              <1> 
  1766 0000A699 BF[44F00000]        <1> 	mov	edi, timer_set  ; beginning address of timer events
  1767                              <1> 				; setting space
  1768 0000A69E 30C0                <1> 	xor	al, al ; 0
  1769                              <1> systimer_1:
  1770 0000A6A0 FEC0                <1> 	inc	al
  1771 0000A6A2 803F00              <1> 	cmp	byte [edi], 0 	; is it free space ?
  1772 0000A6A5 7631                <1> 	jna	short systimer_7 ; yes
  1773 0000A6A7 FECF                <1> 	dec	bh
  1774 0000A6A9 7405                <1> 	jz	short systimer_2
  1775 0000A6AB 83C710              <1> 	add	edi, 16
  1776 0000A6AE EBF0                <1> 	jmp	short  systimer_1 ; next event space
  1777                              <1> 
  1778                              <1> systimer_2:
  1779 0000A6B0 58                  <1> 	pop	eax ; (*) discard
  1780                              <1> systimer_3:
  1781 0000A6B1 C605[80E30000]00    <1> 	mov	byte [u.r0], 0
  1782                              <1> systimer_4:
  1783 0000A6B8 C705[D5E30000]1A00- <1>         mov     dword [u.error], ERR_MISC
  1783 0000A6C0 0000                <1>
  1784                              <1>                                 ; one of miscellaneous/other errors
  1785 0000A6C2 E93CFAFFFF          <1> 	jmp	error ; cf -> 1
  1786                              <1> 
  1787                              <1> systimer_5:
  1788 0000A6C7 883D[80E30000]      <1> 	mov	[u.r0], bh ; Time count unit (=2 or >3)
  1789 0000A6CD EBE9                <1> 	jmp	short systimer_4 ; 07/06/2016
  1790                              <1> 
  1791                              <1> systimer_6:
  1792 0000A6CF 80FF03              <1> 	cmp	bh, 3
  1793 0000A6D2 77F3                <1>         ja      short systimer_5  ; undefined time count unit
  1794                              <1> 
  1795                              <1> 	; bh = 3
  1796                              <1> 	; timer event via real time clock interrupt
  1797                              <1> 	; interrupt/update frequency: 1 Hz (1 tick per second)
  1798                              <1> 	
  1799 0000A6D4 B0B6                <1> 	mov	al, 182 ; (*) ; 18.2 * 10
  1800 0000A6D6 EBB6                <1>         jmp     short systimer_0
  1801                              <1> 
  1802                              <1> systimer_7:
  1803 0000A6D8 A2[80E30000]        <1> 	mov	[u.r0], al ; timer event number
  1804                              <1> 	;
  1805                              <1> 	; edi = address of empty timer event area
  1806 0000A6DD A0[CFE30000]        <1> 	mov	al, [u.uno]
  1807 0000A6E2 FA                  <1> 	cli 	; disable interrupts 
  1808 0000A6E3 AA                  <1> 	stosb	; process number
  1809 0000A6E4 D0E0                <1> 	shl	al, 1
  1810 0000A6E6 89C6                <1> 	mov	esi, eax
  1811 0000A6E8 28C0                <1> 	sub	al, al
  1812 0000A6EA AA                  <1> 	stosb 	; reserved (=0)
  1813 0000A6EB B001                <1> 	mov	al, 1 ; this is for real time clock interrupt
  1814 0000A6ED AA                  <1> 	stosb	; interrupt type
  1815 0000A6EE 88D8                <1> 	mov	al, bl ; Signal return (Response) value
  1816 0000A6F0 AA                  <1> 	stosb  ; response byte
  1817 0000A6F1 58                  <1> 	pop	eax ; (*) ; 10 or 182
  1818 0000A6F2 89D3                <1> 	mov	ebx, edx ; virtual address for response/signal byte
  1819 0000A6F4 F7E1                <1> 	mul	ecx
  1820                              <1> 	; (eax = 10 * count of 18.2 Hz timer ticks)
  1821                              <1> 	; (count down step = 10)
  1822 0000A6F6 AB                  <1> 	stosd  ; count limit (reset value)
  1823 0000A6F7 AB                  <1> 	stosd  ; current count value
  1824                              <1> 	; ebx = virtual address
  1825                              <1> 	; [u.pgdir] = page directory's physical address
  1826 0000A6F8 E8AB91FFFF          <1> 	call	get_physical_addr
  1827 0000A6FD 720D                <1> 	jc	short systimer_8 ; 07/06/2016
  1828                              <1> 	; eax = physical address of the virtual address in user's space
  1829 0000A6FF AB                  <1> 	stosd	; response address (physical)
  1830 0000A700 FE05[40E00000]      <1> 	inc	byte [timer_events] ; 07/06/201
  1831 0000A706 FB                  <1> 	sti 	; enable interrupts
  1832 0000A707 E917FAFFFF          <1> 	jmp	sysret
  1833                              <1> 
  1834                              <1> systimer_8:
  1835                              <1> 	; 10/06/2016
  1836                              <1> 	; 07/06/2016
  1837 0000A70C 28C0                <1> 	sub	al, al ; 0
  1838 0000A70E 8847F4              <1> 	mov	[edi-12], al ; clear process nummber (free timer event)
  1839                              <1> 	;mov	dword [edi], eax ; 0
  1840 0000A711 FB                  <1> 	sti
  1841 0000A712 A2[80E30000]        <1> 	mov	[u.r0], al ; 0
  1842 0000A717 E9E7F9FFFF          <1> 	jmp	error
  1843                              <1> 
  1844                              <1> systimer_9:
  1845                              <1> 	; 10/06/2016
  1846                              <1> 	; 07/06/2016
  1847 0000A71C 28C0                <1> 	sub	al, al
  1848 0000A71E A2[80E30000]        <1> 	mov	byte [u.r0], al ; 0
  1849 0000A723 3805[40E00000]      <1> 	cmp     byte [timer_events], al ;  0
  1850 0000A729 7631                <1> 	jna	short systimer_12
  1851                              <1> 
  1852                              <1> 	; Note: ecx and edx are undefined here
  1853                              <1> 	;	(for stop timer function)
  1854                              <1> 
  1855 0000A72B BE[44F00000]        <1> 	mov	esi, timer_set  ; beginning address of timer events
  1856                              <1> 				; setting space	 
  1857 0000A730 A0[CFE30000]        <1> 	mov	al, [u.uno]
  1858                              <1> 	
  1859 0000A735 B710                <1> 	mov	bh, 16
  1860                              <1> 
  1861 0000A737 08DB                <1> 	or	bl, bl
  1862 0000A739 7544                <1> 	jnz	short systimer_15
  1863                              <1> 
  1864                              <1> 	; clear timer event areas belong to current process
  1865                              <1> 	; (for stopping all timer events belong to current process) 
  1866 0000A73B FA                  <1> 	cli 	; disable interrupts
  1867                              <1> systimer_10:
  1868                              <1> 	; 10/06/2016
  1869                              <1> 	; 07/06/2016 	
  1870 0000A73C 8A26                <1> 	mov	ah, [esi]
  1871 0000A73E 08E4                <1> 	or	ah, ah ; 0 ?
  1872 0000A740 7411                <1> 	jz	short systimer_11
  1873 0000A742 38C4                <1> 	cmp	ah, al ; is the process ID (owner) same ?
  1874 0000A744 750D                <1>         jne     short systimer_11 ; no
  1875                              <1> 
  1876                              <1> 	;mov	byte [esi], 0
  1877 0000A746 66C7060000          <1> 	mov	word [esi], 0 ; clear
  1878                              <1> 	;mov	dword [esi+12], 0 ; clear
  1879                              <1> 
  1880 0000A74B FE0D[40E00000]      <1> 	dec	byte [timer_events]
  1881 0000A751 7409                <1> 	jz	short systimer_12
  1882                              <1> 
  1883                              <1> systimer_11:
  1884 0000A753 FECF                <1> 	dec	bh
  1885 0000A755 7405                <1> 	jz	short systimer_12
  1886 0000A757 83C610              <1> 	add	esi, 16
  1887 0000A75A EBE0                <1> 	jmp	short systimer_10
  1888                              <1> 
  1889                              <1> systimer_12:
  1890 0000A75C 0FB635[CFE30000]    <1> 	movzx	esi, byte [u.uno]
  1891 0000A763 08DB                <1> 	or	bl, bl ; all timer events or one timer event ?
  1892 0000A765 740C                <1> 	jz	short systimer_13
  1893 0000A767 8A9E[41E10000]      <1> 	mov	bl, [esi+p.timer-1]
  1894 0000A76D 20DB                <1> 	and	bl, bl	; previous number of timer events for the process
  1895 0000A76F 7408                <1> 	jz	short systimer_14
  1896 0000A771 FECB                <1> 	dec	bl  ; previous number of timer events for the process - 1
  1897                              <1> systimer_13:
  1898 0000A773 889E[41E10000]      <1> 	mov	[esi+p.timer-1], bl ; 0 ; no timer events for process
  1899                              <1> systimer_14:
  1900 0000A779 FB                  <1> 	sti	; enable interrupts
  1901 0000A77A E9A4F9FFFF          <1> 	jmp	sysret
  1902                              <1> 
  1903                              <1> systimer_15:
  1904 0000A77F 38FB                <1> 	cmp	bl, bh ; 16
  1905 0000A781 0F8731FFFFFF        <1>         ja      systimer_4      ; max. 16 timer events !
  1906                              <1> 	;
  1907 0000A787 88DA                <1> 	mov	dl, bl
  1908 0000A789 FECA                <1> 	dec	dl  ; 16 -> 15 ... 1 -> 0 
  1909 0000A78B C0E204              <1> 	shl	dl, 4 ; * 16
  1910 0000A78E 0FB6FA              <1> 	movzx	edi, dl
  1911 0000A791 01F7                <1> 	add	edi, esi ; timer_set 
  1912                              <1> 	
  1913 0000A793 3A07                <1> 	cmp	al, [edi] ; process number
  1914 0000A795 0F851DFFFFFF        <1>         jne     systimer_4
  1915                              <1> 	
  1916                              <1> 	; same process ID
  1917 0000A79B FA                  <1> 	cli	; disable interrupts
  1918                              <1>  	; 10/06/2016
  1919                              <1> 	;mov	byte [esi], 0 
  1920 0000A79C 66C7060000          <1> 	mov	word [esi], 0 ; clear
  1921                              <1> 	;mov	dword [esi+12], 0 ; clear
  1922 0000A7A1 FE0D[40E00000]      <1> 	dec	byte [timer_events]
  1923 0000A7A7 EBB3                <1> 	jmp	short systimer_12
  1924                              <1> 
  1925                              <1> sysmdate: ; < change the modification time of a file >
  1926                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  1927                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1928                              <1> 	;
  1929                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
  1930                              <1> 	; file into core. The user is checked if he is the owner 
  1931                              <1> 	; or super user. If he is neither an error occurs.
  1932                              <1> 	; 'setimod' is then called to set the i-node modification
  1933                              <1> 	; byte and the modification time, but the modification time
  1934                              <1> 	; is overwritten by whatever get put on the stack during
  1935                              <1> 	; a 'systime' system call. This calls are restricted to
  1936                              <1> 	; the super user.		
  1937                              <1> 	;
  1938                              <1> 	; Calling sequence:
  1939                              <1> 	;	sysmdate; name
  1940                              <1> 	; Arguments:
  1941                              <1> 	;	name - points to the name of file
  1942                              <1> 	; Inputs: (arguments)
  1943                              <1> 	; Outputs: -
  1944                              <1> 	; ...............................................................
  1945                              <1> 	;				
  1946                              <1> 	; Retro UNIX 8086 v1 modification: 
  1947                              <1> 	;	 The user/application program puts address 
  1948                              <1> 	;	 of the file name in BX register 
  1949                              <1> 	;	 as 'sysmdate' system call argument.
  1950                              <1> 	;
  1951                              <1> ; / change the modification time of a file
  1952                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
  1953 0000A7A9 891D[98E30000]      <1>         mov	[u.namep], ebx
  1954 0000A7AF E84B070000          <1> 	call	namei
  1955                              <1> 		; jsr r0,namei / get its i-number
  1956 0000A7B4 0F829EFDFFFF        <1>         jc	fnotfound ; file not found !
  1957                              <1> 	;jc	error       
  1958                              <1> 		; br error2 / no, such file
  1959 0000A7BA E84C160000          <1> 	call	iget
  1960                              <1> 		; jsr r0,iget / get i-node into core
  1961 0000A7BF A0[CCE30000]        <1> 	mov	al, [u.uid]
  1962 0000A7C4 3A05[45E00000]      <1> 	cmp	al, [i.uid]
  1963                              <1>         	; cmpb u.uid,i.uid / is user same as owner
  1964 0000A7CA 7413                <1> 	je	short mdate_1
  1965                              <1>         	; beq 1f / yes
  1966 0000A7CC 20C0                <1> 	and	al, al
  1967                              <1> 		; tstb u.uid / no, is user the super user
  1968                              <1> 	;jnz	error
  1969                              <1> 		; bne error2 / no, error
  1970 0000A7CE 740F                <1> 	jz	short mdate_1
  1971 0000A7D0 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1971 0000A7D8 0000                <1>
  1972 0000A7DA E924F9FFFF          <1> 	jmp	error
  1973                              <1> mdate_1: ;1:
  1974 0000A7DF E82E160000          <1> 	call	setimod
  1975                              <1>         	; jsr r0,setimod / fill in modification data,
  1976                              <1> 		               ; / time etc.
  1977 0000A7E4 BE[FCD20000]        <1> 	mov	esi, p_time
  1978 0000A7E9 BF[5CE00000]        <1> 	mov	edi, i.mtim
  1979 0000A7EE A5                  <1> 	movsd
  1980                              <1> 		; mov 4(sp),i.mtim / move present time to
  1981                              <1>         	; mov 2(sp),i.mtim+2 / modification time
  1982 0000A7EF E92FF9FFFF          <1>         jmp	sysret
  1983                              <1> 		; br sysret2
  1984                              <1> 
  1985                              <1> sysvideo: ; VIDEO DATA TRANSFER FUNCTIONS
  1986                              <1> 	; 13/06/2016
  1987                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  1988                              <1> 	;
  1989                              <1> 	; Inputs:
  1990                              <1> 	;	BH = Video mode (0 = VIDEO BIOS Mode 3, tty/text mode)
  1991                              <1> 	;	     BL = 
  1992                              <1> 	;		Bits 0&1, Transfer direction
  1993                              <1> 	;	     	 	0 - System to system
  1994                              <1> 	;			1 - User to system
  1995                              <1> 	;			2 - System to user
  1996                              <1> 	;			3 - User to user
  1997                              <1> 	;		Bits 2&3, Transfer Type
  1998                              <1> 	;			0 - Display page transfer	
  1999                              <1> 	;	     		1 - Display page window transfer
  2000                              <1> 	;	     		2 - Frame/Viewport/Window address transfer
  2001                              <1> 	;			3 - Window handle transfer		
  2002                              <1> 	;
  2003                              <1> 	;	     /// BL = 0 -> System to system (display page) transfer
  2004                              <1> 	;		 CL = Source page 
  2005                              <1> 	;		 DL = Destination page
  2006                              <1> 	;	     /// BL = 1&2 -> user to system & system to user transfer
  2007                              <1> 	;		 ECX = User buffer
  2008                              <1> 	;		 DL = Video page
  2009                              <1> 	;	     /// BL = 5&6 -> user to system, system to user transfer 
  2010                              <1> 	;		(window in current display page and in current mode)	 	 		
  2011                              <1> 	;		 ESI = User's buffer address
  2012                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2013                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2014                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2015                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2016                              <1>         ;                If BL = 5 ->
  2017                              <1> 	;		 EDI = Swap address (in user's memory space)
  2018                              <1> 	;		 (If swap address > 0, previous content of the window
  2019                              <1> 	;		 will be saved into swap area in user's memory space)		
  2020                              <1> 	;	     /// BL = 4 -> system to system transfer 
  2021                              <1> 	;		 ESI = System's source buffer (video page) address
  2022                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2023                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2024                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2025                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2026                              <1> 	;		 EDI = System's destination buffer (video page) address
  2027                              <1> 	;	
  2028                              <1> 	; Outputs:
  2029                              <1> 	;	EAX = transfer/byte count
  2030                              <1> 	;
  2031                              <1> 	;	NOTE: If the source or destination address passes out of
  2032                              <1> 	;	video pages (B8000h to B8000h+32000), data will not be transferred
  2033                              <1> 	;	and EAX will return as 0.
  2034                              <1> 	;	      	 	
  2035                              <1> 
  2036                              <1> 	; 16/05/2016
  2037 0000A7F4 31C0                <1> 	xor	eax, eax
  2038 0000A7F6 A3[80E30000]        <1> 	mov	[u.r0], eax
  2039                              <1> 
  2040 0000A7FB 20FF                <1> 	and	bh, bh
  2041 0000A7FD 0F8520F9FFFF        <1> 	jnz	sysret
  2042                              <1> 	; Video mode 0, 80*25 text mode, CGA 16 colors  ; [CRT_MODE] = 3
  2043 0000A803 88DF                <1> 	mov	bh, bl
  2044 0000A805 C0EF02              <1> 	shr	bh, 2
  2045 0000A808 20FF                <1> 	and	bh, bh
  2046 0000A80A 0F8598000000        <1>         jnz     sysvideo_4
  2047 0000A810 BF00800B00          <1> 	mov	edi, 0B8000h
  2048 0000A815 20D2                <1> 	and	dl, dl
  2049 0000A817 7413                <1> 	jz	short sysvideo_1
  2050 0000A819 80FA07              <1> 	cmp	dl, 7
  2051 0000A81C 0F8701F9FFFF        <1> 	ja	sysret
  2052                              <1> sysvideo_0:
  2053 0000A822 81C7A00F0000        <1> 	add	edi, 80*25*2
  2054 0000A828 FECA                <1> 	dec	dl
  2055 0000A82A 75F6                <1> 	jnz	short sysvideo_0	
  2056                              <1> sysvideo_1:	
  2057 0000A82C 80E303              <1> 	and	bl, 3
  2058 0000A82F 7530                <1> 	jnz	short sysvideo_2
  2059 0000A831 80F907              <1> 	cmp	cl, 7
  2060 0000A834 0F87E9F8FFFF        <1> 	ja	sysret
  2061                              <1> 	; system to system video/display page transfer (mode 0)
  2062 0000A83A BE00800B00          <1> 	mov	esi, 0B8000h
  2063 0000A83F 0FB6C1              <1> 	movzx	eax, cl
  2064 0000A842 BAA00F0000          <1> 	mov	edx, 80*25*2
  2065 0000A847 F7E2                <1> 	mul	edx
  2066 0000A849 01C6                <1> 	add	esi, eax
  2067 0000A84B B9A00F0000          <1> 	mov	ecx, (80*25*2)
  2068 0000A850 890D[80E30000]      <1> 	mov	[u.r0], ecx
  2069 0000A856 66C1E902            <1> 	shr	cx, 2 ; /4
  2070 0000A85A F3A5                <1> 	rep	movsd
  2071 0000A85C E9C2F8FFFF          <1> 	jmp	sysret	
  2072                              <1> sysvideo_2:  
  2073 0000A861 80FB02              <1> 	cmp	bl, 2
  2074 0000A864 0F87B9F8FFFF        <1>         ja      sysret
  2075 0000A86A 721F                <1> 	jb	short sysvideo_3
  2076                              <1> 	; system to user video/display page transfer (mode 0)
  2077 0000A86C 89FE                <1> 	mov	esi, edi
  2078 0000A86E 89CF                <1> 	mov	edi, ecx ; user buffer
  2079 0000A870 B9A00F0000          <1> 	mov	ecx, 80*25*2
  2080 0000A875 E80B150000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2081 0000A87A 0F82A3F8FFFF        <1> 	jc	sysret
  2082 0000A880 890D[80E30000]      <1> 	mov	[u.r0], ecx
  2083 0000A886 E998F8FFFF          <1> 	jmp	sysret 	
  2084                              <1> sysvideo_3: 
  2085                              <1> 	; user to system video/display page transfer (mode 0)	
  2086 0000A88B 89CE                <1> 	mov	esi, ecx ; user buffer
  2087                              <1> 	; edi = video page address
  2088 0000A88D B9A00F0000          <1> 	mov	ecx, 80*25*2
  2089 0000A892 E838150000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2090 0000A897 0F8286F8FFFF        <1> 	jc	sysret
  2091 0000A89D 890D[80E30000]      <1> 	mov	[u.r0], ecx		
  2092 0000A8A3 E97BF8FFFF          <1> 	jmp	sysret
  2093                              <1> sysvideo_4:
  2094 0000A8A8 80E303              <1> 	and	bl, 3
  2095 0000A8AB 0F85F6000000        <1>         jnz     sysvideo_9
  2096 0000A8B1 80F907              <1> 	cmp	cl, 7
  2097 0000A8B4 0F8769F8FFFF        <1> 	ja	sysret
  2098                              <1> 	; system to system video/display page window transfer (mode 0)
  2099 0000A8BA 81FE00800B00        <1> 	cmp	esi, 0B8000h
  2100 0000A8C0 0F825DF8FFFF        <1> 	jb	sysret
  2101 0000A8C6 81FE00FD0B00        <1> 	cmp	esi, 0B8000h+(80*25*2*8)
  2102 0000A8CC 0F8351F8FFFF        <1> 	jnb	sysret
  2103 0000A8D2 81FF00800B00        <1> 	cmp	edi, 0B8000h
  2104 0000A8D8 0F8245F8FFFF        <1> 	jb	sysret
  2105 0000A8DE 81FF00FD0B00        <1>         cmp     edi, 0B8000h+(80*25*2*8)
  2106 0000A8E4 0F8339F8FFFF        <1> 	jnb	sysret
  2107                              <1> 	;
  2108 0000A8EA 51                  <1> 	push	ecx
  2109 0000A8EB 52                  <1> 	push	edx
  2110 0000A8EC 0FB7C1              <1> 	movzx	eax, cx ; top left column
  2111 0000A8EF 50                  <1> 	push	eax
  2112 0000A8F0 C1E910              <1> 	shr	ecx, 16 ; top row
  2113 0000A8F3 66B8A000            <1> 	mov	ax, 80*2 ; 80 colums, 160 bytes per row
  2114 0000A8F7 F7E1                <1> 	mul	ecx
  2115 0000A8F9 01C6                <1> 	add	esi, eax
  2116 0000A8FB 01C7                <1> 	add	edi, eax
  2117 0000A8FD 58                  <1> 	pop	eax
  2118 0000A8FE 66D1E0              <1> 	shl	ax, 1 ; *2 	
  2119 0000A901 01C6                <1> 	add	esi, eax
  2120 0000A903 01C7                <1> 	add	edi, eax
  2121 0000A905 5A                  <1> 	pop	edx
  2122 0000A906 59                  <1> 	pop	ecx
  2123 0000A907 B800FD0B00          <1> 	mov	eax, 0B8000h+(80*25*2*8)
  2124 0000A90C 39C6                <1> 	cmp	esi, eax
  2125 0000A90E 0F830FF8FFFF        <1> 	jnb	sysret
  2126 0000A914 39C6                <1> 	cmp	esi, eax
  2127 0000A916 0F8307F8FFFF        <1> 	jnb	sysret	
  2128                              <1> 
  2129 0000A91C 56                  <1> 	push	esi ; ****
  2130 0000A91D 57                  <1> 	push	edi ; ***
  2131 0000A91E 52                  <1> 	push	edx ; **
  2132 0000A91F 51                  <1> 	push	ecx ; *
  2133 0000A920 C1E910              <1> 	shr	ecx, 16 ; top row
  2134 0000A923 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2135 0000A926 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2136 0000A929 7773                <1> 	ja	short sysvideo_6
  2137 0000A92B 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2138 0000A92E 776E                <1> 	ja	short sysvideo_6		
  2139 0000A930 28CA                <1> 	sub	dl, cl
  2140 0000A932 726A                <1> 	jc	short sysvideo_6
  2141 0000A934 50                  <1> 	push	eax ; *****
  2142 0000A935 89D3                <1> 	mov	ebx, edx ; row count - 1
  2143 0000A937 B8A0000000          <1> 	mov	eax, 80*2
  2144 0000A93C F7E0                <1> 	mul	eax
  2145 0000A93E 01C6                <1> 	add	esi, eax
  2146 0000A940 01C7                <1> 	add	edi, eax
  2147 0000A942 58                  <1> 	pop	eax ; *****
  2148 0000A943 39C6                <1> 	cmp	esi, eax
  2149 0000A945 7757                <1> 	ja	short sysvideo_6
  2150 0000A947 39C7                <1> 	cmp	edi, eax
  2151 0000A949 7753                <1> 	ja	short sysvideo_6
  2152 0000A94B 59                  <1> 	pop	ecx ; *
  2153 0000A94C 5A                  <1> 	pop	edx ; **
  2154 0000A94D 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2155 0000A953 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2156 0000A959 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2157 0000A95C 7742                <1> 	ja	short sysvideo_7
  2158 0000A95E 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2159 0000A961 773D                <1> 	ja	short sysvideo_7
  2160 0000A963 28CA                <1> 	sub	dl, cl
  2161 0000A965 7639                <1> 	jna	short sysvideo_7
  2162                              <1> 	; edx = column count (width) - 1
  2163 0000A967 D0E2                <1> 	shl	dl, 1
  2164 0000A969 01D6                <1> 	add	esi, edx
  2165 0000A96B 01D7                <1> 	add	edi, edx
  2166 0000A96D 39C6                <1> 	cmp	esi, eax
  2167 0000A96F 772F                <1> 	ja	short sysvideo_7
  2168 0000A971 39C7                <1> 	cmp	edi, eax
  2169 0000A973 772B                <1> 	ja	short sysvideo_7
  2170 0000A975 5F                  <1> 	pop	edi ; ***
  2171 0000A976 5E                  <1> 	pop	esi ; ****
  2172 0000A977 FEC3                <1> 	inc	bl
  2173 0000A979 FEC2                <1> 	inc	dl ; column count
  2174 0000A97B 88D7                <1> 	mov	bh, dl
  2175 0000A97D D0E2                <1> 	shl	dl, 1
  2176 0000A97F B8A0000000          <1> 	mov	eax, 80*2
  2177 0000A984 28D0                <1> 	sub	al, dl ; (80 - columns) * 2
  2178                              <1> sysvideo_5:	
  2179 0000A986 88F9                <1> 	mov	cl, bh
  2180 0000A988 0115[80E30000]      <1> 	add	[u.r0], edx
  2181 0000A98E F366A5              <1> 	rep	movsw
  2182 0000A991 01C6                <1> 	add	esi, eax ; next row
  2183 0000A993 01C7                <1> 	add	edi, eax ; next row
  2184 0000A995 FECB                <1> 	dec	bl
  2185 0000A997 75ED                <1> 	jnz	short sysvideo_5
  2186 0000A999 E985F7FFFF          <1> 	jmp	sysret
  2187                              <1> 
  2188                              <1> sysvideo_6:
  2189 0000A99E 59                  <1> 	pop	ecx ; *
  2190 0000A99F 5A                  <1> 	pop	edx ; **
  2191                              <1> sysvideo_7:	
  2192 0000A9A0 5F                  <1> 	pop	edi ; ***
  2193 0000A9A1 5E                  <1> 	pop	esi ; ****
  2194 0000A9A2 E97CF7FFFF          <1> 	jmp	sysret
  2195                              <1> 
  2196                              <1> sysvideo_9:  
  2197 0000A9A7 80FB02              <1> 	cmp	bl, 2
  2198 0000A9AA 0F8773F7FFFF        <1>         ja      sysret
  2199                              <1> 
  2200 0000A9B0 56                  <1> 	push	esi ; ****
  2201 0000A9B1 57                  <1> 	push	edi ; ***
  2202 0000A9B2 52                  <1> 	push	edx ; **
  2203 0000A9B3 51                  <1> 	push	ecx ; *
  2204                              <1> 
  2205 0000A9B4 C1E910              <1> 	shr	ecx, 16 ; top row
  2206 0000A9B7 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2207 0000A9BA 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2208 0000A9BD 77DF                <1> 	ja	short sysvideo_6
  2209 0000A9BF 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2210 0000A9C2 77DA                <1> 	ja	short sysvideo_6		
  2211 0000A9C4 28CA                <1> 	sub	dl, cl
  2212 0000A9C6 72D6                <1> 	jc	short sysvideo_6
  2213                              <1> 
  2214 0000A9C8 88CD                <1> 	mov	ch, cl ; top row
  2215 0000A9CA 8A0D[E6D20000]      <1> 	mov	cl, [ACTIVE_PAGE]
  2216 0000A9D0 BFA00F0000          <1> 	mov	edi, 80*25*2
  2217 0000A9D5 D3E7                <1> 	shl	edi, cl 
  2218 0000A9D7 81C760700B00        <1> 	add	edi, 0B8000h - 80*25*2
  2219                              <1> 
  2220 0000A9DD 88D7                <1> 	mov	bh, dl ; row count - 1
  2221 0000A9DF 88EA                <1> 	mov	dl, ch ; top row
  2222 0000A9E1 B8A0000000          <1> 	mov	eax, 80*2
  2223 0000A9E6 F7E2                <1> 	mul	edx
  2224 0000A9E8 01C7                <1> 	add	edi, eax
  2225                              <1> 
  2226 0000A9EA 59                  <1> 	pop	ecx ; *
  2227 0000A9EB 5A                  <1> 	pop	edx ; **
  2228 0000A9EC 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2229 0000A9F2 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2230 0000A9F8 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2231 0000A9FB 77A3                <1> 	ja	short sysvideo_7
  2232 0000A9FD 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2233 0000AA00 779E                <1> 	ja	short sysvideo_7
  2234                              <1> 	
  2235 0000AA02 28CA                <1> 	sub	dl, cl
  2236 0000AA04 769A                <1> 	jna	short sysvideo_7
  2237                              <1> 	
  2238 0000AA06 0FB6C1              <1> 	movzx	eax, cl ; left column
  2239 0000AA09 D0E0                <1> 	shl	al, 1  ; column * 2
  2240 0000AA0B 01C7                <1> 	add	edi, eax
  2241                              <1> 
  2242 0000AA0D FEC2                <1> 	inc	dl ; column count
  2243 0000AA0F D0E2                <1> 	shl	dl, 1
  2244 0000AA11 88D1                <1> 	mov	cl, dl ; column count * 2
  2245 0000AA13 B2A0                <1> 	mov	dl, 80*2
  2246 0000AA15 58                  <1> 	pop	eax ; *** (swap address)
  2247 0000AA16 5E                  <1> 	pop	esi ; ****
  2248 0000AA17 FEC7                <1> 	inc	bh
  2249                              <1> 	
  2250                              <1> 	;mov	edx, 80*2
  2251 0000AA19 B2A0                <1> 	mov	dl, 80*2
  2252                              <1> 	;
  2253 0000AA1B 80FB01              <1> 	cmp	bl, 1
  2254 0000AA1E 7735                <1> 	ja	short sysvideo_11
  2255                              <1> 
  2256                              <1> 	; user to system video/display page window transfer (mode 0)	
  2257 0000AA20 21C0                <1> 	and	eax, eax ; swap address
  2258 0000AA22 7413                <1> 	jz	short sysvideo_10 ; no window swap
  2259                              <1> 	; save previous window content in user's buffer (swap address)
  2260 0000AA24 56                  <1> 	push	esi ; user buffer
  2261 0000AA25 57                  <1> 	push	edi ; beginning address of the window
  2262 0000AA26 89FE                <1> 	mov	esi, edi
  2263 0000AA28 89C7                <1> 	mov	edi, eax
  2264 0000AA2A E856130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2265 0000AA2F 5F                  <1> 	pop	edi
  2266 0000AA30 5E                  <1> 	pop	esi
  2267 0000AA31 0F82ECF6FFFF        <1> 	jc	sysret
  2268                              <1> sysvideo_10: 
  2269                              <1> 	; user to system video/display page window transfer (mode 0)	
  2270                              <1> 	; esi =	user buffer
  2271 0000AA37 E893130000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2272 0000AA3C 0F82E1F6FFFF        <1> 	jc	sysret
  2273 0000AA42 010D[80E30000]      <1> 	add	[u.r0], ecx
  2274 0000AA48 01D7                <1> 	add	edi, edx ; next row
  2275 0000AA4A 01CE                <1> 	add	esi, ecx
  2276 0000AA4C FECF                <1> 	dec	bh
  2277 0000AA4E 75E7                <1> 	jnz	short sysvideo_10
  2278 0000AA50 E9CEF6FFFF          <1> 	jmp	sysret
  2279                              <1> 	
  2280                              <1> sysvideo_11:
  2281                              <1> 	; system to user video/display page window transfer (mode 0)
  2282 0000AA55 87FE                <1> 	xchg	edi, esi
  2283                              <1> sysvideo_12:
  2284                              <1> 	; esi = beginning address of the window
  2285                              <1> 	; edi =	user buffer	
  2286 0000AA57 E829130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2287 0000AA5C 0F82C1F6FFFF        <1> 	jc	sysret
  2288 0000AA62 010D[80E30000]      <1> 	add	[u.r0], ecx
  2289 0000AA68 01D6                <1> 	add	esi, edx ; next row
  2290 0000AA6A 01CF                <1> 	add	edi, ecx
  2291 0000AA6C FECF                <1> 	dec	bh
  2292 0000AA6E 75E7                <1> 	jnz	short sysvideo_12
  2293 0000AA70 E9AEF6FFFF          <1> 	jmp	sysret
  2294                              <1> 
  2295                              <1> 
  2296                              <1> sysaudio: ; AUDIO FUNCTIONS
  2297                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  2298                              <1> 	;
  2299                              <1> 	; Inputs:
  2300                              <1> 	;	BH = 0 -> Beep (PC Speaker)
  2301                              <1> 	;	     BL = Duration Counter (1 for 1/64 second)
  2302                              <1> 	;	     CX = Frequency Divisor (1193180/Frequency)
  2303                              <1> 	;		 (1331 for 886 Hz)			
  2304                              <1> 	;
  2305                              <1> 	; Outputs:
  2306                              <1> 	;	none
  2307                              <1> 	;
  2308 0000AA75 20FF                <1> 	and	bh, bh
  2309 0000AA77 0F85A6F6FFFF        <1> 	jnz	sysret
  2310 0000AA7D E8646DFFFF          <1> 	call	beep
  2311 0000AA82 E99CF6FFFF          <1> 	jmp	sysret
  2312                              <1> 
  2313                              <1> syslink:
  2314                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2315                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2316                              <1> 	;
  2317                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
  2318                              <1> 	; name 1 is a file that already exists. name 2 is the name
  2319                              <1> 	; given to the entry that will go in the current directory.
  2320                              <1> 	; name2 will then be a link to the name 1 file. The i-number
  2321                              <1> 	; in the name 2 entry of current directory is the same
  2322                              <1> 	; i-number for the name 1 file.
  2323                              <1> 	;
  2324                              <1> 	; Calling sequence:
  2325                              <1> 	;	syslink; name 1; name 2
  2326                              <1> 	; Arguments:
  2327                              <1> 	;	name 1 - file name to which link will be created.
  2328                              <1> 	;	name 2 - name of entry in current directory that
  2329                              <1> 	;		 links to name 1.
  2330                              <1> 	; Inputs: -
  2331                              <1> 	; Outputs: -
  2332                              <1> 	; ...............................................................
  2333                              <1> 	;	
  2334                              <1> 	; Retro UNIX 8086 v1 modification: 
  2335                              <1> 	;       'syslink' system call has two arguments; so,
  2336                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
  2337                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
  2338                              <1> 	;
  2339                              <1> 		; / name1, name2
  2340                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
  2341 0000AA87 891D[98E30000]      <1> 	mov	[u.namep], ebx
  2342 0000AA8D 51                  <1> 	push	ecx
  2343 0000AA8E E86C040000          <1> 	call	namei
  2344                              <1> 		; jsr r0,namei / find the i-number associated with
  2345                              <1> 			     ; / the 1st path name
  2346                              <1>      	;;and	ax, ax
  2347                              <1> 	;;jz	error ; File not found
  2348                              <1> 	;jc	error 
  2349                              <1> 		; br error9 / cannot be found
  2350 0000AA93 730F                <1> 	jnc	short syslink0
  2351                              <1> 	;pop 	ecx
  2352                              <1> 	; 'file not found !' error
  2353 0000AA95 C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2353 0000AA9D 0000                <1>
  2354 0000AA9F E95FF6FFFF          <1> 	jmp	error
  2355                              <1> syslink0:
  2356 0000AAA4 E862130000          <1> 	call	iget
  2357                              <1> 		; jsr r0,iget / get the i-node into core
  2358 0000AAA9 8F05[98E30000]      <1> 	pop	dword [u.namep] ; ecx
  2359                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2360 0000AAAF 6650                <1> 	push	ax
  2361                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
  2362                              <1> 			    ; / (a link to this file is to be created)
  2363 0000AAB1 66FF35[60E30000]    <1> 	push	word [cdev]
  2364                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2365 0000AAB8 E855000000          <1> 	call	isdir
  2366                              <1> 		; jsr r0,isdir / is it a directory
  2367 0000AABD E83D040000          <1> 	call	namei
  2368                              <1> 		; jsr r0,namei / no, get i-number of name2
  2369                              <1> 	;jnc	error
  2370                              <1> 		; br .+4   / not found 
  2371                              <1> 			 ; / so r1 = i-number of current directory
  2372                              <1> 			 ; / ii = i-number of current directory
  2373                              <1> 		; br error9 / file already exists., error
  2374 0000AAC2 720F                <1> 	jc	short syslink1
  2375                              <1> 	; pop ax
  2376                              <1> 	; pop ax
  2377                              <1> 	; 'file exists !' error
  2378 0000AAC4 C705[D5E30000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2378 0000AACC 0000                <1>
  2379 0000AACE E930F6FFFF          <1> 	jmp	error
  2380                              <1> syslink1:
  2381 0000AAD3 6659                <1> 	pop	cx
  2382                              <1> 	;cmp	cx, [cdev]
  2383 0000AAD5 3A0D[60E30000]      <1> 	cmp	cl, [cdev]
  2384                              <1> 	;jne	error
  2385                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
  2386                              <1> 			       ; / end of current directory
  2387                              <1> 	        ; bne error9
  2388 0000AADB 740F                <1> 	je	short syslink2
  2389                              <1> 	; 'not same drive !' error
  2390 0000AADD C705[D5E30000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2390 0000AAE5 0000                <1>
  2391 0000AAE7 E917F6FFFF          <1> 	jmp	error
  2392                              <1> syslink2:
  2393 0000AAEC 6658                <1> 	pop	ax
  2394 0000AAEE 6650                <1> 	push	ax
  2395 0000AAF0 66A3[B2E30000]      <1> 	mov	[u.dirbuf], ax
  2396                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2397 0000AAF6 E8A8000000          <1> 	call	mkdir
  2398                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2399                              <1> 		 	     ; / in current directory
  2400 0000AAFB 6658                <1> 	pop	ax
  2401                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2402 0000AAFD E809130000          <1> 	call	iget
  2403                              <1> 		; jsr r0,iget / get i-node into core
  2404 0000AB02 FE05[44E00000]      <1> 	inc	byte [i.nlks]
  2405                              <1> 		; incb i.nlks / add 1 to its number of links
  2406 0000AB08 E805130000          <1> 	call	setimod
  2407                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2408 0000AB0D E911F6FFFF          <1> 	jmp	sysret
  2409                              <1> 
  2410                              <1> isdir:
  2411                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  2412                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  2413                              <1> 	;
  2414                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
  2415                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
  2416                              <1> 	;  called by syslink and sysunlink to make sure directories
  2417                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
  2418                              <1> 	; 'isdir' does not bother checking. The current i-node
  2419                              <1> 	;  is not disturbed.			
  2420                              <1> 	;		
  2421                              <1> 	; INPUTS ->
  2422                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
  2423                              <1> 	;    u.uid - user id
  2424                              <1> 	; OUTPUTS ->
  2425                              <1> 	;    r1 - contains current i-number upon exit
  2426                              <1> 	;    	 (current i-node back in core) 
  2427                              <1> 	;	
  2428                              <1> 	; ((AX = R1))
  2429                              <1> 	;
  2430                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2431                              <1> 	;
  2432                              <1> 
  2433                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
  2434                              <1> 	; / there is an error unless super user made the call
  2435                              <1> 	
  2436 0000AB12 803D[CCE30000]00    <1> 	cmp	byte [u.uid], 0 
  2437                              <1> 		; tstb u.uid / super user
  2438 0000AB19 762D                <1> 	jna	short isdir1
  2439                              <1> 		; beq 1f / yes, don't care
  2440 0000AB1B 66FF35[05E40000]    <1> 	push	word [ii]
  2441                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2442 0000AB22 E8E4120000          <1> 	call	iget
  2443                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2444 0000AB27 66F705[42E00000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2444 0000AB2F 40                  <1>
  2445                              <1> 		; bit $40000,i.flgs / is it a directory
  2446                              <1> 	;jnz	error
  2447                              <1> 		; bne error9 / yes, error
  2448 0000AB30 740F                <1> 	jz	short isdir0
  2449 0000AB32 C705[D5E30000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2449 0000AB3A 0000                <1>
  2450                              <1> 				; 'permission denied !' error
  2451                              <1> 	; pop	ax
  2452 0000AB3C E9C2F5FFFF          <1> 	jmp	error	
  2453                              <1> isdir0:	
  2454 0000AB41 6658                <1> 	pop	ax
  2455                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2456 0000AB43 E8C3120000          <1> 	call	iget
  2457                              <1> 		; jsr r0,iget / get it back in
  2458                              <1> isdir1: ; 1:
  2459 0000AB48 C3                  <1> 	retn
  2460                              <1> 		; rts r0
  2461                              <1> 
  2462                              <1> sysunlink:
  2463                              <1> 	; 04/12/2015 (14 byte file names)
  2464                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2465                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2466                              <1> 	;
  2467                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
  2468                              <1> 	; name from its directory. If this entry was the last link
  2469                              <1> 	; to the file, the contents of the file are freed and the
  2470                              <1> 	; file is destroyed. If, however, the file was open in any
  2471                              <1> 	; process, the actual destruction is delayed until it is 
  2472                              <1> 	; closed, even though the directory entry has disappeared.
  2473                              <1> 	; 
  2474                              <1> 	; The error bit (e-bit) is set to indicate that the file	
  2475                              <1> 	; does not exist or that its directory can not be written.
  2476                              <1> 	; Write permission is not required on the file itself.
  2477                              <1> 	; It is also illegal to unlink a directory (except for
  2478                              <1> 	; the superuser).
  2479                              <1> 	;
  2480                              <1> 	; Calling sequence:
  2481                              <1> 	;	sysunlink; name
  2482                              <1> 	; Arguments:
  2483                              <1> 	;	name - name of directory entry to be removed 
  2484                              <1> 	; Inputs: -
  2485                              <1> 	; Outputs: -
  2486                              <1> 	; ...............................................................
  2487                              <1> 	;				
  2488                              <1> 	; Retro UNIX 8086 v1 modification:
  2489                              <1> 	;	 The user/application program puts address of the name
  2490                              <1> 	;        in BX register as 'sysunlink' system call argument.
  2491                              <1> 
  2492                              <1> 	; / name - remove link name
  2493 0000AB49 891D[98E30000]      <1> 	mov	[u.namep], ebx
  2494                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2495 0000AB4F E8AB030000          <1> 	call	namei
  2496                              <1> 		; jsr r0,namei / find the i-number associated 
  2497                              <1> 			     ; / with the path name
  2498                              <1> 	;jc	error
  2499                              <1> 		; br error9 / not found
  2500 0000AB54 730F                <1> 	jnc	short sysunlink1
  2501                              <1> 	; 'file not found !' error
  2502 0000AB56 C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2502 0000AB5E 0000                <1>
  2503 0000AB60 E99EF5FFFF          <1> 	jmp	error
  2504                              <1> sysunlink1:
  2505 0000AB65 6650                <1> 	push	ax
  2506                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2507 0000AB67 E8A6FFFFFF          <1> 	call	isdir
  2508                              <1> 		; jsr r0,isdir / is it a directory
  2509 0000AB6C 6631C0              <1> 	xor 	ax, ax
  2510 0000AB6F 66A3[B2E30000]      <1> 	mov	[u.dirbuf], ax ; 0
  2511                              <1> 		; clr u.dirbuf / no, clear the location that will
  2512                              <1> 			   ; / get written into the i-number portion
  2513                              <1> 			 ; / of the entry
  2514 0000AB75 832D[9CE30000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
  2515                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
  2516 0000AB7C E86E000000          <1> 	call	wdir
  2517                              <1> 		; jsr r0,wdir / free the directory entry
  2518 0000AB81 6658                <1> 	pop	ax
  2519                              <1> 		; mov (sp)+,r1 / get i-number back
  2520 0000AB83 E883120000          <1> 	call	iget
  2521                              <1> 		; jsr r0,iget / get i-node
  2522 0000AB88 E885120000          <1> 	call	setimod
  2523                              <1> 		; jsr r0,setimod / set modified flag
  2524 0000AB8D FE0D[44E00000]      <1> 	dec	byte [i.nlks]
  2525                              <1> 		; decb i.nlks / decrement the number of links
  2526 0000AB93 0F858AF5FFFF        <1> 	jnz	sysret
  2527                              <1> 		; bgt sysret9 / if this was not the last link
  2528                              <1> 			    ; / to file return
  2529                              <1> 	; AX = r1 = i-number
  2530 0000AB99 E886070000          <1> 	call	anyi
  2531                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
  2532                              <1> 			 ; / Then free contents of file and destroy it.
  2533 0000AB9E E980F5FFFF          <1> 	jmp	sysret
  2534                              <1> 		; br sysret9
  2535                              <1> 
  2536                              <1> mkdir:
  2537                              <1> 	; 04/12/2015 (14 byte directory names)
  2538                              <1> 	; 12/10/2015
  2539                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  2540                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2541                              <1> 	;
  2542                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  2543                              <1> 	; by u.namep into the current directory.
  2544                              <1> 	;
  2545                              <1> 	; INPUTS ->
  2546                              <1> 	;    u.namep - points to a file name 
  2547                              <1> 	;	           that is about to be a directory entry.
  2548                              <1> 	;    ii - current directory's i-number.	
  2549                              <1> 	; OUTPUTS ->
  2550                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  2551                              <1> 	;    u.off - points to entry to be filled 
  2552                              <1> 	;	     in the current directory		
  2553                              <1> 	;    u.base - points to start of u.dirbuf.
  2554                              <1> 	;    r1 - contains i-number of current directory 
  2555                              <1> 	;	
  2556                              <1> 	; ((AX = R1)) output
  2557                              <1> 	;
  2558                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  2559                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2560                              <1> 	;
  2561                              <1> 
  2562                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  2563 0000ABA3 31C0                <1> 	xor 	eax, eax
  2564 0000ABA5 BF[B4E30000]        <1> 	mov     edi, u.dirbuf+2
  2565 0000ABAA 89FE                <1> 	mov	esi, edi
  2566 0000ABAC AB                  <1> 	stosd
  2567 0000ABAD AB                  <1> 	stosd
  2568                              <1> 	; 04/12/2015 (14 byte directory names)
  2569 0000ABAE AB                  <1> 	stosd
  2570 0000ABAF 66AB                <1> 	stosw
  2571                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2572 0000ABB1 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2573                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2574                              <1> 	;mov 	ebp, [u.namep]
  2575 0000ABB3 E88C040000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  2576                              <1> 		; esi = physical address (page start + offset)
  2577                              <1> 		; ecx = byte count in the page (1 - 4096)
  2578                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2579                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  2580                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  2581                              <1> mkdir_1: ; 1: 
  2582 0000ABB8 45                  <1> 	inc	ebp ; 12/10/2015
  2583                              <1> 	;
  2584                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  2585                              <1> 	 ; 01/08/2013
  2586 0000ABB9 AC                  <1> 	lodsb
  2587                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2588 0000ABBA 20C0                <1> 	and 	al, al
  2589 0000ABBC 7427                <1> 	jz 	short mkdir_3 	  
  2590                              <1> 		; beq 1f / if null, done
  2591 0000ABBE 3C2F                <1> 	cmp	al, '/'
  2592                              <1> 		; cmp r1,$'/ / is it a "/"?
  2593 0000ABC0 7414                <1> 	je	short mkdir_err
  2594                              <1> 	;je	error
  2595                              <1> 		; beq error9 / yes, error
  2596                              <1> 	; 12/10/2015
  2597 0000ABC2 6649                <1> 	dec	cx
  2598 0000ABC4 7505                <1> 	jnz	short mkdir_2
  2599                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2600 0000ABC6 E87F040000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  2601                              <1> 		; esi = physical address (page start + offset)
  2602                              <1> 		; ecx = byte count in the page
  2603                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2604                              <1> mkdir_2:
  2605 0000ABCB 81FF[C2E30000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  2606                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  2607                              <1> 				     ; / a char?
  2608 0000ABD1 74E5                <1> 	je	short mkdir_1
  2609                              <1> 		; beq 1b / yes, go back
  2610 0000ABD3 AA                  <1> 	stosb
  2611                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2612 0000ABD4 EBE2                <1> 	jmp 	short mkdir_1
  2613                              <1> 		; br 1b / get next char
  2614                              <1> mkdir_err:
  2615                              <1> 	; 17/06/2015
  2616 0000ABD6 C705[D5E30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2616 0000ABDE 0000                <1>
  2617 0000ABE0 E91EF5FFFF          <1> 	jmp	error
  2618                              <1> 
  2619                              <1> mkdir_3: ; 1:
  2620 0000ABE5 A1[94E30000]        <1> 	mov	eax, [u.dirp]
  2621 0000ABEA A3[9CE30000]        <1> 	mov	[u.off], eax
  2622                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  2623                              <1> 				 ; / slot to u.off
  2624                              <1> wdir: ; 29/04/2013
  2625 0000ABEF C705[A0E30000]-     <1>         mov     dword [u.base], u.dirbuf
  2625 0000ABF5 [B2E30000]          <1>
  2626                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2627 0000ABF9 C705[A4E30000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2627 0000AC01 0000                <1>
  2628                              <1> 		; mov $10.,u.count / u.count = 10
  2629 0000AC03 66A1[05E40000]      <1> 	mov	ax, [ii] 
  2630                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2631 0000AC09 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2632 0000AC0B E806120000          <1> 	call 	access
  2633                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  2634                              <1> 				 ; / for writing
  2635                              <1> 	; AX = i-number of current directory
  2636                              <1> 	; 01/08/2013
  2637 0000AC10 FE05[E7E30000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2638 0000AC16 E8F3110000          <1> 	call	writei
  2639                              <1> 		; jsr r0,writei / write into directory
  2640 0000AC1B C3                  <1> 	retn	
  2641                              <1> 		; rts r0
  2642                              <1> 
  2643                              <1> sysexec:
  2644                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  2645                              <1> 	; 23/06/2015 - 23/10/2015 (Retro UNIX 386 v1)
  2646                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2647                              <1> 	;
  2648                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  2649                              <1> 	; pointed to by 'name' in the sysexec call. 
  2650                              <1> 	; 'sysexec' performs the following operations:
  2651                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  2652                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
  2653                              <1> 	;    3. sets trap vectors to system routines.
  2654                              <1> 	;    4. loads arguments to be passed to executing file into
  2655                              <1> 	;	highest locations of user's core
  2656                              <1> 	;    5. puts pointers to arguments in locations immediately
  2657                              <1> 	;	following arguments.
  2658                              <1> 	;    6.	saves number of arguments in next location.
  2659                              <1> 	;    7. intializes user's stack area so that all registers
  2660                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  2661                              <1> 	;	to core when 'sysret' restores registers 
  2662                              <1> 	;	and does an rti.
  2663                              <1> 	;    8. inializes u.r0 and u.sp
  2664                              <1> 	;    9. zeros user's core down to u.r0
  2665                              <1> 	;   10.	reads executable file from storage device into core
  2666                              <1> 	;	starting at location 'core'.
  2667                              <1> 	;   11.	sets u.break to point to end of user's code with
  2668                              <1> 	;	data area appended.
  2669                              <1> 	;   12.	calls 'sysret' which returns control at location
  2670                              <1> 	;	'core' via 'rti' instruction. 		  		
  2671                              <1> 	;
  2672                              <1> 	; Calling sequence:
  2673                              <1> 	;	sysexec; namep; argp
  2674                              <1> 	; Arguments:
  2675                              <1> 	;	namep - points to pathname of file to be executed
  2676                              <1> 	;	argp  - address of table of argument pointers
  2677                              <1> 	;	argp1... argpn - table of argument pointers
  2678                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  2679                              <1> 	; Inputs: (arguments)
  2680                              <1> 	; Outputs: -	
  2681                              <1> 	; ...............................................................
  2682                              <1> 	;
  2683                              <1> 	; Retro UNIX 386 v1 modification: 
  2684                              <1> 	;	User application runs in it's own virtual space 
  2685                              <1> 	;	which is izolated from kernel memory (and other
  2686                              <1> 	;	memory pages) via 80386	paging in ring 3 
  2687                              <1> 	;	privilige mode. Virtual start address is always 0.
  2688                              <1> 	;	User's core memory starts at linear address 400000h
  2689                              <1> 	;	(the end of the 1st 4MB).
  2690                              <1> 	;
  2691                              <1> 	; Retro UNIX 8086 v1 modification: 
  2692                              <1> 	;	user/application segment and system/kernel segment
  2693                              <1> 	;	are different and sysenter/sysret/sysrele routines
  2694                              <1> 	;	are different (user's registers are saved to 
  2695                              <1> 	;	and then restored from system's stack.)
  2696                              <1> 	;
  2697                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2698                              <1> 	;	      arguments which were in these registers;
  2699                              <1> 	;	      but, it returns by putting the 1st argument
  2700                              <1> 	;	      in 'u.namep' and the 2nd argument
  2701                              <1> 	;	      on top of stack. (1st argument is offset of the
  2702                              <1> 	;	      file/path name in the user's program segment.)		 	
  2703                              <1> 	
  2704                              <1> 	;call	arg2
  2705                              <1> 	; * name - 'u.namep' points to address of file/path name
  2706                              <1> 	;          in the user's program segment ('u.segmnt')
  2707                              <1> 	;          with offset in BX register (as sysopen argument 1).
  2708                              <1> 	; * argp - sysexec argument 2 is in CX register 
  2709                              <1> 	;          which is on top of stack.
  2710                              <1> 	;
  2711                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  2712                              <1> 
  2713                              <1> 	; 23/06/2015 (32 bit modifications)
  2714                              <1> 
  2715 0000AC1C 891D[98E30000]      <1> 	mov	[u.namep], ebx ; argument 1
  2716                              <1>         ; 18/10/2015
  2717 0000AC22 890D[00E40000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2718 0000AC28 E8D2020000          <1> 	call	namei
  2719                              <1> 		; jsr r0,namei / namei returns i-number of file 
  2720                              <1> 			     ; / named in sysexec call in r1
  2721                              <1> 	;jc	error
  2722                              <1> 		; br error9
  2723 0000AC2D 731E                <1> 	jnc	short sysexec_0
  2724                              <1> 	;
  2725                              <1> 	; 'file not found !' error
  2726 0000AC2F C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2726 0000AC37 0000                <1>
  2727 0000AC39 E9C5F4FFFF          <1> 	jmp	error 
  2728                              <1> sysexec_not_exf:
  2729                              <1> 	; 'not executable file !' error
  2730 0000AC3E C705[D5E30000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
  2730 0000AC46 0000                <1>
  2731 0000AC48 E9B6F4FFFF          <1> 	jmp	error 
  2732                              <1> sysexec_0:
  2733 0000AC4D E8B9110000          <1> 	call	iget
  2734                              <1> 		; jsr r0,iget / get i-node for file to be executed
  2735 0000AC52 66F705[42E00000]10- <1>         test    word [i.flgs], 10h
  2735 0000AC5A 00                  <1>
  2736                              <1> 		; bit $20,i.flgs / is file executable
  2737 0000AC5B 74E1                <1> 	jz	short sysexec_not_exf
  2738                              <1> 	;jz	error
  2739                              <1> 		; beq error9
  2740                              <1> 	;;
  2741 0000AC5D E8AD110000          <1> 	call	iopen
  2742                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
  2743                              <1> 			     ; / given in r1 (opens file)
  2744                              <1> 	; AX = i-number of the file
  2745 0000AC62 66F705[42E00000]20- <1> 	test	word [i.flgs], 20h
  2745 0000AC6A 00                  <1>
  2746                              <1> 		; bit $40,i.flgs / test user id on execution bit
  2747 0000AC6B 7415                <1> 	jz	short sysexec_1
  2748                              <1> 		; beq 1f
  2749 0000AC6D 803D[CCE30000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
  2750                              <1> 		; tstb u.uid / test user id
  2751 0000AC74 760C                <1> 	jna	short sysexec_1
  2752                              <1> 		; beq 1f / super user
  2753 0000AC76 8A0D[45E00000]      <1> 	mov	cl, [i.uid]
  2754 0000AC7C 880D[CCE30000]      <1> 	mov	[u.uid], cl ; 02/08/2013
  2755                              <1> 		; movb i.uid,u.uid / put user id of owner of file
  2756                              <1> 				 ; / as process user id
  2757                              <1> sysexec_1:
  2758                              <1> 	; 18/10/2215
  2759                              <1> 	; 10/10/2015
  2760                              <1> 	; 24/07/2015
  2761                              <1> 	; 21/07/2015
  2762                              <1> 	; 25/06/2015
  2763                              <1> 	; 24/06/2015
  2764                              <1>         ; Moving arguments to the end of [u.upage]
  2765                              <1> 	; (by regarding page borders in user's memory space)
  2766                              <1> 	;
  2767                              <1> 	; 10/10/2015
  2768                              <1> 	; 21/07/2015
  2769 0000AC82 89E5                <1> 	mov	ebp, esp ; (**)
  2770                              <1> 	; 18/10/2015
  2771 0000AC84 89EF                <1> 	mov 	edi, ebp
  2772 0000AC86 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2773                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2774 0000AC8B 29CF                <1> 	sub	edi, ecx
  2775 0000AC8D 89FC                <1> 	mov	esp, edi
  2776 0000AC8F 31C0                <1> 	xor	eax, eax
  2777 0000AC91 A3[A8E30000]        <1> 	mov 	[u.nread], eax ; 0
  2778 0000AC96 49                  <1> 	dec	ecx ; 256 - 1
  2779 0000AC97 890D[A4E30000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  2780                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  2781                              <1> sysexec_2:
  2782 0000AC9D 8B35[00E40000]      <1> 	mov	esi, [argv] ; 18/10/2015 
  2783 0000ACA3 E866000000          <1> 	call	get_argp
  2784 0000ACA8 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  2785                              <1> sysexec_3:
  2786 0000ACAD 21C0                <1> 	and	eax, eax
  2787 0000ACAF 0F84C4090000        <1>         jz      sysexec_6
  2788                              <1> 	; 18/10/2015
  2789 0000ACB5 010D[00E40000]      <1> 	add	[argv], ecx ; 4
  2790 0000ACBB 66FF05[FEE30000]    <1> 	inc	word [argc]
  2791                              <1> 	;
  2792 0000ACC2 A3[A0E30000]        <1> 	mov	[u.base], eax
  2793                              <1>  	; 23/10/2015
  2794 0000ACC7 66C705[E5E30000]00- <1> 	mov	word [u.pcount], 0
  2794 0000ACCF 00                  <1>
  2795                              <1> sysexec_4:
  2796 0000ACD0 E850100000          <1> 	call	cpass ; get a character from user's core memory
  2797 0000ACD5 750E                <1>         jnz      short sysexec_5
  2798                              <1> 		; (max. 255 chars + null)
  2799                              <1> 	; 18/10/2015
  2800 0000ACD7 28C0                <1> 	sub 	al, al
  2801 0000ACD9 AA                  <1> 	stosb
  2802 0000ACDA FF05[A8E30000]      <1> 	inc	dword [u.nread]
  2803 0000ACE0 E994090000          <1> 	jmp	sysexec_6 ; 24/04/2016
  2804                              <1> sysexec_5:
  2805 0000ACE5 AA                  <1> 	stosb
  2806 0000ACE6 20C0                <1> 	and 	al, al
  2807 0000ACE8 75E6                <1> 	jnz	short sysexec_4
  2808 0000ACEA B904000000          <1> 	mov	ecx, 4
  2809 0000ACEF 390D[FCE30000]      <1> 	cmp	[ncount], ecx ; 4
  2810 0000ACF5 72A6                <1> 	jb	short sysexec_2
  2811 0000ACF7 8B35[F8E30000]      <1> 	mov	esi, [nbase]
  2812 0000ACFD 010D[F8E30000]      <1> 	add	[nbase], ecx ; 4	
  2813 0000AD03 66290D[FCE30000]    <1> 	sub	[ncount], cx 
  2814 0000AD0A 8B06                <1> 	mov	eax, [esi]
  2815 0000AD0C EB9F                <1> 	jmp	short sysexec_3
  2816                              <1> 
  2817                              <1> get_argp:
  2818                              <1> 	; 18/10/2015 (nbase, ncount)
  2819                              <1> 	; 21/07/2015
  2820                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  2821                              <1> 	; Get (virtual) address of argument from user's core memory
  2822                              <1> 	;
  2823                              <1> 	; INPUT:
  2824                              <1> 	;	esi = virtual address of argument pointer
  2825                              <1> 	; OUTPUT:
  2826                              <1> 	;	eax = virtual address of argument
  2827                              <1> 	;
  2828                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  2829                              <1> 	;
  2830 0000AD0E 833D[DDE30000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  2831                              <1> 				    ; (the caller is kernel)
  2832 0000AD15 7667                <1>         jna     short get_argpk 
  2833                              <1> 	;
  2834 0000AD17 89F3                <1>      	mov	ebx, esi
  2835 0000AD19 E88A8BFFFF          <1> 	call	get_physical_addr ; get physical address
  2836 0000AD1E 0F8289000000        <1>         jc      get_argp_err
  2837 0000AD24 A3[F8E30000]        <1> 	mov 	[nbase], eax ; physical address	
  2838 0000AD29 66890D[FCE30000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  2839 0000AD30 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  2840 0000AD35 6639C1              <1> 	cmp	cx, ax ; 4
  2841 0000AD38 735D                <1> 	jnb	short get_argp2
  2842 0000AD3A 89F3                <1> 	mov	ebx, esi
  2843 0000AD3C 01CB                <1> 	add	ebx, ecx
  2844 0000AD3E E8658BFFFF          <1> 	call	get_physical_addr ; get physical address
  2845 0000AD43 7268                <1> 	jc	short get_argp_err
  2846                              <1> 	;push	esi
  2847 0000AD45 89C6                <1> 	mov	esi, eax
  2848 0000AD47 66870D[FCE30000]    <1> 	xchg	cx, [ncount]
  2849 0000AD4E 8735[F8E30000]      <1> 	xchg	esi, [nbase]
  2850 0000AD54 B504                <1> 	mov	ch, 4
  2851 0000AD56 28CD                <1> 	sub	ch, cl
  2852                              <1> get_argp0:
  2853 0000AD58 AC                  <1> 	lodsb
  2854 0000AD59 6650                <1> 	push	ax
  2855 0000AD5B FEC9                <1> 	dec	cl
  2856 0000AD5D 75F9                <1>         jnz     short get_argp0
  2857 0000AD5F 8B35[F8E30000]      <1> 	mov	esi, [nbase]
  2858                              <1> 	; 21/07/2015
  2859 0000AD65 0FB6C5              <1> 	movzx	eax, ch
  2860 0000AD68 0105[F8E30000]      <1> 	add	[nbase], eax
  2861 0000AD6E 662905[FCE30000]    <1> 	sub	[ncount], ax
  2862                              <1> get_argp1:
  2863 0000AD75 AC                  <1> 	lodsb
  2864 0000AD76 FECD                <1> 	dec	ch
  2865 0000AD78 743D                <1>         jz      short get_argp3
  2866 0000AD7A 6650                <1>         push	ax
  2867 0000AD7C EBF7                <1> 	jmp     short get_argp1
  2868                              <1> get_argpk:
  2869                              <1> 	; Argument is in kernel's memory space
  2870 0000AD7E 66C705[FCE30000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  2870 0000AD86 10                  <1>
  2871 0000AD87 8935[F8E30000]      <1> 	mov	[nbase], esi
  2872 0000AD8D 8305[F8E30000]04    <1> 	add	dword [nbase], 4
  2873 0000AD94 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  2874 0000AD96 C3                  <1> 	retn
  2875                              <1> get_argp2:
  2876                              <1> 	; 21/07/2015
  2877                              <1> 	;mov	eax, 4
  2878 0000AD97 8B15[F8E30000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  2879 0000AD9D 0105[F8E30000]      <1> 	add	[nbase], eax
  2880 0000ADA3 662905[FCE30000]    <1> 	sub	[ncount], ax
  2881                              <1> 	;
  2882 0000ADAA 8B02                <1> 	mov	eax, [edx]
  2883 0000ADAC C3                  <1> 	retn
  2884                              <1> get_argp_err:
  2885 0000ADAD A3[D5E30000]        <1> 	mov	[u.error], eax
  2886 0000ADB2 E94CF3FFFF          <1> 	jmp	error
  2887                              <1> get_argp3:
  2888 0000ADB7 B103                <1> 	mov	cl, 3
  2889                              <1> get_argp4:
  2890 0000ADB9 C1E008              <1> 	shl	eax, 8
  2891 0000ADBC 665A                <1> 	pop	dx
  2892 0000ADBE 88D0                <1> 	mov 	al, dl
  2893 0000ADC0 E2F7                <1>         loop    get_argp4
  2894                              <1> 	;pop	esi
  2895 0000ADC2 C3                  <1> 	retn	
  2896                              <1> 
  2897                              <1> sysfstat: 
  2898                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2899                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2900                              <1> 	;
  2901                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
  2902                              <1> 	; on open files instead of files given by name. It puts the
  2903                              <1> 	; buffer address on the stack, gets the i-number and
  2904                              <1> 	; checks to see if the file is open for reading or writing.
  2905                              <1> 	; If the file is open for writing (i-number is negative)
  2906                              <1> 	; the i-number is set positive and a branch into 'sysstat'
  2907                              <1> 	; is made.	
  2908                              <1> 	;
  2909                              <1> 	; Calling sequence:
  2910                              <1> 	;	sysfstat; buf
  2911                              <1> 	; Arguments:
  2912                              <1> 	;	buf - buffer address
  2913                              <1> 	;
  2914                              <1> 	; Inputs: *u.r0 - file descriptor
  2915                              <1> 	; Outputs: buffer is loaded with file information
  2916                              <1> 	; ...............................................................
  2917                              <1> 	;				
  2918                              <1> 	; Retro UNIX 8086 v1 modification:
  2919                              <1> 	;       'sysfstat' system call has two arguments; so,
  2920                              <1> 	;	* 1st argument, file descriptor is in BX register
  2921                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2922                              <1> 
  2923                              <1> 	; / set status of open file
  2924                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
  2925 0000ADC3 51                  <1> 	push	ecx
  2926                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
  2927                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
  2928                              <1> 		; jsr r0,getf / get the files i-number
  2929                              <1> 	; BX = file descriptor (file number)
  2930 0000ADC4 E8FF000000          <1> 	call	getf1
  2931 0000ADC9 6621C0              <1> 	and	ax, ax ; i-number of the file
  2932                              <1> 		; tst	r1 / is it 0?
  2933                              <1> 	;jz	error
  2934                              <1> 		; beq error3 / yes, error
  2935 0000ADCC 750F                <1> 	jnz	short sysfstat1
  2936 0000ADCE C705[D5E30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  2936 0000ADD6 0000                <1>
  2937 0000ADD8 E926F3FFFF          <1> 	jmp	error
  2938                              <1> sysfstat1:
  2939 0000ADDD 80FC80              <1> 	cmp	ah, 80h
  2940 0000ADE0 7223                <1>         jb      short sysstat1
  2941                              <1> 		; bgt 1f / if i-number is negative (open for writing)
  2942 0000ADE2 66F7D8              <1> 	neg	ax
  2943                              <1> 		; neg r1 / make it positive, then branch
  2944 0000ADE5 EB1E                <1> 	jmp	short sysstat1
  2945                              <1> 		; br 1f / to 1f
  2946                              <1> sysstat:
  2947                              <1> 	; 18/10/2015
  2948                              <1> 	; 07/10/2015
  2949                              <1> 	; 02/09/2015
  2950                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2951                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2952                              <1> 	;
  2953                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
  2954                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
  2955                              <1> 	; long and information about the file placed in it.	
  2956                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
  2957                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
  2958                              <1> 	; is then loaded and the results are given in the UNIX
  2959                              <1> 	; Programmers Manual sysstat (II).	
  2960                              <1> 	;
  2961                              <1> 	; Calling sequence:
  2962                              <1> 	;	sysstat; name; buf
  2963                              <1> 	; Arguments:
  2964                              <1> 	;	name - points to the name of the file
  2965                              <1> 	;	buf - address of a 34 bytes buffer
  2966                              <1> 	; Inputs: -
  2967                              <1> 	; Outputs: buffer is loaded with file information
  2968                              <1> 	; ...............................................................
  2969                              <1> 	;				
  2970                              <1> 	; Retro UNIX 8086 v1 modification: 
  2971                              <1> 	;       'sysstat' system call has two arguments; so,
  2972                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  2973                              <1> 	;	to get sysstat system call arguments from the user;
  2974                              <1> 	;	* 1st argument, name is pointed to by BX register
  2975                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  2976                              <1> 	;
  2977                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2978                              <1> 	;	      arguments which were in these registers;
  2979                              <1> 	;	      but, it returns by putting the 1st argument
  2980                              <1> 	;	      in 'u.namep' and the 2nd argument
  2981                              <1> 	;	      on top of stack. (1st argument is offset of the
  2982                              <1> 	;	      file/path name in the user's program segment.)		 	
  2983                              <1> 	
  2984                              <1> 	; / ; name of file; buffer - get files status
  2985                              <1> 		; jsr r0,arg2 / get the 2 arguments
  2986 0000ADE7 891D[98E30000]      <1> 	mov	[u.namep], ebx
  2987 0000ADED 51                  <1> 	push	ecx
  2988 0000ADEE E80C010000          <1> 	call	namei
  2989                              <1> 		; jsr r0,namei / get the i-number for the file
  2990                              <1> 	;jc	error
  2991                              <1> 		; br error3 / no such file, error
  2992 0000ADF3 7310                <1> 	jnc	short sysstat1
  2993                              <1> 	; pop 	ecx
  2994                              <1> sysstat_err0:
  2995                              <1> 	; 'file not found !' error
  2996 0000ADF5 C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2996 0000ADFD 0000                <1>
  2997 0000ADFF E9FFF2FFFF          <1> 	jmp	error
  2998                              <1> 
  2999 0000AE04 00                  <1> statx: db 0
  3000                              <1> 
  3001                              <1> sysstat1: ; 1:
  3002 0000AE05 E801100000          <1> 	call	iget
  3003                              <1> 		; jsr r0,iget / get the i-node into core
  3004                              <1> 	; 07/10/2015 (ax = [ii], inode number)
  3005                              <1> 	; 02/09/2015
  3006 0000AE0A 8F05[A0E30000]      <1> 	pop	dword [u.base]
  3007                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  3008 0000AE10 E858000000          <1> 	call	sysstat_gpa ; get physical address
  3009 0000AE15 730A                <1> 	jnc 	short sysstat2
  3010                              <1> sysstat_err1:
  3011 0000AE17 A3[D5E30000]        <1> 	mov	dword [u.error], eax ; error code
  3012 0000AE1C E9E2F2FFFF          <1> 	jmp	error
  3013                              <1> sysstat2:
  3014 0000AE21 A0[05E40000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  3015 0000AE26 AA                  <1> 	stosb
  3016 0000AE27 FF05[A0E30000]      <1> 	inc 	dword [u.base]
  3017 0000AE2D 6649                <1> 	dec 	cx
  3018 0000AE2F 7505                <1> 	jnz	short sysstat3
  3019 0000AE31 E837000000          <1> 	call	sysstat_gpa
  3020                              <1> 	;jc	short sysstat_err1
  3021                              <1> sysstat3:
  3022 0000AE36 A0[06E40000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  3023 0000AE3B AA                  <1> 	stosb
  3024                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  3025 0000AE3C FF05[A0E30000]      <1> 	inc 	dword [u.base]
  3026                              <1> 	;dec 	word [u.pcount]
  3027 0000AE42 6649                <1> 	dec	cx
  3028 0000AE44 7505                <1> 	jnz	short sysstat4
  3029 0000AE46 E822000000          <1> 	call	sysstat_gpa
  3030                              <1> 	;jc	short sysstat_err1	
  3031                              <1> sysstat4:
  3032 0000AE4B BE[42E00000]        <1> 	mov	esi, inode
  3033                              <1> 		; mov $inode,r2 / r2 points to i-node
  3034                              <1> sysstat5: ; 1:
  3035 0000AE50 A4                  <1> 	movsb
  3036                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  3037 0000AE51 FF05[A0E30000]      <1> 	inc 	dword [u.base]
  3038                              <1> 	;dec 	word [u.pcount]
  3039 0000AE57 6649                <1> 	dec	cx
  3040 0000AE59 7505                <1> 	jnz	short sysstat6
  3041 0000AE5B E80D000000          <1> 	call	sysstat_gpa
  3042                              <1> 	;jc	short sysstat_err1
  3043                              <1> sysstat6:		
  3044 0000AE60 81FE[62E00000]      <1> 	cmp	esi, inode + 32
  3045                              <1> 		; cmp r2,$inode+32 / done?
  3046 0000AE66 75E8                <1> 	jne	short sysstat5
  3047                              <1> 		; bne 1b / no, go back
  3048 0000AE68 E9B6F2FFFF          <1> 	jmp	sysret
  3049                              <1> 		; br sysret3 / return through sysret
  3050                              <1> 	;
  3051                              <1> sysstat_gpa: ; get physical address of file status buffer
  3052                              <1> 	; 02/09/2015
  3053 0000AE6D 8B1D[A0E30000]      <1> 	mov 	ebx, [u.base]
  3054                              <1> 	; 07/10/2015
  3055 0000AE73 E8308AFFFF          <1> 	call	get_physical_addr ; get physical address
  3056                              <1> 	;jc	short sysstat_gpa1
  3057 0000AE78 729D                <1> 	jc	short sysstat_err1
  3058                              <1> 	; 18/10/2015
  3059 0000AE7A 89C7                <1> 	mov	edi, eax ; physical address
  3060                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3061                              <1> ;sysstat_gpa1:
  3062 0000AE7C C3                  <1> 	retn
  3063                              <1> 
  3064                              <1> fclose:
  3065                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  3066                              <1> 	;            (32 bit offset pointer modification)
  3067                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  3068                              <1> 	;
  3069                              <1> 	; Given the file descriptor (index to the u.fp list)
  3070                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  3071                              <1> 	; If i-node is active (i-number > 0) the entry in 
  3072                              <1> 	; u.fp list is cleared. If all the processes that opened
  3073                              <1> 	; that file close it, then fsp etry is freed and the file
  3074                              <1> 	; is closed. If not a return is taken. 
  3075                              <1> 	; If the file has been deleted while open, 'anyi' is called
  3076                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  3077                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  3078                              <1> 	; a check is made to see if the file is special.	
  3079                              <1> 	;
  3080                              <1> 	; INPUTS ->
  3081                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  3082                              <1> 	;    u.fp - list of entries in the fsp table
  3083                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  3084                              <1> 	; OUTPUTS ->
  3085                              <1> 	;    r1 - contains the same file descriptor
  3086                              <1> 	;    r2 - contains i-number
  3087                              <1> 	;
  3088                              <1> 	; ((AX = R1))
  3089                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
  3090                              <1> 	;
  3091                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  3092                              <1> 	;              if i-number of the file is 0. (error)  	
  3093                              <1> 	;
  3094 0000AE7D 0FB7D0              <1> 	movzx	edx, ax ; **
  3095 0000AE80 6650                <1> 	push	ax ; ***
  3096                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
  3097                              <1> 			     ; / the index to u.fp list)
  3098 0000AE82 E83F000000          <1> 	call	getf
  3099                              <1> 		; jsr r0,getf / r1 contains i-number, 
  3100                              <1> 			    ; / cdev has device =, u.fofp 
  3101                              <1> 			    ; / points to 3rd word of fsp entry
  3102 0000AE87 6683F801            <1> 	cmp	ax, 1 ; r1
  3103                              <1> 		; tst r1 / is i-number 0?
  3104 0000AE8B 7236                <1> 	jb	short fclose_2
  3105                              <1> 		; beq 1f / yes, i-node not active so return
  3106                              <1> 		; tst (r0)+ / no, jump over error return
  3107 0000AE8D 89D3                <1> 	mov	ebx, edx ; **
  3108 0000AE8F 6689C2              <1> 	mov 	dx, ax ; *
  3109                              <1> 		; mov r1,r2 / move i-number to r2 ;*
  3110                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
  3111                              <1> 			    ; / which is index to u.fp ; **
  3112 0000AE92 C683[86E30000]00    <1> 	mov	byte [ebx+u.fp], 0
  3113                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3114 0000AE99 8B1D[90E30000]      <1> 	mov	ebx, [u.fofp]
  3115                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3116                              <1> fclose_0:
  3117 0000AE9F FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
  3118                              <1> 		; decb 2(r1) / decrement the number of processes 
  3119                              <1> 			   ; / that have opened the file
  3120 0000AEA2 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
  3121                              <1> 		; bge 1f / if all processes haven't closed the file, return
  3122                              <1> 	;
  3123 0000AEA4 6652                <1> 	push	dx ;*
  3124                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3125 0000AEA6 6631C0              <1> 	xor	ax, ax ; 0
  3126 0000AEA9 668943FC            <1> 	mov	[ebx-4], ax ; 0
  3127                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3128 0000AEAD 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
  3129                              <1> 		; tstb	3(r1) / has this file been deleted
  3130 0000AEB0 20C0                <1> 	and	al, al
  3131 0000AEB2 7408                <1> 	jz	short fclose_1
  3132                              <1> 		; beq 2f / no, branch
  3133 0000AEB4 6689D0              <1> 	mov	ax, dx ; *
  3134                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3135                              <1> 	; AX = inode number
  3136 0000AEB7 E868040000          <1> 	call	anyi
  3137                              <1> 		; jsr r0,anyi / free all blocks related to i-number
  3138                              <1> 			    ; / check if file appears in fsp again
  3139                              <1> fclose_1: ; 2:
  3140 0000AEBC 6658                <1> 	pop	ax ; *
  3141                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3142 0000AEBE E84D0F0000          <1> 	call	iclose ; close if it is special file 
  3143                              <1> 		; jsr r0,iclose / check to see if its a special file
  3144                              <1> fclose_2: ; 1:
  3145 0000AEC3 6658                <1> 	pop	ax ; ***
  3146                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3147 0000AEC5 C3                  <1> 	retn
  3148                              <1> 		; rts r0
  3149                              <1> 
  3150                              <1> getf:	; / get the device number and the i-number of an open file
  3151                              <1> 	; 13/05/2015
  3152                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3153                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3154                              <1> 	;
  3155 0000AEC6 89C3                <1> 	mov	ebx, eax
  3156                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3157 0000AEC8 83FB0A              <1> 	cmp	ebx, 10
  3158                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3159 0000AECB 730A                <1>         jnb	short getf2 ; 13/05/2015
  3160                              <1> 	;jnb     error
  3161                              <1> 		; bhis error3 / u.fp is table of users open files, 
  3162                              <1> 			    ; / index in fsp table
  3163 0000AECD 8A9B[86E30000]      <1> 	mov	bl, [ebx+u.fp]
  3164                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
  3165                              <1> 		                  ; / in fsp table
  3166 0000AED3 08DB                <1> 	or	bl, bl
  3167 0000AED5 7503                <1> 	jnz	short getf3
  3168                              <1> 	;jz	short getf4
  3169                              <1> 		; beq 1f / if its zero return
  3170                              <1> getf2:
  3171                              <1> 	; 'File not open !' error (ax=0)
  3172 0000AED7 29C0                <1> 	sub	eax, eax
  3173 0000AED9 C3                  <1> 	retn
  3174                              <1> getf3:	
  3175                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
  3176                              <1> 	;
  3177                              <1> 	; 'fsp' table (10 bytes/entry)
  3178                              <1> 	; bit 15				   bit 0
  3179                              <1> 	; ---|-------------------------------------------
  3180                              <1> 	; r/w|		i-number of open file
  3181                              <1> 	; ---|-------------------------------------------
  3182                              <1> 	;		   device number
  3183                              <1> 	; -----------------------------------------------
  3184                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3185                              <1> 	; -----------------------------------------------
  3186                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3187                              <1> 	; ----------------------|------------------------
  3188                              <1> 	;  flag that says file 	| number of processes
  3189                              <1> 	;   has been deleted	| that have file open 
  3190                              <1> 	; ----------------------|------------------------
  3191                              <1> 	;
  3192 0000AEDA B80A000000          <1> 	mov	eax, 10
  3193 0000AEDF F6E3                <1> 	mul	bl
  3194 0000AEE1 BB[4CE10000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
  3195 0000AEE6 01C3                <1> 	add	ebx, eax
  3196                              <1> 		; asl r1
  3197                              <1> 		; asl r1 / multiply by 8 to get index into 
  3198                              <1> 		       ; / fsp table entry
  3199                              <1> 		; asl r1
  3200                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
  3201                              <1> 			      ; / in the fsp entry
  3202 0000AEE8 891D[90E30000]      <1> 	mov	[u.fofp], ebx
  3203                              <1> 		; mov r1,u.fofp / save address of 3rd word 
  3204                              <1> 			      ; / in fsp entry in u.fofp
  3205 0000AEEE 4B                  <1> 	dec	ebx
  3206 0000AEEF 4B                  <1> 	dec	ebx
  3207 0000AEF0 668B03              <1> 	mov	ax, [ebx]
  3208                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3209 0000AEF3 66A3[60E30000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
  3210                              <1> 			     ;;dev number is in 1 byte
  3211                              <1> 		; mov -(r1),cdev / remove the device number  cdev
  3212 0000AEF9 4B                  <1> 	dec	ebx
  3213 0000AEFA 4B                  <1> 	dec	ebx
  3214 0000AEFB 668B03              <1> 	mov	ax, [ebx]
  3215                              <1> 		; mov -(r1),r1 / and the i-number  r1
  3216                              <1> getf4:	; 1:
  3217 0000AEFE C3                  <1> 	retn
  3218                              <1> 		; rts r0
  3219                              <1> 
  3220                              <1> namei:
  3221                              <1> 	; 04/12/2015 (14 byte file names)
  3222                              <1> 	; 18/10/2015 (nbase, ncount)
  3223                              <1> 	; 12/10/2015
  3224                              <1> 	; 21/08/2015
  3225                              <1> 	; 18/07/2015
  3226                              <1> 	; 02/07/2015
  3227                              <1> 	; 17/06/2015
  3228                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
  3229                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3230                              <1> 	;
  3231                              <1> 	; 'namei' takes a file path name and returns i-number of
  3232                              <1> 	; the file in the current directory or the root directory
  3233                              <1> 	; (if the first character of the pathname is '/').	
  3234                              <1> 	;
  3235                              <1> 	; INPUTS ->
  3236                              <1> 	;    u.namep - points to a file path name
  3237                              <1> 	;    u.cdir - i-number of users directory
  3238                              <1> 	;    u.cdev - device number on which user directory resides	
  3239                              <1> 	; OUTPUTS ->
  3240                              <1> 	;    r1 - i-number of file
  3241                              <1> 	;    cdev
  3242                              <1> 	;    u.dirbuf - points to directory entry where a match 
  3243                              <1> 	;               occurs in the search for file path name.
  3244                              <1> 	;	        If no match u.dirb points to the end of 
  3245                              <1> 	;               the directory and r1 = i-number of the current
  3246                              <1> 	;	        directory.	
  3247                              <1> 	; ((AX = R1))
  3248                              <1> 	;
  3249                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
  3250                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
  3251                              <1> 	;
  3252                              <1> 
  3253 0000AEFF 66A1[84E30000]      <1> 	mov	ax, [u.cdir]
  3254                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3255                              <1> 			      ; / in r1
  3256 0000AF05 668B15[CAE30000]    <1> 	mov	dx, [u.cdrv]
  3257 0000AF0C 668915[60E30000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
  3258                              <1> 				    ; device/drive number is in 1 byte, 
  3259                              <1> 				    ; not in 1 word!
  3260                              <1> 		; mov u.cdev,cdev / device number for users directory 
  3261                              <1> 				; / into cdev
  3262                              <1> 	; 12/10/2015
  3263                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3264                              <1>       	 ; convert virtual (pathname) addr to physical address
  3265 0000AF13 E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
  3266                              <1> 		; esi = physical address of [u.namep]
  3267                              <1> 		; ecx = byte count in the page
  3268 0000AF18 803E2F              <1> 	cmp	byte [esi], '/'
  3269                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3270 0000AF1B 751E                <1> 	jne	short namei_1
  3271                              <1> 		; bne 1f
  3272 0000AF1D FF05[98E30000]      <1> 	inc	dword [u.namep]
  3273                              <1> 		; inc u.namep / go to next char
  3274 0000AF23 6649                <1> 	dec	cx ; remain byte count in the page
  3275 0000AF25 7506                <1> 	jnz	short namei_0
  3276                              <1> 	; 12/10/2015
  3277 0000AF27 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  3278                              <1> 		; esi = physical address (page start + offset)
  3279                              <1> 		; ecx = byte count in the page
  3280 0000AF2C 4E                  <1> 	dec	esi
  3281                              <1> namei_0:
  3282 0000AF2D 46                  <1> 	inc 	esi  ; go to next char
  3283 0000AF2E 66A1[6AE30000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
  3284                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3285 0000AF34 C605[60E30000]00    <1> 	mov	byte [cdev], 0
  3286                              <1> 		; clr cdev / clear device number
  3287                              <1> namei_1: ; 1:
  3288 0000AF3B F606FF              <1> 	test	byte [esi], 0FFh
  3289 0000AF3E 74BE                <1> 	jz	short getf4
  3290                              <1> 	;jz      nig
  3291                              <1> 		; tstb *u.namep / is the character in file name a nul
  3292                              <1> 		; beq nig / yes, end of file name reached; 
  3293                              <1> 			; / branch to "nig"
  3294                              <1> namei_2: ; 1:
  3295                              <1> 	; 18/10/2015
  3296 0000AF40 8935[F8E30000]      <1> 	mov 	[nbase], esi
  3297 0000AF46 66890D[FCE30000]    <1> 	mov 	[ncount], cx
  3298                              <1> 	;
  3299                              <1> 	;mov	dx, 2
  3300 0000AF4D B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
  3301 0000AF4F E8C20E0000          <1> 	call	access
  3302                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
  3303                              <1> 	; 'access' will not return here if user has not "r" permission !
  3304 0000AF54 66F705[42E00000]00- <1> 	test 	word [i.flgs], 4000h
  3304 0000AF5C 40                  <1>
  3305                              <1> 		; bit $40000,i.flgs / directory i-node?
  3306 0000AF5D 746A                <1>         jz      short namei_err
  3307                              <1> 		; beq error3 / no, got an error
  3308                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3309 0000AF5F 31C0                <1> 	xor	eax, eax
  3310 0000AF61 A3[9CE30000]        <1> 	mov	[u.off], eax ; 0
  3311 0000AF66 66A1[09E40000]      <1> 	mov	ax, [i.size]
  3312 0000AF6C A3[94E30000]        <1> 	mov	[u.dirp], eax
  3313                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
  3314                              <1> 		; clr u.off / u.off is file offset used by user
  3315 0000AF71 C705[90E30000]-     <1> 	mov	dword [u.fofp], u.off
  3315 0000AF77 [9CE30000]          <1>
  3316                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
  3317                              <1> 				  ; / the offset portion of fsp entry
  3318                              <1> namei_3: ; 2:
  3319 0000AF7B C705[A0E30000]-     <1> 	mov	dword [u.base], u.dirbuf
  3319 0000AF81 [B2E30000]          <1>
  3320                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  3321                              <1> 				    ; / copied from a directory
  3322 0000AF85 C705[A4E30000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  3322 0000AF8D 0000                <1>
  3323                              <1>  		; mov $10.,u.count / u.count is byte count 
  3324                              <1> 				 ; / for reads and writes
  3325 0000AF8F 66A1[05E40000]      <1> 	mov 	ax, [ii]
  3326                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  3327 0000AF95 FE05[E7E30000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  3328 0000AF9B E815090000          <1>     	call	readi
  3329                              <1> 		; jsr r0,readi / read 10. bytes of file 
  3330                              <1> 		      ; with i-number (r1); i.e. read a directory entry
  3331 0000AFA0 8B0D[A8E30000]      <1> 	mov 	ecx, [u.nread]
  3332 0000AFA6 09C9                <1> 	or 	ecx, ecx
  3333                              <1> 		; tst u.nread
  3334 0000AFA8 741B                <1> 	jz	short nib
  3335                              <1> 		; ble nib / gives error return
  3336                              <1> 	;
  3337 0000AFAA 668B1D[B2E30000]    <1> 	mov 	bx, [u.dirbuf]
  3338 0000AFB1 6621DB              <1> 	and 	bx, bx       
  3339                              <1> 		; tst u.dirbuf /
  3340 0000AFB4 7522                <1> 	jnz	short namei_4
  3341                              <1> 		; bne 3f / branch when active directory entry 
  3342                              <1> 		       ; / (i-node word in entry non zero)
  3343 0000AFB6 A1[9CE30000]        <1> 	mov	eax, [u.off]
  3344 0000AFBB 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  3345 0000AFBE A3[94E30000]        <1> 	mov	[u.dirp], eax
  3346                              <1> 		; mov u.off,u.dirp
  3347                              <1> 		; sub $10.,u.dirp
  3348 0000AFC3 EBB6                <1> 	jmp	short namei_3
  3349                              <1> 		; br 2b
  3350                              <1> 
  3351                              <1> 	; 18/07/2013
  3352                              <1> nib: 
  3353 0000AFC5 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  3354 0000AFC7 F9                  <1> 	stc
  3355                              <1> nig:
  3356 0000AFC8 C3                  <1> 	retn
  3357                              <1> 
  3358                              <1> namei_err:
  3359                              <1> 	; 16/06/2015
  3360 0000AFC9 C705[D5E30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  3360 0000AFD1 0000                <1>
  3361 0000AFD3 E92BF1FFFF          <1> 	jmp	error
  3362                              <1> 
  3363                              <1> namei_4: ; 3:
  3364                              <1> 	; 18/10/2015
  3365                              <1> 	; 12/10/2015
  3366                              <1> 	; 21/08/2015
  3367                              <1> 	; 18/07/2015
  3368 0000AFD8 8B2D[98E30000]      <1> 	mov	ebp, [u.namep]
  3369                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  3370 0000AFDE BF[B4E30000]        <1> 	mov 	edi, u.dirbuf + 2
  3371                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
  3372                              <1> 	; 18/10/2015
  3373 0000AFE3 8B35[F8E30000]      <1> 	mov	esi, [nbase]	
  3374 0000AFE9 668B0D[FCE30000]    <1> 	mov	cx, [ncount]
  3375                              <1> 	;
  3376 0000AFF0 6621C9              <1> 	and	cx, cx
  3377 0000AFF3 7505                <1> 	jnz	short namei_5	
  3378                              <1> 	;
  3379 0000AFF5 E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3380                              <1> 		; esi = physical address (page start + offset)
  3381                              <1> 		; ecx = byte count in the page
  3382                              <1> namei_5: ; 3:
  3383 0000AFFA 45                  <1> 	inc	ebp ; 18/07/2015
  3384 0000AFFB AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
  3385                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
  3386 0000AFFC 08C0                <1> 	or 	al, al
  3387 0000AFFE 741D                <1> 	jz 	short namei_7
  3388                              <1> 		; beq 3f / if char is nul, then the last char in string
  3389                              <1> 			; / has been moved
  3390 0000B000 3C2F                <1> 	cmp	al, '/'
  3391                              <1> 		; cmp r4,$'/ / is char a </>
  3392 0000B002 7419                <1> 	je 	short namei_7
  3393                              <1> 		; beq 3f	
  3394                              <1> 	; 12/10/2015
  3395 0000B004 6649                <1> 	dec	cx ; remain byte count in the page
  3396 0000B006 7505                <1> 	jnz	short namei_6
  3397 0000B008 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3398                              <1> 		; esi = physical address (page start + offset)
  3399                              <1> 		; ecx = byte count in the page
  3400                              <1> namei_6:
  3401 0000B00D 81FF[C2E30000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3402                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
  3403                              <1> 				     ; / all 8 bytes of file name
  3404 0000B013 74E5                <1> 	je	short namei_5
  3405                              <1> 		; beq 3b
  3406 0000B015 AE                  <1> 	scasb	
  3407                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  3408                              <1> 			      ; / char read from directory
  3409 0000B016 74E2                <1> 	je 	short namei_5
  3410                              <1> 		; beq 3b / branch if chars match
  3411                              <1> 
  3412 0000B018 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
  3413                              <1> 		; br 2b / file names do not match go to next directory entry
  3414                              <1> namei_7: ; 3:
  3415 0000B01D 81FF[C2E30000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3416                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
  3417 0000B023 740A                <1> 	je	short namei_8
  3418                              <1> 		; beq 3f
  3419 0000B025 8A27                <1> 	mov 	ah, [edi]
  3420                              <1> 	;inc 	edi 
  3421 0000B027 20E4                <1> 	and 	ah, ah
  3422                              <1> 		; tstb (r3)+ /
  3423 0000B029 0F854CFFFFFF        <1>         jnz     namei_3
  3424                              <1> 		; bne 2b
  3425                              <1> namei_8: ; 3
  3426 0000B02F 892D[98E30000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
  3427                              <1> 		; mov r2,u.namep / u.namep points to char 
  3428                              <1> 			       ; / following a / or nul
  3429                              <1> 	;mov	bx, [u.dirbuf]
  3430                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
  3431                              <1> 				; / entry to r1
  3432 0000B035 20C0                <1> 	and 	al, al
  3433                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
  3434                              <1> 		      ;  / if r4 = </> then go to next directory
  3435                              <1> 	; mov	ax, bx
  3436 0000B037 66A1[B2E30000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
  3437 0000B03D 0F85FDFEFFFF        <1>         jnz     namei_2 
  3438                              <1> 		; bne 1b
  3439                              <1> 	; AX = i-number of the file
  3440                              <1> ;;nig:
  3441 0000B043 C3                  <1> 	retn
  3442                              <1> 		; tst (r0)+ / gives non-error return
  3443                              <1> ;;nib:
  3444                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
  3445                              <1> 		       ; ax = 0 -> file not found 
  3446                              <1> ;;	stc	; 27/05/2013
  3447                              <1> ;;	retn
  3448                              <1> 		; rts r0
  3449                              <1> 
  3450                              <1> trans_addr_nmbp:
  3451                              <1> 	; 18/10/2015
  3452                              <1> 	; 12/10/2015
  3453 0000B044 8B2D[98E30000]      <1> 	mov 	ebp, [u.namep]
  3454                              <1> trans_addr_nm: 
  3455                              <1> 	; Convert virtual (pathname) address to physical address
  3456                              <1> 	; (Retro UNIX 386 v1 feature only !)
  3457                              <1> 	; 18/10/2015
  3458                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  3459                              <1> 	; 02/07/2015
  3460                              <1> 	; 17/06/2015
  3461                              <1> 	; 16/06/2015
  3462                              <1> 	;
  3463                              <1> 	; INPUTS: 
  3464                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  3465                              <1> 	;	[u.pgdir] = user's page directory
  3466                              <1> 	; OUTPUT:
  3467                              <1> 	;       esi = physical address of the pathname
  3468                              <1> 	;	ecx = remain byte count in the page
  3469                              <1> 	;
  3470                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
  3471                              <1> 	;
  3472 0000B04A 833D[DDE30000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  3473 0000B051 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  3474                              <1> 				     ; it is already physical address
  3475 0000B053 50                  <1>    	push	eax	
  3476 0000B054 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  3477 0000B056 E84D88FFFF          <1>        	call	get_physical_addr ; get physical address
  3478 0000B05B 7204                <1> 	jc	short tr_addr_nm_err
  3479                              <1> 	; 18/10/2015
  3480                              <1> 	; eax = physical address 
  3481                              <1> 	; cx = remain byte count in page (1-4096) 
  3482                              <1> 		; 12/10/2015 (cx = [u.pncount])
  3483 0000B05D 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  3484 0000B05F 58                  <1> 	pop	eax 
  3485 0000B060 C3                  <1> 	retn
  3486                              <1> 
  3487                              <1> tr_addr_nm_err:
  3488 0000B061 A3[D5E30000]        <1> 	mov	[u.error], eax
  3489                              <1> 	;pop 	eax
  3490 0000B066 E998F0FFFF          <1> 	jmp	error
  3491                              <1> 
  3492                              <1> trans_addr_nmk:
  3493                              <1> 	; 12/10/2015
  3494                              <1> 	; 02/07/2015
  3495 0000B06B 8B35[98E30000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  3496 0000B071 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  3497 0000B075 C3                  <1> 	retn
  3498                              <1> 
  3499                              <1> syschdir:
  3500                              <1> 	; / makes the directory specified in the argument
  3501                              <1> 	; / the current directory
  3502                              <1> 	;
  3503                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3504                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3505                              <1> 	;
  3506                              <1> 	; 'syschdir' makes the directory specified in its argument
  3507                              <1> 	; the current working directory.
  3508                              <1> 	;
  3509                              <1> 	; Calling sequence:
  3510                              <1> 	;	syschdir; name
  3511                              <1> 	; Arguments:
  3512                              <1> 	;	name - address of the path name of a directory
  3513                              <1> 	;	       terminated by nul byte.	
  3514                              <1> 	; Inputs: -
  3515                              <1> 	; Outputs: -
  3516                              <1> 	; ...............................................................
  3517                              <1> 	;				
  3518                              <1> 	; Retro UNIX 8086 v1 modification:
  3519                              <1> 	;	 The user/application program puts address of 
  3520                              <1> 	;	 the path name in BX register as 'syschdir' 
  3521                              <1> 	; 	 system call argument.
  3522                              <1> 
  3523 0000B076 891D[98E30000]      <1> 	mov	[u.namep], ebx
  3524                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  3525 0000B07C E87EFEFFFF          <1> 	call	namei
  3526                              <1> 		; jsr r0,namei / find its i-number
  3527                              <1> 	;jc	error
  3528                              <1> 		; br error3
  3529 0000B081 730F                <1> 	jnc	short syschdir0
  3530                              <1> 	; 'directory not found !' error
  3531 0000B083 C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  3531 0000B08B 0000                <1>
  3532 0000B08D E971F0FFFF          <1> 	jmp	error
  3533                              <1> syschdir0:
  3534 0000B092 E87F0D0000          <1> 	call	access
  3535                              <1> 		; jsr r0,access; 2 / get i-node into core
  3536 0000B097 66F705[42E00000]00- <1> 	test	word [i.flgs], 4000h
  3536 0000B09F 40                  <1>
  3537                              <1> 		; bit $40000,i.flgs / is it a directory?
  3538                              <1> 	;jz	error 
  3539                              <1> 		; beq error3 / no error
  3540 0000B0A0 750F                <1> 	jnz	short syschdir1
  3541 0000B0A2 C705[D5E30000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  3541 0000B0AA 0000                <1>
  3542 0000B0AC E952F0FFFF          <1> 	jmp	error
  3543                              <1> syschdir1:
  3544 0000B0B1 66A3[84E30000]      <1> 	mov	[u.cdir], ax
  3545                              <1> 		; mov r1,u.cdir / move i-number to users 
  3546                              <1> 			      ; / current directory
  3547 0000B0B7 66A1[60E30000]      <1> 	mov	ax, [cdev]
  3548 0000B0BD 66A3[CAE30000]      <1> 	mov	[u.cdrv], ax
  3549                              <1> 		; mov cdev,u.cdev / move its device to users 
  3550                              <1> 			        ; / current device
  3551 0000B0C3 E95BF0FFFF          <1> 	jmp	sysret
  3552                              <1> 		; br sysret3
  3553                              <1> 	
  3554                              <1> syschmod: ; < change mode of file >
  3555                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3556                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3557                              <1> 	;
  3558                              <1> 	; 'syschmod' changes mode of the file whose name is given as
  3559                              <1> 	; null terminated string pointed to by 'name' has it's mode 
  3560                              <1> 	; changed to 'mode'.
  3561                              <1> 	;
  3562                              <1> 	; Calling sequence:
  3563                              <1> 	;	syschmod; name; mode
  3564                              <1> 	; Arguments:
  3565                              <1> 	;	name - address of the file name
  3566                              <1> 	;	       terminated by null byte.
  3567                              <1> 	;	mode - (new) mode/flags < attributes >
  3568                              <1> 	;	
  3569                              <1> 	; Inputs: -
  3570                              <1> 	; Outputs: -
  3571                              <1> 	; ...............................................................
  3572                              <1> 	;				
  3573                              <1> 	; Retro UNIX 8086 v1 modification: 
  3574                              <1> 	;       'syschmod' system call has two arguments; so,
  3575                              <1> 	;	* 1st argument, name is pointed to by BX register
  3576                              <1> 	;	* 2nd argument, mode is in CX register
  3577                              <1> 	;
  3578                              <1> 	; Mode bits (Flags):
  3579                              <1> 	;	bit 0 - write permission for non-owner (1)
  3580                              <1> 	;	bit 1 - read permission for non-owner (2)
  3581                              <1> 	;	bit 2 - write permission for owner (4)
  3582                              <1> 	;	bit 3 - read permission for owner (8)
  3583                              <1> 	;	bit 4 - executable flag (16) 	
  3584                              <1> 	;	bit 5 - set user ID on execution flag (32) 
  3585                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
  3586                              <1> 	;	bit 12 - large file flag (4096)
  3587                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
  3588                              <1> 	;	bit 14 - directory flag (16384)
  3589                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
  3590                              <1> 
  3591                              <1> 	; / name; mode
  3592 0000B0C8 E814000000          <1> 	call	isown
  3593                              <1> 		;jsr r0,isown / get the i-node and check user status
  3594 0000B0CD 66F705[42E00000]00- <1> 	test	word [i.flgs], 4000h
  3594 0000B0D5 40                  <1>
  3595                              <1> 		; bit	$40000,i.flgs / directory?
  3596 0000B0D6 7402                <1> 	jz	short syschmod1
  3597                              <1> 		; beq 2f / no
  3598                              <1> 	; AL = (new) mode
  3599 0000B0D8 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
  3600                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
  3601                              <1> 			   ; / executable modes
  3602                              <1> syschmod1: ; 2:
  3603 0000B0DA A2[42E00000]        <1> 	mov	[i.flgs], al	
  3604                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
  3605 0000B0DF EB42                <1> 	jmp	short isown1
  3606                              <1> 		; br 1f
  3607                              <1> 
  3608                              <1> isown:
  3609                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3610                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3611                              <1> 	;
  3612                              <1> 	; 'isown' is given a file name (the 1st argument).
  3613                              <1> 	;  It find the i-number of that file via 'namei' 
  3614                              <1> 	;  then gets the i-node into core via 'iget'.
  3615                              <1> 	;  It then tests to see if the user is super user. 
  3616                              <1> 	;  If not, it cheks to see if the user is owner of 
  3617                              <1> 	;  the file. If he is not an error occurs.
  3618                              <1> 	;  If user is the owner 'setimod' is called to indicate
  3619                              <1> 	;  the inode has been modificed and the 2nd argument of
  3620                              <1> 	;  the call is put in r2.
  3621                              <1> 	;
  3622                              <1> 	; INPUTS ->
  3623                              <1> 	;    arguments of syschmod and syschown calls
  3624                              <1> 	; OUTPUTS ->
  3625                              <1> 	;    u.uid - id of user
  3626                              <1> 	;    imod - set to a 1
  3627                              <1> 	;    r2 - contains second argument of the system call				 	
  3628                              <1> 	;
  3629                              <1> 	;   ((AX=R2) output as 2nd argument)
  3630                              <1> 	;
  3631                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  3632                              <1> 	;
  3633                              <1> 		; jsr r0,arg2 / u.namep points to file name
  3634                              <1> 	;; ! 2nd argument on top of stack !
  3635                              <1> 	;; 22/06/2015 - 32 bit modifications
  3636                              <1> 	;; 07/07/2013
  3637 0000B0E1 891D[98E30000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  3638 0000B0E7 51                  <1> 	push 	ecx ;; 2nd argument
  3639                              <1> 	;;
  3640 0000B0E8 E812FEFFFF          <1> 	call	namei
  3641                              <1> 		; jsr r0,namei / get its i-number
  3642                              <1>        ; Retro UNIX 8086 v1 modification !
  3643                              <1>        ; ax = 0 -> file not found 
  3644                              <1> 	;and	ax, ax
  3645                              <1> 	;jz	error
  3646                              <1> 	;jc	error ; 27/05/2013
  3647                              <1> 		; br error3
  3648 0000B0ED 730F                <1> 	jnc	short isown0
  3649                              <1> 	; 'file not found !' error
  3650 0000B0EF C705[D5E30000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3650 0000B0F7 0000                <1>
  3651 0000B0F9 E905F0FFFF          <1> 	jmp	error
  3652                              <1> isown0:
  3653 0000B0FE E8080D0000          <1> 	call	iget
  3654                              <1> 		; jsr r0,iget / get i-node into core
  3655 0000B103 A0[CCE30000]        <1> 	mov	al, [u.uid] ; 02/08/2013
  3656 0000B108 08C0                <1> 	or	al, al
  3657                              <1> 		; tstb u.uid / super user?
  3658 0000B10A 7417                <1> 	jz	short isown1
  3659                              <1> 		; beq 1f / yes, branch
  3660 0000B10C 3A05[45E00000]      <1> 	cmp	al, [i.uid]
  3661                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
  3662                              <1> 				 ; / the file
  3663                              <1> 	;jne	error
  3664                              <1> 		; beq 1f / yes
  3665                              <1> 		; jmp error3 / no, error
  3666 0000B112 740F                <1> 	je	short isown1
  3667                              <1> 
  3668 0000B114 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
  3668 0000B11C 0000                <1>
  3669                              <1> 			;  'permission denied !' error
  3670 0000B11E E9E0EFFFFF          <1> 	jmp	error
  3671                              <1> isown1: ; 1:
  3672 0000B123 E8EA0C0000          <1> 	call	setimod
  3673                              <1> 		; jsr r0,setimod / indicates 
  3674                              <1> 		;	       ; / i-node has been modified
  3675 0000B128 58                  <1> 	pop	eax ; 2nd argument
  3676                              <1> 		; mov (sp)+,r2 / mode is put in r2 
  3677                              <1> 		       ; / (u.off put on stack with 2nd arg)
  3678 0000B129 C3                  <1> 	retn
  3679                              <1> 		; rts r0
  3680                              <1> 
  3681                              <1> ;;arg:  ; < get system call arguments >
  3682                              <1> 	; 'arg' extracts an argument for a routine whose call is 
  3683                              <1> 	; of form:
  3684                              <1> 	;	sys 'routine' ; arg1
  3685                              <1> 	;		or
  3686                              <1> 	;	sys 'routine' ; arg1 ; arg2
  3687                              <1> 	;		or
  3688                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
  3689                              <1> 	;	
  3690                              <1> 	; INPUTS ->
  3691                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
  3692                              <1> 	;	This pointers's value is actually the value of
  3693                              <1> 	;	update pc at the the trap to sysent (unkni) is
  3694                              <1> 	;	made to process the sys instruction
  3695                              <1> 	;    r0 - contains the return address for the routine
  3696                              <1> 	;	that called arg. The data in the word pointer 
  3697                              <1> 	;	to by the return address is used as address
  3698                              <1> 	;	in which the extracted argument is stored   		
  3699                              <1> 	;    	
  3700                              <1> 	; OUTPUTS ->
  3701                              <1> 	;    'address' - contains the extracted argument 
  3702                              <1> 	;    u.sp+18 - is incremented by 2 
  3703                              <1> 	;    r1 - contains the extracted argument
  3704                              <1> 	;    r0 - points to the next instruction to be
  3705                              <1> 	;	 executed in the calling routine.
  3706                              <1> 	;
  3707                              <1>   
  3708                              <1> 	; mov u.sp,r1
  3709                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
  3710                              <1> 			; / into argument of arg2
  3711                              <1> 	; add $2,18.(r1) / point pc on stack 
  3712                              <1> 			      ; / to next system argument
  3713                              <1> 	; rts r0
  3714                              <1> 
  3715                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
  3716                              <1> 	; 'arg2' takes first argument in system call
  3717                              <1> 	;  (pointer to name of the file) and puts it in location
  3718                              <1> 	;  u.namep; takes second argument and puts it in u.off
  3719                              <1> 	;  and on top of the stack
  3720                              <1> 	;	
  3721                              <1> 	; INPUTS ->
  3722                              <1> 	;    u.sp, r0
  3723                              <1> 	;    	
  3724                              <1> 	; OUTPUTS ->
  3725                              <1> 	;    u.namep
  3726                              <1> 	;    u.off 
  3727                              <1> 	;    u.off pushed on stack
  3728                              <1> 	;    r1
  3729                              <1> 	;
  3730                              <1> 
  3731                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
  3732                              <1> 				; / first arg in sys call
  3733                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
  3734                              <1> 				; / second arg in sys call
  3735                              <1> 	; mov r0,r1 / r0 points to calling routine
  3736                              <1> 	; mov (sp),r0 / put operation code back in r0
  3737                              <1> 	; mov u.off,(sp) / put pointer to second argument 
  3738                              <1> 			; / on stack
  3739                              <1> 	; jmp (r1) / return to calling routine
  3740                              <1> 
  3741                              <1> syschown: ; < change owner of file >
  3742                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3743                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3744                              <1> 	;
  3745                              <1> 	; 'syschown' changes the owner of the file whose name is given
  3746                              <1> 	; as null terminated string pointed to by 'name' has it's owner
  3747                              <1> 	; changed to 'owner'
  3748                              <1> 	;
  3749                              <1> 	; Calling sequence:
  3750                              <1> 	;	syschown; name; owner
  3751                              <1> 	; Arguments:
  3752                              <1> 	;	name - address of the file name
  3753                              <1> 	;	       terminated by null byte.
  3754                              <1> 	;	owner - (new) owner (number/ID)
  3755                              <1> 	;	
  3756                              <1> 	; Inputs: -
  3757                              <1> 	; Outputs: -
  3758                              <1> 	; ...............................................................
  3759                              <1> 	;				
  3760                              <1> 	; Retro UNIX 8086 v1 modification: 
  3761                              <1> 	;       'syschown' system call has two arguments; so,
  3762                              <1> 	;	* 1st argument, name is pointed to by BX register
  3763                              <1> 	;	* 2nd argument, owner number is in CX register
  3764                              <1> 	;
  3765                              <1> 	; / name; owner
  3766 0000B12A E8B2FFFFFF          <1> 	call	isown
  3767                              <1> 		; jsr r0,isown / get the i-node and check user status
  3768 0000B12F 803D[CCE30000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
  3769                              <1> 		; tstb u.uid / super user
  3770 0000B136 7418                <1> 	jz	short syschown1
  3771                              <1> 		; beq 2f / yes, 2f
  3772 0000B138 F605[42E00000]20    <1>         test    byte [i.flgs], 20h ; 32
  3773                              <1> 		; bit $40,i.flgs / no, set userid on execution?
  3774                              <1> 	;jnz	error
  3775                              <1> 		; bne 3f / yes error, could create Trojan Horses
  3776 0000B13F 740F                <1> 	jz	short syschown1
  3777                              <1> 	; 'permission denied !'
  3778 0000B141 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  3778 0000B149 0000                <1>
  3779 0000B14B E9B3EFFFFF          <1> 	jmp	error
  3780                              <1> syschown1: ; 2:
  3781                              <1> 	; AL = owner (number/ID)
  3782 0000B150 A2[45E00000]        <1> 	mov	[i.uid], al ; 23/06/2015
  3783                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
  3784                              <1> 			       ; / in the i-node
  3785 0000B155 E9C9EFFFFF          <1> 	jmp	sysret
  3786                              <1> 	; 1: 
  3787                              <1> 		; jmp sysret4
  3788                              <1> 	; 3:
  3789                              <1> 		; jmp	error
  3790                              <1> 
  3791                              <1> systime: ; / get time of year
  3792                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3793                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  3794                              <1> 	;
  3795                              <1> 	; 20/06/2013
  3796                              <1> 	; 'systime' gets the time of the year.
  3797                              <1> 	; The present time is put on the stack.
  3798                              <1> 	;
  3799                              <1> 	; Calling sequence:
  3800                              <1> 	;	systime
  3801                              <1> 	; Arguments: -
  3802                              <1> 	;	
  3803                              <1> 	; Inputs: -
  3804                              <1> 	; Outputs: sp+2, sp+4 - present time
  3805                              <1> 	; ...............................................................
  3806                              <1> 	;	
  3807                              <1> 	; Retro UNIX 8086 v1 modification: 
  3808                              <1> 	;       'systime' system call will return to the user
  3809                              <1> 	;	with unix time (epoch) in DX:AX register pair
  3810                              <1> 	;
  3811                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
  3812                              <1> 	;	system call for PC compatibility !!		 	
  3813                              <1> 
  3814 0000B15A E8B90C0000          <1> 	call 	epoch
  3815 0000B15F A3[80E30000]        <1> 	mov 	[u.r0], eax
  3816                              <1> 		; mov s.time,4(sp)
  3817                              <1> 		; mov s.time+2,2(sp) / put the present time 
  3818                              <1> 				   ; / on the stack
  3819                              <1> 		; br sysret4
  3820 0000B164 E9BAEFFFFF          <1> 	jmp	sysret 
  3821                              <1> 
  3822                              <1> sysstime: ; / set time
  3823                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3824                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3825                              <1> 	;
  3826                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
  3827                              <1> 	;
  3828                              <1> 	; Calling sequence:
  3829                              <1> 	;	sysstime
  3830                              <1> 	; Arguments: -
  3831                              <1> 	;	
  3832                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
  3833                              <1> 	; Outputs: -
  3834                              <1> 	; ...............................................................
  3835                              <1> 	;	
  3836                              <1> 	; Retro UNIX 8086 v1 modification: 
  3837                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
  3838                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
  3839                              <1> 	; 
  3840                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  3841                              <1> 	;	to get sysstime system call arguments from the user;
  3842                              <1> 	;	* 1st argument, lowword of unix time is in BX register
  3843                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
  3844                              <1> 	;
  3845                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
  3846                              <1> 	;	system call for PC compatibility !!	
  3847                              <1> 
  3848 0000B169 803D[CCE30000]00    <1> 	cmp	byte [u.uid], 0
  3849                              <1> 		; tstb u.uid / is user the super user
  3850                              <1> 	;ja	error
  3851                              <1> 		; bne error4 / no, error
  3852 0000B170 760F                <1> 	jna	short systime1
  3853                              <1> 	; 'permission denied !'
  3854 0000B172 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  3854 0000B17A 0000                <1>
  3855 0000B17C E982EFFFFF          <1> 	jmp	error
  3856                              <1> systime1:
  3857                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
  3858                              <1> 	; EBX = unix (epoch) time (from user)
  3859 0000B181 89D8                <1> 	mov	eax, ebx
  3860 0000B183 E8910C0000          <1> 	call 	set_date_time
  3861                              <1> 		; mov 4(sp),s.time
  3862                              <1> 		; mov 2(sp),s.time+2 / set the system time
  3863 0000B188 E996EFFFFF          <1> 	jmp	sysret
  3864                              <1> 		; br sysret4
  3865                              <1> 
  3866                              <1> sysbreak:
  3867                              <1> 	; 18/10/2015
  3868                              <1> 	; 07/10/2015
  3869                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3870                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  3871                              <1> 	;
  3872                              <1> 	; 'sysbreak' sets the programs break points. 
  3873                              <1> 	; It checks the current break point (u.break) to see if it is
  3874                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  3875                              <1> 	; even address (if it was odd) and the area between u.break
  3876                              <1> 	; and the stack is cleared. The new breakpoint is then put
  3877                              <1> 	; in u.break and control is passed to 'sysret'.
  3878                              <1> 	;
  3879                              <1> 	; Calling sequence:
  3880                              <1> 	;	sysbreak; addr
  3881                              <1> 	; Arguments: -
  3882                              <1> 	;	
  3883                              <1> 	; Inputs: u.break - current breakpoint
  3884                              <1> 	; Outputs: u.break - new breakpoint 
  3885                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  3886                              <1> 	; ...............................................................
  3887                              <1> 	;	
  3888                              <1> 	; Retro UNIX 8086 v1 modification:
  3889                              <1> 	;	The user/application program puts breakpoint address
  3890                              <1> 	;       in BX register as 'sysbreak' system call argument.
  3891                              <1> 	; 	(argument transfer method 1)
  3892                              <1> 	;
  3893                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  3894                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  3895                              <1> 	;  NOTE:
  3896                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  3897                              <1> 	;	'u.break' address) of user's memory for original unix's
  3898                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  3899                              <1> 
  3900                              <1> 		; mov u.break,r1 / move users break point to r1
  3901                              <1> 		; cmp r1,$core / is it the same or lower than core?
  3902                              <1> 		; blos 1f / yes, 1f
  3903                              <1> 	; 23/06/2015
  3904 0000B18D 8B2D[ACE30000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  3905                              <1> 	;and	ebp, ebp
  3906                              <1> 	;jz	short sysbreak_3 
  3907                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  3908                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  3909 0000B193 8B15[78E30000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  3910 0000B199 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  3911                              <1> 	; 07/10/2015
  3912 0000B19C 891D[ACE30000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  3913                              <1> 	;
  3914 0000B1A2 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  3915                              <1> 			   ; with top of user's stack (virtual!)
  3916 0000B1A4 7327                <1> 	jnb	short sysbreak_3
  3917                              <1> 		; cmp r1,sp / is it the same or higher 
  3918                              <1> 			  ; / than the stack?
  3919                              <1> 		; bhis 1f / yes, 1f
  3920 0000B1A6 89DE                <1> 	mov	esi, ebx
  3921 0000B1A8 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  3922 0000B1AA 7621                <1> 	jna	short sysbreak_3 
  3923                              <1> 	;push	ebx
  3924                              <1> sysbreak_1:
  3925 0000B1AC 89EB                <1> 	mov	ebx, ebp  
  3926 0000B1AE E8F586FFFF          <1> 	call	get_physical_addr ; get physical address
  3927 0000B1B3 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
  3928                              <1> 	; 18/10/2015
  3929 0000B1B9 89C7                <1> 	mov	edi, eax 
  3930 0000B1BB 29C0                <1> 	sub	eax, eax ; 0
  3931                              <1> 		 ; ECX = remain byte count in page (1-4096)
  3932 0000B1BD 39CE                <1> 	cmp	esi, ecx
  3933 0000B1BF 7302                <1> 	jnb	short sysbreak_2
  3934 0000B1C1 89F1                <1> 	mov	ecx, esi
  3935                              <1> sysbreak_2:
  3936 0000B1C3 29CE                <1> 	sub	esi, ecx
  3937 0000B1C5 01CD                <1> 	add	ebp, ecx
  3938 0000B1C7 F3AA                <1> 	rep 	stosb
  3939 0000B1C9 09F6                <1> 	or	esi, esi
  3940 0000B1CB 75DF                <1> 	jnz	short sysbreak_1
  3941                              <1> 	;
  3942                              <1> 		; bit $1,r1 / is it an odd address
  3943                              <1> 		; beq 2f / no, its even
  3944                              <1> 		; clrb (r1)+ / yes, make it even
  3945                              <1> 	; 2: / clear area between the break point and the stack
  3946                              <1> 		; cmp r1,sp / is it higher or same than the stack
  3947                              <1> 		; bhis 1f / yes, quit
  3948                              <1> 		; clr (r1)+ / clear word
  3949                              <1> 		; br 2b / go back
  3950                              <1> 	;pop	ebx
  3951                              <1> sysbreak_3: ; 1:
  3952                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  3953                              <1> 		; jsr r0,arg; u.break / put the "address" 
  3954                              <1> 			; / in u.break (set new break point)
  3955                              <1> 		; br sysret4 / br sysret
  3956 0000B1CD E951EFFFFF          <1> 	jmp	sysret
  3957                              <1> 
  3958                              <1> 
  3959                              <1> maknod: 
  3960                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  3961                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  3962                              <1> 	;
  3963                              <1> 	; 'maknod' creates an i-node and makes a directory entry
  3964                              <1> 	; for this i-node in the current directory.
  3965                              <1> 	;
  3966                              <1> 	; INPUTS ->
  3967                              <1> 	;    r1 - contains mode
  3968                              <1> 	;    ii - current directory's i-number	
  3969                              <1> 	;    	
  3970                              <1> 	; OUTPUTS ->
  3971                              <1> 	;    u.dirbuf - contains i-number of free i-node 
  3972                              <1> 	;    i.flgs - flags in new i-node 
  3973                              <1> 	;    i.uid - filled with u.uid
  3974                              <1> 	;    i.nlks - 1 is put in the number of links
  3975                              <1> 	;    i.ctim - creation time				
  3976                              <1> 	;    i.ctim+2 - modification time
  3977                              <1> 	;    imod - set via call to setimod
  3978                              <1> 	;	
  3979                              <1> 	; ((AX = R1)) input
  3980                              <1> 	;
  3981                              <1> 	; (Retro UNIX Prototype : 
  3982                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
  3983                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  3984                              <1> 
  3985                              <1> 	; / r1 contains the mode
  3986 0000B1D2 80CC80              <1> 	or 	ah, 80h  ; 10000000b
  3987                              <1> 		; bis	$100000,r1 / allocate flag set
  3988 0000B1D5 6650                <1> 	push	ax
  3989                              <1> 		; mov r1,-(sp) / put mode on stack
  3990                              <1> 	; 31/07/2013
  3991 0000B1D7 66A1[05E40000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
  3992                              <1> 		; mov ii,r1 / move current i-number to r1
  3993 0000B1DD B201                <1> 	mov	dl, 1 ; owner flag mask
  3994 0000B1DF E8320C0000          <1> 	call	access	
  3995                              <1> 		; jsr r0,access; 1 / get its i-node into core
  3996 0000B1E4 6650                <1> 	push	ax
  3997                              <1> 		; mov r1,-(sp) / put i-number on stack
  3998 0000B1E6 66B82800            <1> 	mov	ax, 40
  3999                              <1> 		; mov $40.,r1 / r1 = 40
  4000                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
  4001 0000B1EA 6640                <1> 	inc	ax
  4002                              <1> 		; inc r1 / r1 = r1 + 1
  4003 0000B1EC E8290C0000          <1> 	call	imap
  4004                              <1> 		; jsr r0,imap / get byte address and bit position in 
  4005                              <1> 			    ; /	inode map in r2 & m
  4006                              <1>           ; DX (MQ) has a 1 in the calculated bit position
  4007                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
  4008                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
  4009                              <1> 	;	       Inode count must be checked here
  4010                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
  4011 0000B1F1 8413                <1> 	test	[ebx], dl
  4012                              <1> 		; bitb mq,(r2) / is the i-node active
  4013 0000B1F3 75F5                <1> 	jnz	short maknod1
  4014                              <1> 		; bne 1b / yes, try the next one
  4015 0000B1F5 0813                <1> 	or	[ebx], dl
  4016                              <1> 		; bisb mq,(r2) / no, make it active 
  4017                              <1> 			     ; / (put a 1 in the bit map)
  4018 0000B1F7 E80F0C0000          <1> 	call	iget
  4019                              <1> 		; jsr r0,iget / get i-node into core
  4020 0000B1FC 66F705[42E00000]00- <1> 	test	word [i.flgs], 8000h 
  4020 0000B204 80                  <1>
  4021                              <1> 		; tst i.flgs / is i-node already allocated
  4022 0000B205 75E3                <1> 	jnz	short maknod1	
  4023                              <1> 		; blt 1b / yes, look for another one
  4024 0000B207 66A3[B2E30000]      <1> 	mov	[u.dirbuf], ax
  4025                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  4026 0000B20D 6658                <1> 	pop	ax
  4027                              <1> 		; mov (sp)+,r1 / get current i-number back
  4028 0000B20F E8F70B0000          <1> 	call	iget
  4029                              <1> 		; jsr r0,iget / get i-node in core
  4030 0000B214 E88AF9FFFF          <1> 	call	mkdir
  4031                              <1> 		; jsr r0,mkdir / make a directory entry 
  4032                              <1> 			     ; / in current directory
  4033 0000B219 66A1[B2E30000]      <1> 	mov	ax, [u.dirbuf]
  4034                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  4035 0000B21F E8E70B0000          <1> 	call	iget
  4036                              <1> 		; jsr r0,iget / get it into core
  4037                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
  4038 0000B224 B908000000          <1> 	mov	ecx, 8 
  4039 0000B229 31C0                <1> 	xor	eax, eax ; 0
  4040 0000B22B BF[42E00000]        <1> 	mov	edi, inode 
  4041 0000B230 F3AB                <1> 	rep	stosd
  4042                              <1> 	;
  4043 0000B232 668F05[42E00000]    <1> 	pop	word [i.flgs]
  4044                              <1> 		; mov (sp)+,i.flgs / fill flags
  4045 0000B239 8A0D[CCE30000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
  4046 0000B23F 880D[45E00000]      <1> 	mov 	[i.uid], cl
  4047                              <1> 		; movb u.uid,i.uid / user id	
  4048 0000B245 C605[44E00000]01    <1> 	mov     byte [i.nlks], 1
  4049                              <1> 		; movb $1,i.nlks / 1 link
  4050                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
  4051                              <1> 	;mov	eax, [s.time]
  4052                              <1> 	;mov 	[i.ctim], eax
  4053                              <1> 	 	; mov s.time,i.ctim / time created
  4054                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
  4055                              <1> 	; Retro UNIX 8086 v1 modification !
  4056                              <1> 	; i.ctime=0, i.ctime+2=0 and
  4057                              <1>         ; 'setimod' will set ctime of file via 'epoch'
  4058 0000B24C E8C10B0000          <1> 	call setimod
  4059                              <1> 		; jsr r0,setimod / set modified flag
  4060 0000B251 C3                  <1> 	retn
  4061                              <1> 		; rts r0 / return
  4062                              <1> 
  4063                              <1> sysseek: ; / moves read write pointer in an fsp entry
  4064                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4065                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4066                              <1> 	;
  4067                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  4068                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  4069                              <1> 	; The file descriptor refers to a file open for reading or
  4070                              <1> 	; writing. The read (or write) pointer is set as follows:
  4071                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  4072                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  4073                              <1> 	;	  current location plus offset.
  4074                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  4075                              <1> 	;	  size of file plus offset.
  4076                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  4077                              <1> 	;
  4078                              <1> 	; Calling sequence:
  4079                              <1> 	;	sysseek; offset; ptrname
  4080                              <1> 	; Arguments:
  4081                              <1> 	;	offset - number of bytes desired to move 
  4082                              <1> 	;		 the r/w pointer
  4083                              <1> 	;	ptrname - a switch indicated above
  4084                              <1> 	;
  4085                              <1> 	; Inputs: r0 - file descriptor 
  4086                              <1> 	; Outputs: -
  4087                              <1> 	; ...............................................................
  4088                              <1> 	;	
  4089                              <1> 	; Retro UNIX 8086 v1 modification: 
  4090                              <1> 	;       'sysseek' system call has three arguments; so,
  4091                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  4092                              <1> 	;	* 2nd argument, offset is in CX register
  4093                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  4094                              <1> 	;	
  4095                              <1> 
  4096 0000B252 E823000000          <1> 	call	seektell
  4097                              <1> 	; AX = u.count
  4098                              <1> 	; BX = *u.fofp
  4099                              <1> 		; jsr r0,seektell / get proper value in u.count
  4100                              <1> 		; add u.base,u.count / add u.base to it
  4101 0000B257 0305[A0E30000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  4102 0000B25D 8903                <1> 	mov	[ebx], eax
  4103                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  4104 0000B25F E9BFEEFFFF          <1> 	jmp	sysret
  4105                              <1> 		; br sysret4
  4106                              <1> 
  4107                              <1> systell: ; / get the r/w pointer
  4108                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4109                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4110                              <1> 	;
  4111                              <1> 	; Retro UNIX 8086 v1 modification:
  4112                              <1> 	; ! 'systell' does not work in original UNIX v1,
  4113                              <1> 	; 	    it returns with error !
  4114                              <1> 	; Inputs: r0 - file descriptor 
  4115                              <1> 	; Outputs: r0 - file r/w pointer
  4116                              <1> 
  4117                              <1> 	;xor	ecx, ecx ; 0
  4118 0000B264 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  4119                              <1> 	;call 	seektell
  4120 0000B269 E812000000          <1> 	call 	seektell0 ; 05/08/2013
  4121                              <1> 	;mov	ebx, [u.fofp]
  4122 0000B26E 8B03                <1> 	mov	eax, [ebx]
  4123 0000B270 A3[80E30000]        <1> 	mov	[u.r0], eax
  4124 0000B275 E9A9EEFFFF          <1> 	jmp	sysret
  4125                              <1> 
  4126                              <1> ; Original unix v1 'systell' system call:
  4127                              <1> 		; jsr r0,seektell
  4128                              <1> 		; br error4
  4129                              <1> 
  4130                              <1> seektell:
  4131                              <1> 	; 03/01/2016
  4132                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4133                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4134                              <1> 	;
  4135                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  4136                              <1> 	; call in u.base and u.count. It then gets the i-number of
  4137                              <1> 	; the file from the file descriptor in u.r0 and by calling
  4138                              <1> 	; getf. The i-node is brought into core and then u.count
  4139                              <1> 	; is checked to see it is a 0, 1, or 2.
  4140                              <1> 	; If it is 0 - u.count stays the same
  4141                              <1> 	;          1 - u.count = offset (u.fofp)
  4142                              <1> 	;	   2 - u.count = i.size (size of file)
  4143                              <1> 	; 	 		
  4144                              <1> 	; !! Retro UNIX 8086 v1 modification:
  4145                              <1> 	;	Argument 1, file descriptor is in BX;
  4146                              <1> 	;	Argument 2, offset is in CX;
  4147                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  4148                              <1> 	;
  4149                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
  4150                              <1> 	; call 	arg
  4151                              <1> 	;
  4152                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
  4153                              <1> 	;
  4154 0000B27A 890D[A0E30000]      <1> 	mov 	[u.base], ecx ; offset
  4155                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  4156                              <1> seektell0:
  4157 0000B280 8915[A4E30000]      <1> 	mov 	[u.count], edx
  4158                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
  4159                              <1> 	; mov	ax, bx
  4160                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
  4161                              <1> 			     ; / (index in u.fp list)
  4162                              <1> 	; call	getf
  4163                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
  4164                              <1> 	; BX = file descriptor (file number)
  4165 0000B286 E83DFCFFFF          <1> 	call	getf1
  4166 0000B28B 6609C0              <1> 	or	ax, ax ; i-number of the file
  4167                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
  4168                              <1> 		             ; / put it on the stack
  4169                              <1> 	;jz	error
  4170                              <1> 		; beq error4 / if i-number is 0, not active so error
  4171 0000B28E 750F                <1> 	jnz	short seektell1
  4172 0000B290 C705[D5E30000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  4172 0000B298 0000                <1>
  4173 0000B29A E964EEFFFF          <1> 	jmp	error
  4174                              <1> seektell1:
  4175                              <1> 	;push	eax
  4176 0000B29F 80FC80              <1> 	cmp	ah, 80h
  4177 0000B2A2 7203                <1> 	jb	short seektell2
  4178                              <1> 		; bgt .+4 / if its positive jump
  4179 0000B2A4 66F7D8              <1> 	neg	ax
  4180                              <1> 		; neg r1 / if not make it positive
  4181                              <1> seektell2:
  4182 0000B2A7 E85F0B0000          <1> 	call	iget
  4183                              <1> 		; jsr r0,iget / get its i-node into core
  4184 0000B2AC 8B1D[90E30000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  4185 0000B2B2 803D[A4E30000]01    <1> 	cmp	byte [u.count], 1
  4186                              <1> 		; cmp u.count,$1 / is ptr name =1
  4187 0000B2B9 7705                <1> 	ja	short seektell3
  4188                              <1> 		; blt 2f / no its zero
  4189 0000B2BB 740A                <1> 	je	short seektell_4
  4190                              <1> 		; beq 1f / yes its 1
  4191 0000B2BD 31C0                <1> 	xor	eax, eax
  4192                              <1> 	;jmp	short seektell_5
  4193 0000B2BF C3                  <1> 	retn
  4194                              <1> seektell3:
  4195                              <1> 	; 03/01/2016
  4196                              <1> 	;movzx	eax, word [i.size]
  4197 0000B2C0 66A1[09E40000]      <1>         mov   	ax, [i.size]
  4198                              <1>                 ; mov i.size,u.count /  put number of bytes 
  4199                              <1>                                    ; / in file in u.count
  4200                              <1> 	;jmp	short seektell_5
  4201                              <1> 		; br 2f
  4202 0000B2C6 C3                  <1> 	retn
  4203                              <1> seektell_4: ; 1: / ptrname =1
  4204                              <1> 	;mov	ebx, [u.fofp]
  4205 0000B2C7 8B03                <1> 	mov	eax, [ebx]
  4206                              <1> 		; mov *u.fofp,u.count / put offset in u.count
  4207                              <1> ;seektell_5: ; 2: / ptrname =0
  4208                              <1> 	;mov	[u.count], eax
  4209                              <1> 	;pop	eax 
  4210                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
  4211 0000B2C9 C3                  <1> 	retn
  4212                              <1> 		; rts r0
  4213                              <1> 
  4214                              <1> sysintr: ; / set interrupt handling
  4215                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4216                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4217                              <1> 	;
  4218                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  4219                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  4220                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  4221                              <1> 	; If one does the interrupt character in the tty buffer is
  4222                              <1> 	; cleared and 'sysret'is called. If one does not exits
  4223                              <1> 	; 'sysret' is just called.	
  4224                              <1> 	;
  4225                              <1> 	; Calling sequence:
  4226                              <1> 	;	sysintr; arg
  4227                              <1> 	; Argument:
  4228                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  4229                              <1> 	;	    - if 1, intterupts cause their normal result
  4230                              <1> 	;		 i.e force an exit.
  4231                              <1> 	;	    - if arg is a location within the program,
  4232                              <1> 	;		control is passed to that location when
  4233                              <1> 	;		an interrupt occurs.	
  4234                              <1> 	; Inputs: -
  4235                              <1> 	; Outputs: -
  4236                              <1> 	; ...............................................................
  4237                              <1> 	;	
  4238                              <1> 	; Retro UNIX 8086 v1 modification: 
  4239                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  4240                              <1> 	;	then branches into sysquit.
  4241                              <1> 	;
  4242 0000B2CA 66891D[C4E30000]    <1> 	mov	[u.intr], bx
  4243                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  4244                              <1> 		; br 1f / go into quit routine
  4245 0000B2D1 E94DEEFFFF          <1> 	jmp	sysret
  4246                              <1> 
  4247                              <1> sysquit:
  4248                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4249                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4250                              <1> 	;
  4251                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  4252                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  4253                              <1> 	; tty exists. If one does the interrupt character in the tty
  4254                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  4255                              <1> 	; 'sysret' is just called.	
  4256                              <1> 	;
  4257                              <1> 	; Calling sequence:
  4258                              <1> 	;	sysquit; arg
  4259                              <1> 	; Argument:
  4260                              <1> 	;	arg - if 0, this call diables quit signals from the
  4261                              <1> 	;		typewriter (ASCII FS)
  4262                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  4263                              <1> 	;		cease and a core image to be produced.
  4264                              <1> 	;		 i.e force an exit.
  4265                              <1> 	;	    - if arg is an addres in the program,
  4266                              <1> 	;		a quit causes control to sent to that
  4267                              <1> 	;		location.	
  4268                              <1> 	; Inputs: -
  4269                              <1> 	; Outputs: -
  4270                              <1> 	; ...............................................................
  4271                              <1> 	;	
  4272                              <1> 	; Retro UNIX 8086 v1 modification: 
  4273                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  4274                              <1> 	;	then branches into 'sysret'.
  4275                              <1> 	;
  4276 0000B2D6 66891D[C6E30000]    <1> 	mov	[u.quit], bx
  4277 0000B2DD E941EEFFFF          <1> 	jmp	sysret
  4278                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  4279                              <1> 	;1:
  4280                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  4281                              <1> 			      ; / to r1
  4282                              <1> 		; beq sysret4 / return to user
  4283                              <1> 		; clrb 6(r1) / clear the interrupt character 
  4284                              <1> 			   ; / in the tty buffer
  4285                              <1> 		; br sysret4 / return to user
  4286                              <1> 
  4287                              <1> syssetuid: ; / set process id
  4288                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4289                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4290                              <1> 	;
  4291                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
  4292                              <1> 	; to the process id in (u.r0). Both the effective user and 
  4293                              <1> 	; u.uid and the real user u.ruid are set to this. 
  4294                              <1> 	; Only the super user can make this call.	
  4295                              <1> 	;
  4296                              <1> 	; Calling sequence:
  4297                              <1> 	;	syssetuid
  4298                              <1> 	; Arguments: -
  4299                              <1> 	;
  4300                              <1> 	; Inputs: (u.r0) - contains the process id.
  4301                              <1> 	; Outputs: -
  4302                              <1> 	; ...............................................................
  4303                              <1> 	;	
  4304                              <1> 	; Retro UNIX 8086 v1 modification: 
  4305                              <1> 	;       BL contains the (new) user ID of the current process
  4306                              <1> 
  4307                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
  4308 0000B2E2 3A1D[CDE30000]      <1> 	cmp	bl, [u.ruid] 
  4309                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
  4310                              <1> 			       ; / id number
  4311 0000B2E8 741E                <1> 	je	short setuid1
  4312                              <1> 		; beq 1f / yes
  4313 0000B2EA 803D[CCE30000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  4314                              <1> 		; tstb u.uid / no, is current user the super user?
  4315                              <1> 	;ja	error
  4316                              <1> 		; bne error4 / no, error
  4317 0000B2F1 760F                <1> 	jna	short setuid0
  4318 0000B2F3 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  4318 0000B2FB 0000                <1>
  4319                              <1> 				;  'permission denied !' error
  4320 0000B2FD E901EEFFFF          <1> 	jmp	error
  4321                              <1> setuid0:
  4322 0000B302 881D[CDE30000]      <1> 	mov	[u.ruid], bl
  4323                              <1> setuid1: ; 1:
  4324 0000B308 881D[CCE30000]      <1> 	mov	[u.uid], bl ; 02/08/2013
  4325                              <1> 		; movb r1,u.uid / put process id in u.uid
  4326                              <1> 		; movb r1,u.ruid / put process id in u.ruid
  4327 0000B30E E910EEFFFF          <1> 	jmp	sysret
  4328                              <1> 		; br sysret4 / system return
  4329                              <1> 
  4330                              <1> sysgetuid: ; < get user id >
  4331                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4332                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4333                              <1> 	;
  4334                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
  4335                              <1> 	; The real user ID identifies the person who is logged in,
  4336                              <1> 	; in contradistinction to the effective user ID, which
  4337                              <1> 	; determines his access permission at each moment. It is thus
  4338                              <1> 	; useful to programs which operate using the 'set user ID'
  4339                              <1> 	; mode, to find out who invoked them.	
  4340                              <1> 	;
  4341                              <1> 	; Calling sequence:
  4342                              <1> 	;	syssetuid
  4343                              <1> 	; Arguments: -
  4344                              <1> 	;
  4345                              <1> 	; Inputs: -
  4346                              <1> 	; Outputs: (u.r0) - contains the real user's id.
  4347                              <1> 	; ...............................................................
  4348                              <1> 	;	
  4349                              <1> 	; Retro UNIX 8086 v1 modification: 
  4350                              <1> 	;       AL contains the real user ID at return.
  4351                              <1> 	;
  4352 0000B313 0FB605[CDE30000]    <1> 	movzx 	eax, byte [u.ruid]
  4353 0000B31A A3[80E30000]        <1> 	mov	[u.r0], eax
  4354                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  4355 0000B31F E9FFEDFFFF          <1> 	jmp	sysret
  4356                              <1> 		; br sysret4 / systerm return, sysret
  4357                              <1> 
  4358                              <1> anyi: 
  4359                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4360                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  4361                              <1> 	;
  4362                              <1> 	; 'anyi' is called if a file deleted while open.
  4363                              <1> 	; "anyi" checks to see if someone else has opened this file.
  4364                              <1> 	;
  4365                              <1> 	; INPUTS ->
  4366                              <1> 	;    r1 - contains an i-number
  4367                              <1> 	;    fsp - start of table containing open files
  4368                              <1> 	;
  4369                              <1> 	; OUTPUTS ->
  4370                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  4371                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  4372                              <1> 	;    if file not found - bit in i-node map is cleared
  4373                              <1> 	;    			 (i-node is freed)
  4374                              <1> 	;               all blocks related to i-node are freed
  4375                              <1> 	;	        all flags in i-node are cleared
  4376                              <1> 	; ((AX = R1)) input
  4377                              <1> 	;
  4378                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  4379                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  4380                              <1> 	;
  4381                              <1> 		; / r1 contains an i-number
  4382 0000B324 BB[52E10000]        <1> 	mov	ebx, fsp
  4383                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  4384                              <1> anyi_1: ; 1:
  4385 0000B329 663B03              <1> 	cmp	ax, [ebx]
  4386                              <1> 		; cmp r1,(r2) / do i-numbers match?
  4387 0000B32C 7433                <1> 	je	short anyi_3
  4388                              <1> 		; beq 1f / yes, 1f
  4389 0000B32E 66F7D8              <1> 	neg	ax
  4390                              <1> 		; neg r1 / no complement r1
  4391 0000B331 663B03              <1> 	cmp	ax, [ebx]
  4392                              <1> 		; cmp r1,(r2) / do they match now?
  4393 0000B334 742B                <1> 	je	short anyi_3
  4394                              <1> 		; beq 1f / yes, transfer
  4395                              <1> 		; / i-numbers do not match
  4396 0000B336 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
  4397                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
  4398                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
  4399 0000B339 81FB[46E30000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
  4400                              <1> 		; cmp r2,$fsp+[nfiles*8] 
  4401                              <1> 				; / are we at last entry in the table
  4402 0000B33F 72E8                <1> 	jb	short anyi_1
  4403                              <1> 		; blt 1b / no, check next entries i-number
  4404                              <1> 	;cmp	ax, 32768
  4405 0000B341 80FC80              <1> 	cmp	ah, 80h ; negative number check
  4406                              <1> 		; tst r1 / yes, no match
  4407                              <1> 		; bge .+4
  4408 0000B344 7203                <1> 	jb	short anyi_2
  4409 0000B346 66F7D8              <1> 	neg	ax
  4410                              <1> 		; neg r1 / make i-number positive
  4411                              <1> anyi_2:	
  4412 0000B349 E8CC0A0000          <1> 	call	imap
  4413                              <1> 		; jsr r0,imap / get address of allocation bit 
  4414                              <1> 			    ; / in the i-map in r2
  4415                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
  4416                              <1>         ;; eBX (R2) has address of the byte with allocation bit
  4417                              <1>  	; not	dx
  4418 0000B34E F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
  4419                              <1>         ;and	[ebx], dx
  4420 0000B350 2013                <1> 	and 	[ebx], dl 
  4421                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  4422 0000B352 E8BA0A0000          <1> 	call	itrunc
  4423                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  4424 0000B357 66C705[42E00000]00- <1>  	mov 	word [i.flgs], 0
  4424 0000B35F 00                  <1>
  4425                              <1> 		; clr i.flgs / clear all flags in the i-node
  4426 0000B360 C3                  <1> 	retn
  4427                              <1> 		;rts	r0 / return
  4428                              <1> anyi_3: ; 1: / i-numbers match
  4429 0000B361 FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
  4430                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
  4431                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
  4432 0000B364 C3                  <1> 	retn
  4433                              <1> 		; rts r0
  4434                              <1> 
  4435                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u7.s
  4436                              <1> ; Last Modification: 14/11/2015
  4437                              <1> 
  4438                              <1> sysmount: ; / mount file system; args special; name
  4439                              <1> 	; 14/11/2015
  4440                              <1> 	; 24/10/2015
  4441                              <1> 	; 13/10/2015
  4442                              <1> 	; 10/07/2015
  4443                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4444                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4445                              <1> 	;
  4446                              <1> 	; 'sysmount' anounces to the system that a removable 
  4447                              <1> 	; file system has been mounted on a special file.
  4448                              <1> 	; The device number of the special file is obtained via
  4449                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
  4450                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
  4451                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
  4452                              <1> 	; to read file system into core, i.e. the first block on the
  4453                              <1> 	; mountable file system is read in. This block is super block
  4454                              <1> 	; for the file system. This call is super user restricted.	
  4455                              <1> 	;
  4456                              <1> 	; Calling sequence:
  4457                              <1> 	;	sysmount; special; name
  4458                              <1> 	; Arguments:
  4459                              <1> 	;	special - pointer to name of special file (device)
  4460                              <1> 	;	name -  pointer to name of the root directory of the
  4461                              <1> 	;		newly mounted file system. 'name' should 
  4462                              <1> 	;		always be a directory.
  4463                              <1> 	; Inputs: - 
  4464                              <1> 	; Outputs: -
  4465                              <1> 	; ...............................................................
  4466                              <1> 	;				
  4467                              <1> 	; Retro UNIX 8086 v1 modification: 
  4468                              <1> 	;       'sysmount' system call has two arguments; so,
  4469                              <1> 	;	* 1st argument, special is pointed to by BX register
  4470                              <1> 	;	* 2nd argument, name is in CX register
  4471                              <1> 	;
  4472                              <1> 	;	NOTE: Device numbers, names and related procedures are 
  4473                              <1> 	;	       already modified for IBM PC compatibility and 
  4474                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
  4475                              <1> 	
  4476                              <1> 	;call	arg2
  4477                              <1> 		; jsr r0,arg2 / get arguments special and name
  4478 0000B365 891D[98E30000]      <1> 	mov	[u.namep], ebx
  4479 0000B36B 51                  <1> 	push	ecx ; directory name
  4480 0000B36C 66833D[66E30000]00  <1> 	cmp	word [mnti], 0
  4481                              <1> 		; tst mnti / is the i-number of the cross device file
  4482                              <1> 			 ; / zero?
  4483                              <1> 	;ja	error
  4484                              <1>         	; bne errora / no, error
  4485 0000B374 0F87E9000000        <1> 	ja	sysmnt_err0
  4486                              <1> 	;
  4487 0000B37A E8CC000000          <1> 	call	getspl
  4488                              <1> 		; jsr r0,getspl / get special files device number in r1
  4489                              <1> 	; 13/10/2015
  4490 0000B37F 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
  4491 0000B382 F683[0CCE0000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
  4492 0000B389 750F                <1> 	jnz	short sysmnt_1
  4493                              <1> sysmnt_err1:
  4494 0000B38B C705[D5E30000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  4494 0000B393 0000                <1>
  4495 0000B395 E969EDFFFF          <1> 	jmp	error
  4496                              <1> sysmnt_1:
  4497 0000B39A 8F05[98E30000]      <1> 	pop	dword [u.namep]
  4498                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
  4499                              <1> 				  ; / on the device
  4500                              <1> 	; 14/11/2015
  4501 0000B3A0 53                  <1> 	push	ebx ; 13/10/2015
  4502                              <1> 		; mov r1,-(sp) / save the device number
  4503                              <1>         ;
  4504 0000B3A1 E859FBFFFF          <1> 	call	namei
  4505                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4506                              <1> 		       ; ax = 0 -> file not found 	
  4507                              <1> 	;jz	error
  4508                              <1> 	;jc	error
  4509                              <1> 		; jsr r0,namei / get the i-number of the file
  4510                              <1>                	; br errora
  4511 0000B3A6 730F                <1> 	jnc	short sysmnt_2
  4512                              <1> sysmnt_err2:
  4513 0000B3A8 C705[D5E30000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  4513 0000B3B0 0000                <1>
  4514 0000B3B2 E94CEDFFFF          <1> 	jmp	error
  4515                              <1> sysmnt_2:	
  4516 0000B3B7 66A3[66E30000]      <1> 	mov	[mnti], ax
  4517                              <1>         	; mov r1,mnti / put it in mnti
  4518                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
  4519                              <1> sysmnt_3: ;1:
  4520                              <1>         ;cmp	byte [ebx+1], 0
  4521                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
  4522                              <1> 			   ; / dismountable device set?
  4523                              <1>         ;jna	short sysmnt_4		
  4524                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
  4525                              <1> 	;call	idle 	; (wait for hardware interrupt)
  4526                              <1> 	;jmp	short sysmnt_3
  4527                              <1> sysmnt_4:   
  4528 0000B3BD 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  4529 0000B3BE A2[63E30000]        <1> 	mov	[mdev], al
  4530                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
  4531 0000B3C3 8803                <1> 	mov	[ebx], al
  4532                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
  4533                              <1> 			      ; / of the I/O queue entry
  4534                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
  4535                              <1>         	; mov (sp)+,cdev / put device number in cdev
  4536 0000B3C5 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
  4537                              <1> 		; bis $2000,sb1 / set the read bit
  4538                              <1> 	; Retro UNIX 386 v1 modification : 
  4539                              <1> 	;	32 bit block number at buffer header offset 4
  4540 0000B3CA C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
  4541 0000B3D1 E8450A0000          <1> 	call 	diskio
  4542 0000B3D6 731C                <1> 	jnc	short sysmnt_5
  4543 0000B3D8 31C0                <1> 	xor 	eax, eax
  4544 0000B3DA 66A3[66E30000]      <1> 	mov	[mnti], ax ; 0
  4545 0000B3E0 A2[63E30000]        <1> 	mov	[mdev], al ; 0
  4546                              <1> 	;mov	[cdev], al ; 0
  4547                              <1> sysmnt_invd:
  4548                              <1> 	; 14/11/2015
  4549 0000B3E5 FEC8                <1> 	dec 	al
  4550 0000B3E7 8903                <1> 	mov	[ebx], eax ; 000000FFh
  4551 0000B3E9 FEC0                <1> 	inc	al
  4552 0000B3EB 48                  <1> 	dec	eax
  4553 0000B3EC 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  4554 0000B3EF E90FEDFFFF          <1> 	jmp	error
  4555                              <1> sysmnt_5:
  4556                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
  4557                              <1> 	; (Following check is needed to prevent mounting an
  4558                              <1> 	; in valid valid file system (in valid super block).
  4559                              <1> 	; 
  4560 0000B3F4 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  4561 0000B3F7 C0E002              <1> 	shl	al, 2 ; 4*index
  4562 0000B3FA 8B88[F0CD0000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  4563 0000B400 C1E103              <1> 	shl 	ecx, 3
  4564 0000B403 0FB715[39EE0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
  4565 0000B40A 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
  4566                              <1> 			 ; (in sectors), if they are not equal
  4567                              <1> 			 ; the disk to be mounted is an...	
  4568 0000B40C 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
  4569                              <1> 			 ; (which has not got a valid super block)
  4570                              <1> 	;
  4571 0000B40E C6430100            <1> 	mov	byte [ebx+1], 0
  4572                              <1> 	       	; jsr r0,ppoke / read in entire file system
  4573                              <1> ;sysmnt_6: ;1:
  4574                              <1> 	;;cmp	byte [sb1+1], 0
  4575                              <1> 		; tstb   sb1+1 / done reading?
  4576                              <1>    	;;jna	sysret
  4577                              <1> 	;;call	idle ; (wait for hardware interrupt)
  4578                              <1> 	;;jmp	short sysmnt_6
  4579                              <1> 		;bne 1b / no, wait
  4580                              <1>         	;br sysreta / yes
  4581 0000B412 E90CEDFFFF          <1> 	jmp	sysret
  4582                              <1> 
  4583                              <1> sysumount: ; / special dismount file system
  4584                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4585                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4586                              <1> 	;
  4587                              <1> 	; 04/11/2013
  4588                              <1> 	; 09/07/2013
  4589                              <1> 	; 'sysumount' anounces to the system that the special file, 
  4590                              <1> 	; indicated as an argument is no longer contain a removable
  4591                              <1> 	; file system. 'getspl' gets the device number of the special
  4592                              <1> 	; file. If no file system was mounted on that device an error
  4593                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
  4594                              <1> 	; to 'sysret'.
  4595                              <1> 	;
  4596                              <1> 	; Calling sequence:
  4597                              <1> 	;	sysmount; special
  4598                              <1> 	; Arguments:
  4599                              <1> 	;	special - special file to dismount (device)
  4600                              <1> 	;
  4601                              <1> 	; Inputs: - 
  4602                              <1> 	; Outputs: -
  4603                              <1> 	; ...............................................................
  4604                              <1> 	;				
  4605                              <1> 	; Retro UNIX 8086 v1 modification: 
  4606                              <1> 	;       'sysumount' system call has one argument; so,
  4607                              <1> 	;	* Single argument, special is pointed to by BX register
  4608                              <1> 	;
  4609                              <1> 	
  4610                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
  4611                              <1> 	;call	arg
  4612                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
  4613 0000B417 891D[98E30000]      <1>         mov	[u.namep], ebx
  4614 0000B41D E829000000          <1> 	call	getspl
  4615                              <1> 		; jsr r0,getspl / get the device number in r1
  4616 0000B422 3A05[63E30000]      <1> 	cmp	al, [mdev]
  4617                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  4618 0000B428 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  4619                              <1> 	;jne	error
  4620                              <1>         	; bne errora / no error
  4621 0000B42A 30C0                <1> 	xor	al, al ; ah = 0
  4622                              <1> sysumnt_0: ;1:
  4623 0000B42C 3805[36EE0000]      <1>      	cmp 	[sb1+1], al ; 0
  4624                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
  4625                              <1> 			   ; / (inhibit bit set)?
  4626 0000B432 7607                <1> 	jna	short sysumnt_1		
  4627                              <1> 		; bne 1b / yes, wait
  4628 0000B434 E8E3090000          <1> 	call	idle ; (wait for hardware interrupt)
  4629 0000B439 EBF1                <1> 	jmp	short sysumnt_0
  4630                              <1> sysumnt_1:        
  4631 0000B43B A2[63E30000]        <1> 	mov	[mdev], al
  4632                              <1> 	     	; clr mntd / no, clear these
  4633 0000B440 66A3[66E30000]      <1>    	mov	[mnti], ax
  4634                              <1>         	; clr mnti
  4635 0000B446 E9D8ECFFFF          <1>         jmp	sysret
  4636                              <1> 		; br sysreta / return
  4637                              <1> 
  4638                              <1> getspl: ; / get device number from a special file name
  4639 0000B44B E8AFFAFFFF          <1> 	call	namei
  4640                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4641                              <1> 		       ; ax = 0 -> file not found 	
  4642 0000B450 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
  4643                              <1> 	;jz	error
  4644                              <1> 	;jc	error
  4645                              <1> 		; jsr r0,namei / get the i-number of the special file
  4646                              <1>                 ; br errora / no such file
  4647 0000B456 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
  4648                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
  4649                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
  4650 0000B45A 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  4651                              <1> 	;jc	error
  4652                              <1> 		; ble errora / less than 0?  yes, error
  4653 0000B45C 6683F805            <1>         cmp	ax, 5 ;
  4654                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
  4655 0000B460 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
  4656                              <1> 	;ja	error
  4657                              <1>         	; bgt errora / yes, error
  4658                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
  4659                              <1> iopen_retn:
  4660 0000B462 C3                  <1> 	retn
  4661                              <1> 		; rts    r0 / return with device number in r1
  4662                              <1> sysmnt_err0:
  4663 0000B463 C705[D5E30000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  4663 0000B46B 0000                <1>
  4664 0000B46D E991ECFFFF          <1> 	jmp	error
  4665                              <1> 
  4666                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
  4667                              <1> ; Last Modification: 09/12/2015
  4668                              <1> 
  4669                              <1> syssleep:
  4670                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  4671                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  4672                              <1> 	;
  4673                              <1> 	; Retro UNIX 8086 v1 feature only
  4674                              <1> 	; (INPUT -> none)
  4675                              <1> 	;
  4676 0000B472 0FB61D[CFE30000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4677 0000B479 8AA3[C1E00000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  4678 0000B47F E899090000          <1> 	call	sleep
  4679 0000B484 E99AECFFFF          <1> 	jmp	sysret
  4680                              <1> 
  4681                              <1> _vp_clr:
  4682                              <1> 	; Reset/Clear Video Page
  4683                              <1> 	;
  4684                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  4685                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  4686                              <1> 	;
  4687                              <1> 	; Retro UNIX 8086 v1 feature only !
  4688                              <1> 	;
  4689                              <1> 	; INPUTS -> 
  4690                              <1> 	;   BH = video page number	 
  4691                              <1> 	;
  4692                              <1> 	; OUTPUT ->
  4693                              <1> 	;   none
  4694                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  4695                              <1> 	;
  4696                              <1> 	; 04/12/2013
  4697 0000B489 28C0                <1> 	sub	al, al
  4698                              <1> 	; al = 0 (clear video page)
  4699                              <1> 	; bh = video page ; 13/05/2016
  4700 0000B48B B407                <1> 	mov	ah, 07h
  4701                              <1> 	; ah = 7 (attribute/color)
  4702 0000B48D 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  4703 0000B490 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  4704 0000B494 E8A560FFFF          <1> 	call	_scroll_up
  4705                              <1> 	; bh = video page
  4706 0000B499 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  4707 0000B49C E9EC62FFFF          <1> 	jmp 	_set_cpos
  4708                              <1> 
  4709                              <1> sysmsg:
  4710                              <1> 	; 13/05/2016
  4711                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  4712                              <1> 	; 01/07/2015 - 11/11/2015 (Retro UNIX 386 v1)
  4713                              <1> 	; Print user-application message on user's console tty
  4714                              <1> 	;
  4715                              <1> 	; Input -> EBX = Message address
  4716                              <1> 	;	   ECX = Message length (max. 255)
  4717                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  4718                              <1> 	;
  4719 0000B4A1 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  4720 0000B4A7 0F8776ECFFFF        <1> 	ja	sysret ; nothing to do with big message size
  4721 0000B4AD 08C9                <1> 	or	cl, cl
  4722 0000B4AF 0F846EECFFFF        <1> 	jz	sysret
  4723 0000B4B5 20D2                <1> 	and	dl, dl
  4724 0000B4B7 7502                <1> 	jnz	short sysmsg0
  4725 0000B4B9 B207                <1> 	mov	dl, 07h ; default color
  4726                              <1> 		; (black background, light gray character) 
  4727                              <1> sysmsg0:
  4728 0000B4BB 891D[A0E30000]      <1> 	mov	[u.base], ebx
  4729 0000B4C1 8815[E7D20000]      <1> 	mov	[ccolor], dl ; color attributes
  4730 0000B4C7 89E5                <1> 	mov	ebp, esp
  4731 0000B4C9 31DB                <1> 	xor	ebx, ebx ; 0
  4732 0000B4CB 891D[A8E30000]      <1> 	mov	[u.nread], ebx ; 0
  4733                              <1> 	;
  4734 0000B4D1 381D[E7E30000]      <1> 	cmp	[u.kcall], bl ; 0
  4735 0000B4D7 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  4736                              <1> 	;
  4737 0000B4D9 890D[A4E30000]      <1> 	mov	[u.count], ecx
  4738 0000B4DF 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ
  4739 0000B4E0 29CC                <1> 	sub	esp, ecx
  4740 0000B4E2 89E7                <1> 	mov	edi, esp
  4741 0000B4E4 89E6                <1> 	mov	esi, esp
  4742 0000B4E6 66891D[E5E30000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  4743                              <1> 	; 11/11/2015
  4744 0000B4ED 8A25[B0E30000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  4745                              <1> 	; 0 = none
  4746 0000B4F3 FECC                <1> 	dec	ah
  4747 0000B4F5 790C                <1> 	jns	short sysmsg1 
  4748 0000B4F7 8A1D[CFE30000]      <1> 	mov	bl, [u.uno] ; process number	
  4749 0000B4FD 8AA3[C1E00000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  4750                              <1> sysmsg1:
  4751 0000B503 8825[D4E30000]      <1> 	mov	[u.ttyn], ah
  4752                              <1> sysmsg2:
  4753 0000B509 E817080000          <1> 	call	cpass
  4754 0000B50E 7416                <1> 	jz	short sysmsg5
  4755 0000B510 AA                  <1> 	stosb
  4756 0000B511 20C0                <1> 	and	al, al
  4757 0000B513 75F4                <1> 	jnz	short sysmsg2
  4758                              <1> sysmsg3:
  4759 0000B515 80FC07              <1> 	cmp	ah, 7 ; tty number
  4760 0000B518 7711                <1> 	ja	short sysmsg6 ; serial port
  4761 0000B51A E83E000000          <1> 	call	print_cmsg
  4762                              <1> sysmsg4:
  4763 0000B51F 89EC                <1> 	mov	esp, ebp	
  4764 0000B521 E9FDEBFFFF          <1> 	jmp	sysret
  4765                              <1> sysmsg5:
  4766 0000B526 C60700              <1> 	mov	byte [edi], 0
  4767 0000B529 EBEA                <1> 	jmp	short sysmsg3
  4768                              <1> sysmsg6:
  4769 0000B52B 8A06                <1> 	mov	al, [esi]
  4770 0000B52D E8E3080000          <1> 	call	sndc
  4771 0000B532 72EB                <1> 	jc	short sysmsg4
  4772 0000B534 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  4773 0000B537 76E6                <1> 	jna	short sysmsg4
  4774 0000B539 46                  <1> 	inc 	esi
  4775 0000B53A 8A25[D4E30000]      <1> 	mov	ah, [u.ttyn]
  4776 0000B540 EBE9                <1> 	jmp	short sysmsg6
  4777                              <1> 
  4778                              <1> sysmsgk: ; Temporary (01/07/2015)
  4779                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  4780                              <1> 	; (ECX -character count- will not be considered)
  4781 0000B542 8B35[A0E30000]      <1> 	mov	esi, [u.base]
  4782 0000B548 8A25[E6D20000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  4783 0000B54E 8825[D4E30000]      <1> 	mov	[u.ttyn], ah
  4784 0000B554 C605[E7E30000]00    <1> 	mov	byte [u.kcall], 0
  4785 0000B55B EBB8                <1> 	jmp	short sysmsg3
  4786                              <1> 	
  4787                              <1> print_cmsg: 
  4788                              <1> 	; 13/05/2016 - TRDOS 386 (TRDOS v2.0)
  4789                              <1> 	; 01/07/2015 (Retro UNIX 386 v1)
  4790                              <1> 	;
  4791                              <1> 	; print message (on user's console tty) 
  4792                              <1> 	;	with requested color
  4793                              <1> 	;
  4794                              <1> 	; INPUTS:
  4795                              <1> 	;	esi = message address
  4796                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  4797                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  4798                              <1> 	
  4799 0000B55D 8A3D[D4E30000]      <1> 	mov	bh, [u.ttyn]
  4800                              <1> 	;mov	bh, ah
  4801                              <1> 
  4802 0000B563 AC                  <1> 	lodsb
  4803                              <1> pcmsg1:
  4804 0000B564 56                  <1> 	push 	esi
  4805 0000B565 8A1D[E7D20000]      <1> 	mov	bl, [ccolor]
  4806                              <1> 	;mov	bh, [u.ttyn]
  4807 0000B56B E89261FFFF          <1> 	call 	_write_tty
  4808 0000B570 5E                  <1> 	pop	esi
  4809 0000B571 AC                  <1> 	lodsb
  4810 0000B572 20C0                <1> 	and 	al, al  ; 0
  4811 0000B574 75EE                <1> 	jnz 	short pcmsg1
  4812 0000B576 C3                  <1> 	retn
  4813                              <1> 
  4814                              <1> sysgeterr:
  4815                              <1> 	; 09/12/2015
  4816                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  4817                              <1> 	; Get last error number or page fault count
  4818                              <1> 	; (for debugging)
  4819                              <1> 	;
  4820                              <1> 	; Input -> EBX = return type
  4821                              <1> 	;	   0 = last error code (which is in 'u.error')	
  4822                              <1> 	;	   FFFFFFFFh = page fault count for running process
  4823                              <1> 	;	   FFFFFFFEh = total page fault count
  4824                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  4825                              <1> 	;
  4826                              <1> 	; Output -> EAX = last error number or page fault count
  4827                              <1> 	;	   (depending on EBX input)
  4828                              <1> 	; 	
  4829 0000B577 21DB                <1> 	and 	ebx, ebx
  4830 0000B579 750B                <1> 	jnz	short glerr_2
  4831                              <1> glerr_0:
  4832 0000B57B A1[D5E30000]        <1> 	mov	eax, [u.error]
  4833                              <1> glerr_1:
  4834 0000B580 A3[80E30000]        <1> 	mov	[u.r0], eax
  4835 0000B585 C3                  <1>  	retn
  4836                              <1> glerr_2:
  4837 0000B586 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  4838 0000B587 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  4839 0000B589 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  4840 0000B58A 75EF                <1> 	jnz	short glerr_0
  4841 0000B58C A1[64F10000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  4842 0000B591 EBED                <1>         jmp     short glerr_1
  4843                              <1> glerr_3:
  4844 0000B593 A1[E9E30000]        <1> 	mov 	eax, [u.pfcount]
  4845 0000B598 EBE6                <1> 	jmp	short glerr_1
  4846                              <1> 
  4847                              <1> load_and_run_file:
  4848                              <1> 	; 06/06/2016
  4849                              <1> 	; 06/05/2016
  4850                              <1> 	; 03/05/2016
  4851                              <1> 	; 02/05/2016
  4852                              <1> 	; 24/04/2016
  4853                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  4854                              <1> 	; 23/10/2015 (Retro UNIX 386 v1, 'sysexec')
  4855                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4856                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  4857                              <1> 	; EAX = First Cluster number
  4858                              <1> 	; EDX = File Size
  4859                              <1> 	; ESI = Argument list address
  4860                              <1> 	; [argc] = argument count
  4861                              <1> 	; [u.nread] = argument list length
  4862                              <1> 	; [esp] = return address to the caller (*)
  4863                              <1> 	;
  4864 0000B59A 8935[00E40000]      <1> 	mov	[argv], esi
  4865 0000B5A0 8915[09E40000]      <1> 	mov	[i.size], edx
  4866 0000B5A6 A3[05E40000]        <1> 	mov	[ii], eax
  4867                              <1> 
  4868                              <1> 	; 06/05/2016
  4869                              <1> 	; Set 'sysexit' return order to MainProg
  4870                              <1> 	;
  4871 0000B5AB 58                  <1> 	pop	eax ; * 'loc_load_and_run_file_8:' address
  4872 0000B5AC 8B25[54D20000]      <1> 	mov	esp, [tss.esp0]
  4873                              <1> 	;
  4874                              <1> 	; 'loc_load_run_file_8' address has 
  4875                              <1> 	; 'jmp loc_file_rw_restore_retn' instruction
  4876                              <1> 	; 'loc_file_rw_restore_retn:' will return to
  4877                              <1> 	; [mainprog_return_addr] 
  4878                              <1> 	; just after 'call command_interpreter'
  4879                              <1> 	;
  4880 0000B5B2 68[0E400000]        <1> 	push	_end_of_mainprog ; we must not return to here !
  4881 0000B5B7 FF35[2CE00000]      <1> 	push	dword [mainprog_return_addr]
  4882 0000B5BD 89E5                <1> 	mov	ebp, esp ; **
  4883                              <1> 	;	
  4884 0000B5BF 9C                  <1> 	pushfd  ; EFLAGS      ; IRETD
  4885 0000B5C0 6A08                <1> 	push	KCODE ; cs    ; IRETD
  4886 0000B5C2 50                  <1> 	push	eax ; * (eip) ; IRETD
  4887 0000B5C3 8925[78E30000]      <1> 	mov	[u.sp], esp
  4888 0000B5C9 1E                  <1> 	push	ds
  4889 0000B5CA 06                  <1> 	push	es
  4890 0000B5CB 0FA0                <1> 	push	fs
  4891 0000B5CD 0FA8                <1> 	push	gs	
  4892 0000B5CF 60                  <1> 	pushad
  4893 0000B5D0 68[23A10000]        <1> 	push	sysret
  4894 0000B5D5 8925[7CE30000]      <1> 	mov	[u.usp], esp
  4895                              <1> 	;
  4896 0000B5DB E858060000          <1> 	call	wswap ; Save MainProg (process 1) 'u' structure
  4897                              <1> 		      ; and registers for return (from program)	
  4898 0000B5E0 89EC                <1> 	mov	esp, ebp ; **
  4899 0000B5E2 50                  <1> 	push	eax  ; * 'loc_load_and_run_file_8:' address
  4900                              <1> 	;
  4901                              <1> 	;;; 02/05/2016
  4902                              <1> 	;;; Create a new process (parent: MainProg)	
  4903 0000B5E3 31F6                <1> 	xor 	esi, esi
  4904                              <1> cnpm_1: ; search p.stat table for unused process number
  4905 0000B5E5 46                  <1> 	inc	esi
  4906 0000B5E6 80BE[F1E00000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE
  4907                              <1> 				; is process active, unused, dead
  4908 0000B5ED 760B                <1> 	jna	short cnpm_2	; it's unused so branch
  4909 0000B5EF 6683FE10            <1> 	cmp	si, nproc 	; all processes checked
  4910 0000B5F3 72F0                <1> 	jb	short cnpm_1    ; no, branch back
  4911 0000B5F5 E98A8AFFFF          <1> 	jmp	panic 
  4912                              <1> cnpm_2:
  4913 0000B5FA A1[D9E30000]        <1> 	mov	eax, [u.pgdir] ; page directory of MainProg
  4914 0000B5FF A3[DDE30000]        <1> 	mov	[u.ppgdir], eax ; parent's page directory
  4915 0000B604 E88D7BFFFF          <1> 	call	allocate_page
  4916 0000B609 0F82758AFFFF        <1> 	jc	panic
  4917                              <1> 	; EAX = UPAGE (user structure page) address
  4918 0000B60F A3[D0E30000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  4919 0000B614 89F7                <1> 	mov	edi, esi
  4920 0000B616 66C1E702            <1> 	shl	di, 2
  4921 0000B61A 8987[FEE00000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  4922 0000B620 E8EB7BFFFF          <1> 	call	clear_page ; 03/05/2016
  4923                              <1> 	;movzx	eax, byte [p.ttyc] ; console tty (for MainProg)
  4924 0000B625 6629C0              <1> 	sub	ax, ax ; 0
  4925 0000B628 668986[C1E00000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  4926                              <1> 				   ; ah - reset child's wait channel	
  4927 0000B62F 89F0                <1> 	mov	eax, esi
  4928 0000B631 A2[CFE30000]        <1> 	mov	[u.uno], al ; child process number
  4929 0000B636 FE86[F1E00000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN
  4930 0000B63C 66D1E6              <1> 	shl	si, 1 ; multiply si by 2 to get index into p.pid table
  4931 0000B63F 66FF05[68E30000]    <1> 	inc	word [mpid] ; increment m.pid; get a new process name
  4932 0000B646 66A1[68E30000]      <1> 	mov	ax, [mpid]
  4933 0000B64C 668986[60E00000]    <1> 	mov	[esi+p.pid-2], ax ; put new process name 
  4934                              <1> 				  ; in child process' name slot
  4935                              <1> 	;mov	ax, [p.pid]  ; get process name of MainProg
  4936 0000B653 66B80100            <1> 	mov	ax, 1
  4937 0000B657 668986[80E00000]    <1> 	mov	[esi+p.ppid-2], ax ; put parent process name 
  4938                              <1> 			           ; in parent process slot for child
  4939 0000B65E 6648                <1> 	dec	ax ; 0
  4940 0000B660 66A3[B0E30000]      <1> 	mov 	[u.ttyp], ax ; 0
  4941                              <1> 	;;;
  4942 0000B666 A1[05E40000]        <1> 	mov 	eax,  [ii]
  4943                              <1> 	; Retro UNIX 386 v1, 'sysexec' (u2.s)
  4944 0000B66B E89F070000          <1> 	call	iopen
  4945                              <1> 	; 06/06/2016
  4946 0000B670 C605[C3E30000]01    <1> 	mov	byte [u.pri], 1 ; normal priority
  4947                              <1> 	;
  4948 0000B677 EB0A                <1> 	jmp	short sysexec_7 ; 02/05/2016
  4949                              <1> 
  4950                              <1> sysexec_6:
  4951                              <1> 	;;02/05/2016
  4952                              <1> 	; 23/04/2016
  4953                              <1> 	; 18/10/2015 ('sysexec_6')
  4954                              <1> 	; 23/06/2015
  4955                              <1> 	;;mov	eax, [u.pgdir] ; parent's page directory
  4956                              <1> 	;;cmp 	eax, [k_page_dir] ; TRDOS MainProg ? 
  4957                              <1> 	;;je	short sysexec_7
  4958 0000B679 A1[D9E30000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  4959 0000B67E E84C7CFFFF          <1> 	call	deallocate_page_dir
  4960                              <1> sysexec_7:
  4961 0000B683 E87C7BFFFF          <1> 	call	make_page_dir
  4962 0000B688 0F82F689FFFF        <1> 	jc	panic  ; allocation error 
  4963                              <1> 		       ; after a deallocation would be nonsence !?
  4964                              <1> 	; 24/07/2015
  4965                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  4966                              <1> 	;     of the user's page directory
  4967                              <1> 	;     (It is needed for interrupts!)
  4968                              <1> 	; 18/10/2015
  4969 0000B68E 8B15[B8D20000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  4970 0000B694 8B02                <1> 	mov	eax, [edx] ; physical address of
  4971                              <1> 			   ; kernel's first page table (1st 4 MB)
  4972                              <1> 			   ; (PDE 0 of kernel's page directory)
  4973 0000B696 8B15[D9E30000]      <1> 	mov 	edx, [u.pgdir]
  4974 0000B69C 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  4975                              <1> 	;
  4976                              <1> 	; 20/07/2015
  4977 0000B69E BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  4978                              <1> 	; 18/10/2015
  4979 0000B6A3 BE[F0E30000]        <1> 	mov	esi, pcore ; physical start address
  4980                              <1> sysexec_8:	
  4981 0000B6A8 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  4982 0000B6AD E8707BFFFF          <1> 	call	make_page_table
  4983 0000B6B2 0F82CC89FFFF        <1> 	jc	panic
  4984                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  4985 0000B6B8 E8737BFFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  4986 0000B6BD 0F82C189FFFF        <1> 	jc	panic
  4987                              <1> 	;
  4988 0000B6C3 8906                <1> 	mov	[esi], eax ; 24/06/2015
  4989                              <1> 	; ebx = virtual address (24/07/2015)
  4990 0000B6C5 E80881FFFF          <1> 	call 	add_to_swap_queue
  4991                              <1> 	; 18/10/2015
  4992 0000B6CA 81FE[F4E30000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  4993 0000B6D0 740C                <1> 	je	short sysexec_9 ; yes
  4994 0000B6D2 BE[F4E30000]        <1> 	mov	esi, ecore  ; physical address of the last page 
  4995                              <1> 	; 20/07/2015
  4996 0000B6D7 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  4997                              <1> 	; ebx = virtual end address + segment base address - 4K
  4998 0000B6DC EBCA                <1>         jmp     short sysexec_8
  4999                              <1> sysexec_9:
  5000                              <1> 	; 24/04/2016
  5001                              <1> 	; 18/10/2015
  5002                              <1> 	; 26/08/2015
  5003                              <1> 	; 25/06/2015
  5004                              <1> 	; move arguments from kernel stack to [ecore]
  5005                              <1> 	; (argument list/line will be copied from kernel stack
  5006                              <1> 	; frame to the last (stack) page of user's core memory)
  5007                              <1> 	; 18/10/2015
  5008 0000B6DE 8B3D[F4E30000]      <1> 	mov	edi, [ecore]
  5009 0000B6E4 81C700100000        <1> 	add	edi, PAGE_SIZE
  5010 0000B6EA 0FB705[FEE30000]    <1> 	movzx	eax, word [argc]
  5011 0000B6F1 09C0                <1> 	or	eax, eax
  5012 0000B6F3 7509                <1> 	jnz	short sysexec_10
  5013 0000B6F5 89FB                <1> 	mov 	ebx, edi
  5014 0000B6F7 83EB04              <1> 	sub	ebx, 4 
  5015 0000B6FA 8903                <1> 	mov	[ebx], eax ; 0
  5016 0000B6FC EB44                <1> 	jmp 	short sysexec_13
  5017                              <1> sysexec_10:
  5018 0000B6FE 8B0D[A8E30000]      <1> 	mov	ecx, [u.nread]
  5019                              <1> 	;mov	esi, TextBuffer
  5020 0000B704 8B35[00E40000]      <1> 	mov	esi, [argv] ; 24/04/2016 (TRDOS 386  = TRDOS v2.0)
  5021 0000B70A 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  5022 0000B70C 89C2                <1> 	mov	edx, eax
  5023 0000B70E FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  5024 0000B710 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  5025 0000B713 89FB                <1> 	mov	ebx, edi
  5026 0000B715 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  5027 0000B718 29D3                <1> 	sub 	ebx, edx
  5028 0000B71A 89FA                <1> 	mov	edx, edi
  5029 0000B71C F3A4                <1> 	rep	movsb
  5030 0000B71E 89D6                <1> 	mov 	esi, edx
  5031 0000B720 89DF                <1> 	mov 	edi, ebx
  5032 0000B722 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  5033 0000B727 2B15[F4E30000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  5034 0000B72D AB                  <1> 	stosd	; eax = argument count	
  5035                              <1> sysexec_11:
  5036 0000B72E 89F0                <1> 	mov	eax, esi
  5037 0000B730 01D0                <1> 	add	eax, edx
  5038 0000B732 AB                  <1> 	stosd  ; eax = virtual address
  5039 0000B733 FE0D[FEE30000]      <1> 	dec	byte [argc]
  5040 0000B739 7407                <1> 	jz	short sysexec_13
  5041                              <1> sysexec_12:
  5042 0000B73B AC                  <1> 	lodsb
  5043 0000B73C 20C0                <1> 	and	al, al
  5044 0000B73E 75FB                <1> 	jnz	short sysexec_12
  5045 0000B740 EBEC                <1> 	jmp	short sysexec_11
  5046                              <1> sysexec_13:
  5047                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  5048                              <1> 	; 23/06/2015 - 19/10/2015 (Retro UNIX 386 v1, 'sysexec_13')
  5049                              <1> 	;
  5050                              <1> 	; moving arguments to [ecore] is OK here..
  5051                              <1> 	;
  5052                              <1> 	; ebx = beginning addres of argument list pointers
  5053                              <1> 		;	in user's stack
  5054 0000B742 2B1D[F4E30000]      <1> 	sub 	ebx, [ecore]
  5055 0000B748 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  5056                              <1> 			; end of core - 4096 (last page)
  5057                              <1> 			; (virtual address)
  5058 0000B74E 891D[00E40000]      <1> 	mov	[argv], ebx
  5059 0000B754 891D[ACE30000]      <1> 	mov	[u.break], ebx ; available user memory
  5060                              <1> 	;
  5061 0000B75A 29C0                <1> 	sub	eax, eax
  5062 0000B75C C705[A4E30000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  5062 0000B764 0000                <1>
  5063 0000B766 C705[90E30000]-     <1> 	mov	dword [u.fofp], u.off
  5063 0000B76C [9CE30000]          <1>
  5064 0000B770 A3[9CE30000]        <1> 	mov	[u.off], eax ; 0
  5065 0000B775 A3[A0E30000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  5066 0000B77A A1[05E40000]        <1> 	mov	eax, [ii] ; Fist Cluster of the Program (PRG) file
  5067                              <1> 	; EAX = First cluster of the executable file
  5068 0000B77F E831010000          <1> 	call	readi
  5069                              <1> 
  5070 0000B784 8B0D[ACE30000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  5071 0000B78A 890D[A4E30000]      <1> 	mov	[u.count], ecx ; save for overrun check
  5072                              <1> 	;
  5073 0000B790 8B0D[A8E30000]      <1> 	mov	ecx, [u.nread]
  5074 0000B796 890D[ACE30000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  5075 0000B79C 80F920              <1> 	cmp	cl, 32
  5076 0000B79F 7540                <1>         jne     short sysexec_15
  5077                              <1> 	;:
  5078                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  5079 0000B7A1 8B35[F0E30000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  5080                              <1> 		             ; (phys. start addr. of the exec. file)
  5081 0000B7A7 AD                  <1> 	lodsd
  5082 0000B7A8 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  5083 0000B7AC 7533                <1> 	jne	short sysexec_15
  5084 0000B7AE AD                  <1> 	lodsd
  5085 0000B7AF 89C1                <1> 	mov	ecx, eax ; text (code) section size
  5086 0000B7B1 AD                  <1> 	lodsd
  5087 0000B7B2 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  5088 0000B7B4 89CB                <1> 	mov	ebx, ecx
  5089 0000B7B6 AD                  <1> 	lodsd	
  5090 0000B7B7 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  5091 0000B7B9 3B1D[A4E30000]      <1> 	cmp	ebx, [u.count]
  5092 0000B7BF 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  5093                              <1> 	;
  5094                              <1> 	; add bss section size to [u.break]
  5095 0000B7C1 0105[ACE30000]      <1> 	add 	[u.break], eax
  5096                              <1> 	;
  5097 0000B7C7 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  5098                              <1> 	;cmp	ecx, [u.count]
  5099                              <1> 	;jnb	short sysexec_16
  5100 0000B7CA 890D[A4E30000]      <1> 	mov	[u.count], ecx ; required read count
  5101 0000B7D0 EB29                <1> 	jmp	short sysexec_16
  5102                              <1> sysexec_14:
  5103                              <1> 	; insufficient (out of) memory
  5104 0000B7D2 C705[D5E30000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  5104 0000B7DA 0000                <1>
  5105 0000B7DC E922E9FFFF          <1> 	jmp	error
  5106                              <1> sysexec_15:
  5107 0000B7E1 8B15[09E40000]      <1>         mov	edx, [i.size] ; file size
  5108 0000B7E7 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  5109 0000B7E9 7626                <1> 	jna	short sysexec_17 ; no need to next read
  5110 0000B7EB 01D1                <1> 	add	ecx, edx ; [i.size]
  5111 0000B7ED 3B0D[A4E30000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  5112 0000B7F3 77DD                <1> 	ja	short sysexec_14
  5113 0000B7F5 8915[A4E30000]      <1> 	mov	[u.count], edx
  5114                              <1> sysexec_16:
  5115 0000B7FB A1[05E40000]        <1> 	mov	eax, [ii] ; first cluster
  5116 0000B800 E8B0000000          <1> 	call	readi
  5117 0000B805 8B0D[A8E30000]      <1> 	mov	ecx, [u.nread]
  5118 0000B80B 010D[ACE30000]      <1> 	add	[u.break], ecx
  5119                              <1> sysexec_17:
  5120 0000B811 A1[05E40000]        <1> 	mov	eax, [ii] ; first cluster
  5121 0000B816 E8F5050000          <1> 	call	iclose
  5122 0000B81B 31C0                <1> 	xor     eax, eax
  5123 0000B81D FEC0                <1> 	inc	al
  5124 0000B81F 66A3[C4E30000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  5125 0000B825 66A3[C6E30000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  5126 0000B82B 833D[DDE30000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller MainProg (kernel) ?
  5127 0000B832 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  5128                              <1> 	; If the caller is kernel (MainProg), 'sysexec' will come here
  5129 0000B834 8B15[B8D20000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  5130 0000B83A 8915[DDE30000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
  5131                              <1> sysexec_18:
  5132                              <1> 	; 02/05/2016
  5133                              <1> 	; 24/04/2016 (TRDOS 386 = TRDOS v2.0)
  5134                              <1> 	; 18/10/2015 (Retro UNIX 386 v1)
  5135                              <1> 	; 05/08/2015
  5136                              <1> 	; 29/07/2015
  5137 0000B840 8B2D[00E40000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  5138                              <1> 			    ; list pointers (argument count)
  5139 0000B846 FA                  <1> 	cli
  5140 0000B847 8B25[54D20000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
  5141                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  5142                              <1> 			    ; for this process	 
  5143                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  5144                              <1> 	;xor	eax, eax ; 0
  5145 0000B84D FEC8                <1> 	dec	al ; eax = 0
  5146 0000B84F 66BA2300            <1> 	mov	dx, UDATA
  5147 0000B853 6652                <1> 	push	dx  ; user's stack segment
  5148 0000B855 55                  <1> 	push	ebp ; user's stack pointer
  5149                              <1> 		    ; (points to number of arguments)
  5150 0000B856 FB                  <1> 	sti
  5151 0000B857 9C                  <1> 	pushfd	; EFLAGS
  5152                              <1> 		; Set IF for enabling interrupts in user mode	
  5153                              <1> 	;or	dword [esp], 200h 
  5154                              <1> 	;
  5155                              <1> 	;mov	bx, UCODE
  5156                              <1> 	;push	bx ; user's code segment
  5157 0000B858 6A1B                <1> 	push	UCODE
  5158                              <1> 	;push	0
  5159 0000B85A 50                  <1> 	push	eax ; EIP (=0) - start address -	
  5160 0000B85B 8925[78E30000]      <1> 	mov	[u.sp], esp ; 29/07/2015
  5161                              <1> 	; 05/08/2015
  5162                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  5163                              <1> 	; ('push dx' would cause to general protection fault, 
  5164                              <1> 	; after 'pop ds' etc.)
  5165                              <1> 	;
  5166                              <1> 	;; push dx ; ds (UDATA)
  5167                              <1> 	;; push dx ; es (UDATA)
  5168                              <1> 	;; push dx ; fs (UDATA)
  5169                              <1> 	;; push dx ; gs (UDATA)
  5170                              <1> 	;
  5171                              <1> 	; This is a trick to prevent general protection fault
  5172                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  5173 0000B861 8EC2                <1> 	mov 	es, dx ; UDATA
  5174 0000B863 06                  <1> 	push 	es ; ds (UDATA)
  5175 0000B864 06                  <1> 	push 	es ; es (UDATA)
  5176 0000B865 06                  <1> 	push 	es ; fs (UDATA)
  5177 0000B866 06                  <1> 	push	es ; gs (UDATA)
  5178 0000B867 66BA1000            <1> 	mov	dx, KDATA
  5179 0000B86B 8EC2                <1> 	mov	es, dx
  5180                              <1> 	;
  5181                              <1> 	;; pushad simulation
  5182 0000B86D 89E5                <1> 	mov	ebp, esp ; esp before pushad
  5183 0000B86F 50                  <1> 	push	eax ; eax (0)
  5184 0000B870 50                  <1> 	push	eax ; ecx (0)
  5185 0000B871 50                  <1> 	push	eax ; edx (0)
  5186 0000B872 50                  <1> 	push	eax ; ebx (0)
  5187 0000B873 55                  <1> 	push	ebp ; esp before pushad
  5188 0000B874 50                  <1> 	push	eax ; ebp (0)
  5189 0000B875 50                  <1> 	push	eax ; esi (0)		
  5190 0000B876 50                  <1> 	push	eax ; edi (0)	
  5191                              <1> 	;
  5192 0000B877 A3[80E30000]        <1> 	mov	[u.r0], eax ; eax = 0
  5193 0000B87C 8925[7CE30000]      <1> 	mov	[u.usp], esp
  5194                              <1> 
  5195                              <1> 	; 02/05/2016
  5196 0000B882 FE05[75E30000]      <1> 	inc	byte [sysflg] ; 0FFh -> 0
  5197 0000B888 0FB61D[CFE30000]    <1> 	movzx	ebx, byte [u.uno]	
  5198 0000B88F 6683BB[80E00000]01  <1> 	cmp	word [ebx+p.ppid-2], 1 ; MainProg
  5199 0000B897 0F8789E8FFFF        <1> 	ja	sysret0 ; 03/05/2016
  5200 0000B89D 68[23A10000]        <1> 	push	sysret ; * 
  5201 0000B8A2 8925[7CE30000]      <1> 	mov	[u.usp], esp
  5202 0000B8A8 E88B030000          <1> 	call	wswap ; save child process 'u' structure and
  5203                              <1> 		      ; registers
  5204 0000B8AD 8305[7CE30000]04    <1> 	add	dword [u.usp], 4 ; 03/05/2016 
  5205                              <1> sysexec_19: ; 02/05/2016
  5206 0000B8B4 C3                  <1> 	retn ; * 'sysret' ; byte [sysflg] -> 0FFh
  5207                              <1> 
  5208                              <1> readi:
  5209                              <1> 	; 01/05/2016
  5210                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5211                              <1> 	; 20/05/2015 - Retro UNIX 386 v1
  5212                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5213                              <1> 	;
  5214                              <1> 	; Reads from a file whose the first cluster number in EAX
  5215                              <1> 	; 
  5216                              <1> 	; INPUTS ->
  5217                              <1> 	;    EAX - First cluster number of the file
  5218                              <1> 	;    u.count - byte count user desires
  5219                              <1> 	;    u.base - points to user buffer
  5220                              <1> 	;    u.fofp - points to dword with current file offset
  5221                              <1> 	;    i.size - file size
  5222                              <1> 	; OUTPUTS ->
  5223                              <1> 	;    u.count - cleared
  5224                              <1> 	;    u.nread - accumulates total bytes passed back
  5225                              <1> 	;
  5226                              <1> 	; ((EAX)) input/output
  5227                              <1> 	; (Retro UNIX Prototype : 01/03/2013 - 14/12/2012, UNIXCOPY.ASM)
  5228                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, esi, ebp))  
  5229                              <1> 
  5230 0000B8B5 31D2                <1> 	xor	edx, edx ; 0
  5231 0000B8B7 8915[A8E30000]      <1> 	mov 	[u.nread], edx ; 0
  5232 0000B8BD 668915[E5E30000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  5233 0000B8C4 3915[A4E30000]      <1> 	cmp 	[u.count], edx ; 0
  5234 0000B8CA 7701                <1> 	ja 	short readi_1
  5235 0000B8CC C3                  <1> 	retn
  5236                              <1> readi_1:
  5237                              <1> dskr:
  5238                              <1> 	; 01/05/2016
  5239                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5240                              <1> 	; 24/05/2015 - 12/10/2015 (Retro UNIX 386 v1)
  5241                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  5242                              <1> dskr_0:
  5243 0000B8CD 8B15[09E40000]      <1>         mov	edx, [i.size]
  5244 0000B8D3 8B1D[90E30000]      <1> 	mov	ebx, [u.fofp]
  5245 0000B8D9 2B13                <1> 	sub	edx, [ebx]
  5246 0000B8DB 7647                <1> 	jna	short dskr_4
  5247                              <1> 	;
  5248 0000B8DD 50                  <1> 	push	eax ; 01/05/2016
  5249 0000B8DE 3B15[A4E30000]      <1> 	cmp     edx, [u.count] 
  5250 0000B8E4 7306                <1> 	jnb	short dskr_1
  5251 0000B8E6 8915[A4E30000]      <1> 	mov	[u.count], edx
  5252                              <1> dskr_1:
  5253                              <1> 	; EAX = First Cluster
  5254                              <1> 	; [Current_Drv] = Physical drive number 
  5255 0000B8EC E83B000000          <1> 	call	mget_r
  5256                              <1> 	; NOTE: in 'mget_r', relevant sector will be read in buffer
  5257                              <1> 	; if it not already in buffer !
  5258 0000B8F1 BB[15E40000]        <1> 	mov	ebx, readi_buffer
  5259 0000B8F6 803D[E7E30000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  5260 0000B8FD 770F                <1> 	ja	short dskr_3	  ; zf=0 -> the caller is 'namei'
  5261 0000B8FF 66833D[E5E30000]00  <1> 	cmp	word [u.pcount], 0
  5262 0000B907 7705                <1> 	ja	short dskr_3
  5263                              <1> dskr_2:
  5264                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  5265 0000B909 E89A010000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  5266                              <1> dskr_3:
  5267                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
  5268 0000B90E E8F3010000          <1> 	call	sioreg
  5269 0000B913 87F7                <1> 	xchg	esi, edi
  5270                              <1> 	; EDI = file (user data) offset
  5271                              <1> 	; ESI = sector (I/O) buffer offset
  5272                              <1> 	; ECX = byte count
  5273 0000B915 F3A4                <1> 	rep	movsb
  5274                              <1> 	; eax = remain bytes in buffer
  5275                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  5276 0000B917 09C0                <1> 	or	eax, eax
  5277 0000B919 75EE                <1> 	jnz	short dskr_2 ; (page end before system buffer end!)		
  5278 0000B91B 58                  <1> 	pop	eax  ; (first cluster number)
  5279 0000B91C 390D[A4E30000]      <1> 	cmp	[u.count], ecx ; 0
  5280 0000B922 77A9                <1> 	ja	short dskr_0
  5281                              <1> dskr_4:
  5282 0000B924 C605[E7E30000]00    <1> 	mov	byte [u.kcall], 0
  5283 0000B92B C3                  <1> 	retn
  5284                              <1> 
  5285                              <1> mget_r:
  5286                              <1> 	; 29/04/2016
  5287                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5288                              <1> 	; 03/06/2015 (Retro UNIX 386 v1, 'mget', u.5s)
  5289                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5290                              <1> 	;
  5291                              <1> 	; Get existing or (allocate) a new disk block for file
  5292                              <1> 	; 
  5293                              <1> 	; INPUTS ->
  5294                              <1> 	;    u.fofp = file offset pointer
  5295                              <1> 	;    EAX = First Cluster
  5296                              <1> 	;    (u.off = file offset)
  5297                              <1> 	; OUTPUTS ->
  5298                              <1> 	;    EAX = logical sector number
  5299                              <1> 	;    ESI = Logical Dos Drive Description Table address	
  5300                              <1> 	;
  5301                              <1> 	; Modified registers: EDX, EBX, ECX, ESI, EDI, EBP  
  5302                              <1> 
  5303 0000B92C 8B35[90E30000]      <1> 	mov     esi, [u.fofp]
  5304 0000B932 8B1E                <1> 	mov	ebx, [esi] ; u.off
  5305                              <1> 
  5306 0000B934 29C9                <1> 	sub	ecx, ecx
  5307 0000B936 8A2D[7ED30000]      <1> 	mov	ch, [Current_Drv]
  5308                              <1> 
  5309 0000B93C BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5310 0000B941 01CE                <1> 	add	esi, ecx
  5311                              <1> 
  5312 0000B943 380D[ECDF0000]      <1> 	cmp	[readi.valid], cl ; 0
  5313 0000B949 764B                <1> 	jna	short mget_r_0
  5314                              <1> 	
  5315 0000B94B 3A2D[EDDF0000]      <1> 	cmp	ch, [readi.drv]
  5316 0000B951 7543                <1> 	jne	short mget_r_0
  5317                              <1> 
  5318 0000B953 3B05[00E00000]      <1> 	cmp	eax, [readi.fclust]
  5319 0000B959 7567                <1> 	jne	short mget_r_3
  5320                              <1> 	
  5321 0000B95B 668B0D[F4DF0000]    <1> 	mov	cx, [readi.bpc]
  5322 0000B962 41                  <1> 	inc	ecx ; <= 65536
  5323 0000B963 29D2                <1> 	sub	edx, edx
  5324 0000B965 F7F1                <1> 	div	ecx
  5325                              <1> 
  5326 0000B967 8B3D[FCDF0000]      <1> 	mov	edi, [readi.c_index] ; cluster index
  5327                              <1> 
  5328 0000B96D 39F8                <1> 	cmp	eax, edi
  5329 0000B96F 0F858B000000        <1>         jne     mget_r_5  ; (*)
  5330                              <1> 
  5331                              <1> 	; edx = byte offset in cluster (<= 65535)
  5332 0000B975 668915[F6DF0000]    <1> 	mov	[readi.offset], dx
  5333 0000B97C 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5334 0000B980 8815[EFDF0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5335                              <1> 	
  5336 0000B986 A1[F8DF0000]        <1> 	mov	eax, [readi.cluster]
  5337 0000B98B 8B15[04E00000]      <1> 	mov	edx, [readi.fs_index]
  5338 0000B991 E9AF000000          <1>         jmp     mget_r_8
  5339                              <1> 	
  5340                              <1> mget_r_0:
  5341 0000B996 882D[EDDF0000]      <1> 	mov	[readi.drv], ch ; physical drive number
  5342 0000B99C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5343 0000B9A0 7707                <1> 	ja	short  mget_r_1
  5344 0000B9A2 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  5345 0000B9A5 D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  5346 0000B9A7 EB03                <1> 	jmp	short mget_r_2	
  5347                              <1> mget_r_1:
  5348 0000B9A9 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]
  5349                              <1> mget_r_2:
  5350 0000B9AC 880D[EEDF0000]      <1> 	mov	[readi.spc], cl  ; sectors per cluster
  5351                              <1> 	; NOTE: readi bytes per sector value is always 512 ! 
  5352 0000B9B2 66C1E109            <1> 	shl	cx, 9 ; * 512
  5353 0000B9B6 6649                <1> 	dec	cx ; bytes per cluster - 1
  5354 0000B9B8 66890D[F4DF0000]    <1> 	mov	[readi.bpc], cx
  5355 0000B9BF 6629C9              <1> 	sub	cx, cx
  5356                              <1> mget_r_3:
  5357 0000B9C2 A3[00E00000]        <1> 	mov	[readi.fclust], eax ; first cluster (or FDT address)
  5358 0000B9C7 880D[ECDF0000]      <1> 	mov	[readi.valid], cl ; 0 
  5359 0000B9CD 880D[EFDF0000]      <1> 	mov	[readi.s_index], cl ; 0
  5360 0000B9D3 66890D[F6DF0000]    <1> 	mov	[readi.offset], cx ; 0
  5361 0000B9DA 890D[FCDF0000]      <1> 	mov	[readi.c_index], ecx ; 0
  5362 0000B9E0 890D[F8DF0000]      <1> 	mov	[readi.cluster], ecx ; 0
  5363 0000B9E6 890D[F0DF0000]      <1> 	mov	[readi.sector], ecx ; 0
  5364                              <1> mget_r_4:	
  5365 0000B9EC 89D8                <1> 	mov	eax, ebx ; file offset
  5366 0000B9EE 668B0D[F4DF0000]    <1> 	mov	cx, [readi.bpc]
  5367 0000B9F5 41                  <1> 	inc	ecx ; <= 65536
  5368 0000B9F6 29D2                <1> 	sub	edx, edx
  5369 0000B9F8 F7F1                <1> 	div	ecx
  5370 0000B9FA 8B3D[FCDF0000]      <1> 	mov	edi, [readi.c_index] ; previous cluster index
  5371                              <1> mget_r_5:
  5372 0000BA00 A3[FCDF0000]        <1> 	mov	[readi.c_index], eax ; cluster index
  5373                              <1> 	; edx = byte offset in cluster (<= 65535)
  5374 0000BA05 668915[F6DF0000]    <1> 	mov	[readi.offset], dx
  5375 0000BA0C 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5376 0000BA10 8815[EFDF0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5377                              <1> 
  5378 0000BA16 89C1                <1> 	mov	ecx, eax ; current cluster index
  5379 0000BA18 A1[00E00000]        <1> 	mov	eax, [readi.fclust]
  5380 0000BA1D 09C9                <1> 	or	ecx, ecx ; cluster index
  5381 0000BA1F 741F                <1> 	jz	short mget_r_7
  5382                              <1> 
  5383 0000BA21 39CF                <1> 	cmp	edi, ecx
  5384 0000BA23 7710                <1> 	ja	short mget_r_6 ; old cluster index is higher
  5385 0000BA25 8B15[F8DF0000]      <1> 	mov	edx, [readi.cluster]
  5386 0000BA2B 21D2                <1> 	and	edx, edx
  5387 0000BA2D 7406                <1> 	jz	short mget_r_6
  5388                              <1> 	; valid 'readi' parameters (*)
  5389 0000BA2F 89D0                <1> 	mov	eax, edx
  5390 0000BA31 29F9                <1> 	sub	ecx, edi
  5391 0000BA33 7410                <1> 	jz	short mget_r_8
  5392                              <1> mget_r_6:
  5393                              <1> 	; EAX = Beginning cluster
  5394                              <1> 	; EDX = Sector index in disk/file section
  5395                              <1> 	;	(Only for SINGLIX file system!)
  5396                              <1> 	; ECX = Cluster sequence number after the beginning cluster
  5397                              <1> 	; ESI = Logical DOS Drive Description Table address
  5398 0000BA35 E897E5FFFF          <1> 	call	get_cluster_by_index
  5399 0000BA3A 0F82C3E6FFFF        <1> 	jc	error
  5400                              <1> 	; EAX = Cluster number		
  5401                              <1> mget_r_7:
  5402 0000BA40 A3[F8DF0000]        <1> 	mov	[readi.cluster], eax ; FDT number for Singlix File System
  5403                              <1> mget_r_8:
  5404 0000BA45 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5405 0000BA49 764E                <1> 	jna	short  mget_r_13
  5406                              <1> 
  5407 0000BA4B 83E802              <1> 	sub	eax, 2
  5408 0000BA4E 0FB615[EEDF0000]    <1> 	movzx	edx, byte [readi.spc]
  5409 0000BA55 F7E2                <1> 	mul	edx
  5410                              <1> 
  5411 0000BA57 034668              <1> 	add	eax, [esi+LD_DATABegin]
  5412 0000BA5A 8A15[EFDF0000]      <1> 	mov	dl, [readi.s_index]
  5413 0000BA60 01D0                <1> 	add	eax, edx
  5414                              <1> msget_r_9:
  5415                              <1> 	; eax = logical sector number
  5416 0000BA62 803D[ECDF0000]00    <1> 	cmp	byte [readi.valid], 0
  5417 0000BA69 7608                <1> 	jna	short mget_r_10
  5418 0000BA6B 3B05[F0DF0000]      <1> 	cmp	eax, [readi.sector]
  5419 0000BA71 7425                <1> 	je	short mget_r_12 ; sector is already in 'readi' buffer
  5420                              <1> mget_r_10:
  5421 0000BA73 A3[F0DF0000]        <1> 	mov	[readi.sector], eax
  5422 0000BA78 BB[15E40000]        <1> 	mov	ebx, readi_buffer ; buffer address
  5423 0000BA7D B901000000          <1> 	mov	ecx, 1
  5424                              <1> 	; 29/04/2016
  5425                              <1> 	;xor	dl, dl
  5426                              <1> 
  5427                              <1> 	; EAX = Logical sector number
  5428                              <1> 	; ECX = Sector count
  5429                              <1> 	; EBX = Buffer address
  5430                              <1> 	; (EDX = 0)
  5431                              <1> 	; ESI = Logical DOS drive description table address	
  5432                              <1> 
  5433 0000BA82 E8A6030000          <1> 	call	disk_read
  5434 0000BA87 730A                <1> 	jnc	short mget_r_11
  5435                              <1> 
  5436 0000BA89 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  5437 0000BA8E E970E6FFFF          <1> 	jmp	error
  5438                              <1> mget_r_11:
  5439 0000BA93 A1[F0DF0000]        <1> 	mov	eax, [readi.sector]
  5440                              <1> mget_r_12:
  5441 0000BA98 C3                  <1> 	retn
  5442                              <1> mget_r_13:
  5443                              <1> 	; EAX = FDT number
  5444                              <1> 	; EDX = Sector index from FDT sector (0,1,2,3,4...)
  5445 0000BA99 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  5446 0000BA9A 8915[04E00000]      <1> 	mov	[readi.fs_index], edx
  5447 0000BAA0 01D0                <1> 	add	eax, edx
  5448 0000BAA2 EBBE                <1> 	jmp	short msget_r_9
  5449                              <1> 
  5450                              <1> trans_addr_r:
  5451                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  5452                              <1> 	; Translate virtual address to physical address 
  5453                              <1> 	; for reading from user's memory space
  5454                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5455                              <1> 
  5456 0000BAA4 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  5457 0000BAA6 EB04                <1> 	jmp 	short trans_addr_rw
  5458                              <1> 
  5459                              <1> trans_addr_w:
  5460                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5461                              <1> 	; Translate virtual address to physical address 
  5462                              <1> 	; for writing to user's memory space
  5463                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  5464                              <1> 	
  5465 0000BAA8 29D2                <1> 	sub	edx, edx
  5466 0000BAAA FEC2                <1> 	inc	dl ; 1 (write access sign)
  5467                              <1> trans_addr_rw:
  5468 0000BAAC 50                  <1> 	push	eax
  5469 0000BAAD 53                  <1> 	push	ebx
  5470 0000BAAE 52                  <1> 	push 	edx ; r/w sign (in DL)
  5471                              <1> 	;
  5472 0000BAAF 8B1D[A0E30000]      <1> 	mov	ebx, [u.base]
  5473 0000BAB5 E8EE7DFFFF          <1> 	call	get_physical_addr ; get physical address
  5474 0000BABA 730A                <1> 	jnc	short passc_0
  5475 0000BABC A3[D5E30000]        <1> 	mov	[u.error], eax
  5476                              <1> 	;pop	edx
  5477                              <1> 	;pop 	ebx
  5478                              <1> 	;pop	eax
  5479 0000BAC1 E93DE6FFFF          <1> 	jmp	error
  5480                              <1> passc_0:
  5481 0000BAC6 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page
  5482 0000BAC9 5A                  <1> 	pop	edx
  5483 0000BACA 751C                <1> 	jnz	short passc_1
  5484                              <1> 	
  5485 0000BACC 20D2                <1> 	and 	dl, dl
  5486 0000BACE 7418                <1> 	jz	short passc_1
  5487                              <1> 	; read only (duplicated) page -must be copied to a new page-
  5488                              <1> 	; EBX = linear address
  5489 0000BAD0 51                  <1> 	push 	ecx
  5490 0000BAD1 E8687AFFFF          <1> 	call 	copy_page
  5491 0000BAD6 59                  <1> 	pop	ecx
  5492 0000BAD7 721E                <1> 	jc	short passc_2
  5493 0000BAD9 50                  <1> 	push	eax ; physical address of the new/allocated page
  5494 0000BADA E8F37CFFFF          <1> 	call	add_to_swap_queue	
  5495 0000BADF 58                  <1> 	pop	eax
  5496 0000BAE0 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  5497                              <1> 	;mov 	ecx, PAGE_SIZE
  5498                              <1> 	;sub	ecx, ebx 
  5499 0000BAE6 01D8                <1> 	add	eax, ebx  
  5500                              <1> passc_1: 
  5501 0000BAE8 A3[E1E30000]        <1> 	mov 	[u.pbase], eax ; physical address	
  5502 0000BAED 66890D[E5E30000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  5503 0000BAF4 5B                  <1> 	pop	ebx
  5504 0000BAF5 58                  <1> 	pop	eax
  5505 0000BAF6 C3                  <1> 	retn
  5506                              <1> passc_2:
  5507 0000BAF7 C705[D5E30000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
  5507 0000BAFF 0000                <1>
  5508                              <1> 	;pop 	ebx
  5509                              <1> 	;pop	eax
  5510 0000BB01 E9FDE5FFFF          <1> 	jmp	error
  5511                              <1> 
  5512                              <1> sioreg: 
  5513                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5514                              <1> 	; 19/05/2015 - 25/07/2015 (Retro UNIX 386 v1)
  5515                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
  5516                              <1> 	; INPUTS -> 
  5517                              <1> 	;     EBX = system buffer (data) address (r5)
  5518                              <1> 	;     [u.fofp] = pointer to file offset pointer
  5519                              <1> 	;     [u.base] = virtual address of the user buffer
  5520                              <1> 	;     [u.pbase] = physical address of the user buffer
  5521                              <1> 	;     [u.count] = byte count
  5522                              <1> 	;     [u.pcount] = byte count within page frame 			
  5523                              <1> 	; OUTPUTS -> 
  5524                              <1> 	;     ESI = user data offset (r1)
  5525                              <1> 	;     EDI = system (I/O) buffer offset (r2)
  5526                              <1> 	;     ECX = byte count (r3)
  5527                              <1> 	;     EAX = remain bytes after byte count within page frame
  5528                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
  5529                              <1>         ;
  5530                              <1> 	; ((Modified registers:  EDX))
  5531                              <1>  
  5532 0000BB06 8B35[90E30000]      <1>         mov     esi, [u.fofp]
  5533 0000BB0C 8B3E                <1>         mov     edi, [esi]
  5534 0000BB0E 89F9                <1> 	mov	ecx, edi
  5535 0000BB10 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  5536 0000BB16 81E7FF010000        <1> 	and	edi, 1FFh
  5537 0000BB1C 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  5538 0000BB1E F7D9                <1> 	neg	ecx
  5539 0000BB20 3B0D[A4E30000]      <1> 	cmp	ecx, [u.count]
  5540 0000BB26 7606                <1> 	jna	short sioreg_0
  5541 0000BB28 8B0D[A4E30000]      <1> 	mov	ecx, [u.count]
  5542                              <1> sioreg_0:
  5543 0000BB2E 803D[E7E30000]00    <1> 	cmp	byte [u.kcall], 0 
  5544 0000BB35 7613                <1> 	jna	short sioreg_1
  5545                              <1> 	 ; the caller is 'mkdir' or 'namei'
  5546 0000BB37 A1[A0E30000]        <1> 	mov	eax, [u.base]
  5547 0000BB3C A3[E1E30000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  5548 0000BB41 66890D[E5E30000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  5549 0000BB48 EB0B                <1> 	jmp	short sioreg_2
  5550                              <1> sioreg_1:
  5551 0000BB4A 0FB715[E5E30000]    <1> 	movzx	edx, word [u.pcount]
  5552 0000BB51 39D1                <1> 	cmp	ecx, edx	
  5553 0000BB53 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  5554                              <1> sioreg_2: ; 2:
  5555 0000BB55 31C0                <1> 	xor 	eax, eax
  5556                              <1> sioreg_3:
  5557 0000BB57 010D[A8E30000]      <1> 	add 	[u.nread], ecx
  5558 0000BB5D 290D[A4E30000]      <1> 	sub 	[u.count], ecx
  5559 0000BB63 010D[A0E30000]      <1> 	add 	[u.base], ecx
  5560 0000BB69 010E                <1>         add 	[esi], ecx 
  5561 0000BB6B 8B35[E1E30000]      <1> 	mov	esi, [u.pbase]
  5562 0000BB71 66290D[E5E30000]    <1> 	sub	[u.pcount], cx
  5563 0000BB78 010D[E1E30000]      <1> 	add	[u.pbase], ecx
  5564 0000BB7E C3                  <1>         retn
  5565                              <1> sioreg_4:
  5566                              <1> 	; transfer count > [u.pcount] 
  5567                              <1> 	; (ecx > edx)
  5568 0000BB7F 89C8                <1> 	mov	eax, ecx
  5569 0000BB81 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  5570 0000BB83 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  5571 0000BB85 EBD0                <1> 	jmp	short sioreg_3
  5572                              <1> 
  5573                              <1> tswitch: ; Retro UNIX 386 v1
  5574                              <1> tswap:
  5575                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0)
  5576                              <1> 	; 10/05/2015 - 01/09/2015 (Retro UNIX 386 v1)
  5577                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  5578                              <1> 	; time out swap, called when a user times out.
  5579                              <1> 	; the user is put on the low priority queue.
  5580                              <1> 	; This is done by making a link from the last user
  5581                              <1> 	; on the low priority queue to him via a call to 'putlu'.
  5582                              <1> 	; then he is swapped out.
  5583                              <1> 
  5584                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 21/05/2016 **
  5585                              <1> 	;     * when a high priority (event) process will be stopped
  5586                              <1> 	;	(swapped out, swithched out/off), 'tswap/tswitch' will
  5587                              <1> 	;	not add it to a run queue. 
  5588                              <1> 	;	/// What for: Process may be already in a run queue, 
  5589                              <1> 	;	it is unspeficied state because process might be started
  5590                              <1> 	;	by a timer event which does not regard previous priority
  5591                              <1> 	;	level and run queue of the process (for fast executing!).
  5592                              <1> 	;	After the 'run for event', process will be sequenced
  5593                              <1> 	;	to run by it's actual run queue. ///
  5594                              <1> 	;
  5595                              <1> 	; Retro UNIX 386 v1 modification ->
  5596                              <1> 	;       swap (software task switch) is performed by changing
  5597                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  5598                              <1> 	;	as in Retro UNIX 8086 v1.
  5599                              <1> 	;
  5600                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5601                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5602                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5603                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5604                              <1> 	;	compatibles was using 1MB segmented memory 
  5605                              <1> 	;	in 8086/8088 times.
  5606                              <1> 	;
  5607                              <1> 	; INPUTS ->
  5608                              <1> 	;    u.uno - users process number
  5609                              <1> 	;    runq+4 - lowest priority queue
  5610                              <1> 	; OUTPUTS ->
  5611                              <1> 	;    r0 - users process number
  5612                              <1> 	;    r2 - lowest priority queue address
  5613                              <1> 	;
  5614                              <1> 	; ((AX = R0, BX = R2)) output
  5615                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
  5616                              <1> 	;
  5617                              <1> 
  5618                              <1> 	NOTE:
  5619                              <1> 	;* [u.pri] priority level is specified by run queue which is process 
  5620                              <1> 	;  comes to run from.
  5621                              <1> 	;* Initial [u.pri] is 1 ('normal/regular') for programs 
  5622                              <1> 	;  (which are launched by MainProg or 'sysexec'), it is changed
  5623                              <1> 	;  to 2 ('high') by timer event, if program uses 'systimer' system call.
  5624                              <1> 	;* Program (Process) also can change it's running priority 
  5625                              <1> 	;  from 1 to 0 or up to 2 by using 'syspri' system call; but,
  5626                              <1> 	;  if program selects priority level 2 (high) for running, next time 
  5627                              <1> 	;  it is reduced to 1 (normal/regular) because 'syspri' adds this
  5628                              <1> 	;  program to 'run for normal' queue while running duration is a bit
  5629                              <1> 	;  protected from swap/switch out immediate, behalf of other high 
  5630                              <1> 	;  priority process in sequence. Program (with high priority) will not 
  5631                              <1> 	;  be swapped/switched out (by timer event) before it's time quantum 
  5632                              <1> 	;  will be elapsed, but, this will be temporary if program is not using 
  5633                              <1> 	;  timer event function.	  			 	
  5634                              <1> 
  5635                              <1> 	;For example:
  5636                              <1> 	;If a process frequently gets a timer event, it runs at high priority
  5637                              <1> 	;level but when it returns from running it returns to actual run queue,
  5638                              <1> 	;not to 'run for event' queue again.
  5639                              <1> 	;'tswap' will not change the sequence at return/stop(swap out) stage.
  5640                              <1> 	;But if priority level not high (=2, 'run for event'), 'tswap/tswitch'
  5641                              <1> 	;will add the stopping process to relevant run queue according to
  5642                              <1> 	;[u.pri] priority level.
  5643                              <1> 
  5644                              <1> 	; 21/05/2016
  5645 0000BB87 803D[C3E30000]02    <1> 	cmp	byte [u.pri], 2	; high priority (run for event) ?
  5646 0000BB8E 731A                <1> 	jnb	short swap      ; yes, do not add process to the run queue   
  5647                              <1> 	
  5648 0000BB90 BB[6EE30000]        <1> 	mov	ebx, runq+2 	; 'runq_normal' ; normal/regular priority
  5649 0000BB95 803D[C3E30000]00    <1> 	cmp	byte [u.pri], 0
  5650 0000BB9C 7702                <1> 	ja	short tswap_1	; normal priority
  5651                              <1> 
  5652 0000BB9E 43                  <1> 	inc	ebx
  5653 0000BB9F 43                  <1> 	inc	ebx		; runq+4, 'runq_background', low priority
  5654                              <1> tswap_1:
  5655 0000BBA0 A0[CFE30000]        <1> 	mov 	al, [u.uno]
  5656                              <1> 	       	; movb u.uno,r1 / move users process number to r1
  5657                              <1> 		; mov  $runq+4,r2 
  5658                              <1> 			; / move lowest priority queue address to r2
  5659                              <1>       	; ebx = run queue
  5660 0000BBA5 E8F0000000          <1> 	call 	putlu
  5661                              <1> 		; jsr r0,putlu / create link from last user on Q to 
  5662                              <1> 		             ; / u.uno's user
  5663                              <1> 
  5664                              <1> switch: ; Retro UNIX 386 v1
  5665                              <1> swap:
  5666                              <1> 	; 21/05/2016
  5667                              <1> 	; 20/05/2016
  5668                              <1> 	; 02/05/2016
  5669                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5670                              <1> 	; 10/05/2015 - 02/09/2015 (Retro UNIX 386 v1)
  5671                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5672                              <1> 	;
  5673                              <1> 	; 'swap' is routine that controls the swapping of processes
  5674                              <1> 	; in and out of core.
  5675                              <1> 	;
  5676                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 20/05/2016 **
  5677                              <1> 	;     * 3 different priority level is applied 
  5678                              <1> 	;	(just as original unix v1)
  5679                              <1> 	;	1) high priority (event) run queue, 'runq_event'
  5680                              <1> 	;	2) normal priority (regular) run queue, 'runq_normal'
  5681                              <1> 	;	3) low priority (background) run queue, 'runq_backgroud'
  5682                              <1> 	;	'swap' code will run a process which has max. priority
  5683                              <1>         ;       (for earliest event at first)
  5684                              <1> 	;
  5685                              <1> 	; Retro UNIX 386 v1 modification ->
  5686                              <1> 	;       swap (software task switch) is performed by changing
  5687                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  5688                              <1> 	;	as in Retro UNIX 8086 v1.
  5689                              <1> 	;
  5690                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5691                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5692                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5693                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5694                              <1> 	;	compatibles was using 1MB segmented memory 
  5695                              <1> 	;	in 8086/8088 times.
  5696                              <1> 	;
  5697                              <1> 	; INPUTS ->
  5698                              <1> 	;    runq table - contains processes to run.
  5699                              <1> 	;    p.link - contains next process in line to be run.
  5700                              <1> 	;    u.uno - process number of process in core	
  5701                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
  5702                              <1> 	; OUTPUTS ->
  5703                              <1> 	;    (original unix v1 -> present process to its disk block)
  5704                              <1> 	;    (original unix v1 -> new process into core -> 
  5705                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
  5706                              <1> 	;	   for new process)
  5707                              <1> 	;    u.quant = 3 (Time quantum for a process)
  5708                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
  5709                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
  5710                              <1> 	;	 for now, it will swap the process if there is not
  5711                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
  5712                              <1> 	;	 or will count down from 3 to 0 even if there is a
  5713                              <1> 	;        keyboard event locking due to repetitive key strokes.
  5714                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
  5715                              <1> 	;
  5716                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
  5717                              <1> 
  5718                              <1> 	;NOTE:
  5719                              <1> 	;High priority queue is the first for selecting a process to run.
  5720                              <1> 	;If there is not a process in high priority level run queue,
  5721                              <1> 	;a process in normal priority run queue will be selected
  5722                              <1> 	;or a proces in low priority run queue will be selected if normal
  5723                              <1> 	;priority level run queue is empty.
  5724                              <1> 	
  5725                              <1> 	; 21/05/2016 -(3 priority levels, 3 run queues)
  5726 0000BBAA BE[6CE30000]        <1> 	mov	esi, runq ; 'runq_event' ; high priority, 'run for event'
  5727 0000BBAF C605[38E00000]03    <1> 	mov	byte [priority], 3 ; high priority + 1
  5728                              <1> swap_0: ; 1: / search runq table for highest priority process
  5729 0000BBB6 66AD                <1> 	lodsw  ; mov ax, [esi], add esi+2
  5730 0000BBB8 31DB                <1> 	xor	ebx, ebx ; 02/05/2016
  5731 0000BBBA 6621C0              <1> 	and 	ax, ax ; are there any processes to run in this Q entry
  5732 0000BBBD 750E                <1> 	jnz	short swap_2 
  5733                              <1> 	; 21/05/2026
  5734                              <1> 	; runq_normal = runq+2, runq_background = runq+4
  5735 0000BBBF FE0D[38E00000]      <1> 	dec	byte [priority] ; 3 -> 3, 2 -> 1, 1-> 0
  5736 0000BBC5 75EF                <1> 	jnz	short swap_0	
  5737                              <1> 	;cmp	esi, runq+6  ; if zero compare address to end of table
  5738                              <1> 	;jb	short swap_0 ; if not at end, go back
  5739                              <1> swap_1:
  5740                              <1> 	; 02/05/2016
  5741                              <1> 	; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
  5742                              <1> 	; No user process to run...
  5743                              <1> 	; Run the kernel process... MainProg: Internal Command Interpreter  
  5744 0000BBC7 FEC0                <1> 	inc	al ; mov al, 1  ; process number of MainProg
  5745 0000BBC9 FEC3                <1> 	inc	bl ; mov bl, al ; 1
  5746 0000BBCB EB1E                <1> 	jmp	short swap_4
  5747                              <1> swap_2:
  5748                              <1> 	; 21/05/2016
  5749 0000BBCD FE0D[38E00000]      <1> 	dec	byte [priority] ; priority level of present user/process
  5750                              <1> 			        ; 0, 1, 2	   
  5751 0000BBD3 4E                  <1> 	dec	esi
  5752 0000BBD4 4E                  <1>         dec     esi
  5753                              <1> 	;
  5754 0000BBD5 88C3                <1> 	mov	bl, al
  5755 0000BBD7 38E0                <1> 	cmp	al, ah ; is there only 1 process in the queue to be run
  5756 0000BBD9 740A                <1> 	je	short swap_3 ; yes
  5757 0000BBDB 8AA3[E1E00000]      <1> 	mov	ah, [ebx+p.link-1] 
  5758 0000BBE1 8826                <1>        	mov	[esi], ah ; move next process in line into run queue
  5759 0000BBE3 EB06                <1> 	jmp	short swap_4
  5760                              <1> swap_3: 
  5761 0000BBE5 6631D2              <1> 	xor	dx, dx
  5762 0000BBE8 668916              <1> 	mov	[esi], dx ; zero the entry; no processes on the Q
  5763                              <1> swap_4: 
  5764 0000BBEB 8A25[CFE30000]      <1> 	mov 	ah, [u.uno]
  5765 0000BBF1 38C4                <1> 	cmp	ah, al ;is this process the same as the process in core?
  5766 0000BBF3 743B                <1>        	je	short swap_8 ; yes, don't have to swap
  5767 0000BBF5 08E4                <1> 	or	ah, ah  ; is the process # = 0
  5768 0000BBF7 740D                <1>        	jz	short swap_6 ; 'sysexit'
  5769 0000BBF9 8925[7CE30000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  5770 0000BBFF E834000000          <1> 	call	wswap   ; write out core to disk
  5771 0000BC04 EB1C                <1> 	jmp 	short swap_7
  5772                              <1> swap_6:
  5773                              <1> 	; Deallocate memory pages belong to the process
  5774                              <1> 	; which is being terminated.
  5775                              <1> 	; (Retro UNIX 386 v1 modification !)
  5776                              <1> 	;
  5777 0000BC06 53                  <1> 	push	ebx
  5778 0000BC07 A1[D9E30000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  5779 0000BC0C 8B1D[DDE30000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  5780 0000BC12 E8B876FFFF          <1> 	call	deallocate_page_dir
  5781 0000BC17 A1[D0E30000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  5782 0000BC1C E84D77FFFF          <1> 	call	deallocate_page
  5783 0000BC21 5B                  <1> 	pop	ebx
  5784                              <1> swap_7: 
  5785 0000BC22 C0E302              <1> 	shl	bl, 2 ; * 4 
  5786 0000BC25 8B83[FEE00000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  5787 0000BC2B E831000000          <1> 	call	rswap ; read new process into core
  5788                              <1> swap_8: 
  5789                              <1> 	; Retro UNIX  8086 v1 modification !
  5790 0000BC30 C605[C2E30000]04    <1> 	mov	byte [u.quant], time_count 
  5791 0000BC37 C3                  <1> 	retn
  5792                              <1> 
  5793                              <1> wswap:  ; < swap out, swap to disk >
  5794                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5795                              <1> 	; 09/05/2015 (Retro UNIX 386 v1)
  5796                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5797                              <1> 	; 'wswap' writes out the process that is in core onto its 
  5798                              <1> 	; appropriate disk area.
  5799                              <1> 	;
  5800                              <1> 	; Retro UNIX 386 v1 modification ->
  5801                              <1> 	;       User (u) structure content and the user's register content
  5802                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
  5803                              <1> 	;	saving 'u' structure and user registers for task switching).
  5804                              <1> 	;	u.usp - points to kernel stack address which contains
  5805                              <1> 	;		user's registers while entering system call.  
  5806                              <1> 	;	u.sp  - points to kernel stack address 
  5807                              <1> 	;		to return from system call -for IRET-.
  5808                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5809                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5810                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5811                              <1> 	;
  5812                              <1> 	; Retro UNIX 8086 v1 modification ->
  5813                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5814                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5815                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5816                              <1> 	;	compatibles was using 1MB segmented memory 
  5817                              <1> 	;	in 8086/8088 times.
  5818                              <1> 	;
  5819                              <1> 	; INPUTS ->
  5820                              <1> 	;    u.break - points to end of program
  5821                              <1> 	;    u.usp - stack pointer at the moment of swap
  5822                              <1> 	;    core - beginning of process program		
  5823                              <1> 	;    ecore - end of core 	
  5824                              <1> 	;    user - start of user parameter area		
  5825                              <1> 	;    u.uno - user process number	
  5826                              <1> 	;    p.dska - holds block number of process	
  5827                              <1> 	; OUTPUTS ->
  5828                              <1> 	;    swp I/O queue
  5829                              <1> 	;    p.break - negative word count of process 
  5830                              <1> 	;    r1 - process disk address	
  5831                              <1> 	;    r2 - negative word count
  5832                              <1> 	;
  5833                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5834                              <1> 	;
  5835                              <1> 	; INPUTS ->
  5836                              <1> 	;    u.uno - process number (to be swapped out)
  5837                              <1> 	; OUTPUTS ->
  5838                              <1> 	;    none
  5839                              <1> 	;
  5840                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
  5841                              <1> 	;
  5842 0000BC38 8B3D[D0E30000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  5843 0000BC3E B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5844 0000BC43 BE[78E30000]        <1> 	mov	esi, user ; active user (u) structure	
  5845 0000BC48 F3A5                <1> 	rep	movsd
  5846                              <1> 	;
  5847 0000BC4A 8B35[7CE30000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  5848                              <1> 			     ;      points to user registers)
  5849 0000BC50 8B0D[78E30000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5850                              <1> 			     ; (for IRET)
  5851                              <1> 			     ; [u.sp] -> EIP (user)
  5852                              <1> 			     ; [u.sp+4]-> CS (user)
  5853                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5854                              <1> 			     ; [u.sp+12] -> ESP (user)
  5855                              <1> 			     ; [u.sp+16] -> SS (user)	
  5856 0000BC56 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  5857 0000BC58 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5858                              <1> 			     ; (for IRET) 	
  5859 0000BC5B C1E902              <1> 	shr	ecx, 2	     		
  5860 0000BC5E F3A5                <1> 	rep	movsd
  5861 0000BC60 C3                  <1> 	retn
  5862                              <1> 
  5863                              <1> rswap:  ; < swap in, swap from disk >
  5864                              <1> 	; 21/05/2016
  5865                              <1> 	; 03/05/2016
  5866                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5867                              <1> 	; 09/05/2015 - 15/09/2015 (Retro UNIX 386 v1)
  5868                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  5869                              <1> 	; 'rswap' reads a process whose number is in r1, 
  5870                              <1> 	; from disk into core.
  5871                              <1> 	;
  5872                              <1> 	; Retro UNIX 386 v1 modification ->
  5873                              <1> 	;       User (u) structure content and the user's register content
  5874                              <1> 	;	will be restored from process's/user's UPAGE (a page for
  5875                              <1> 	;	saving 'u' structure and user registers for task switching).
  5876                              <1> 	;	u.usp - points to kernel stack address which contains
  5877                              <1> 	;		user's registers while entering system call.  
  5878                              <1> 	;	u.sp  - points to kernel stack address 
  5879                              <1> 	;		to return from system call -for IRET-.
  5880                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  5881                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  5882                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  5883                              <1> 	;
  5884                              <1> 	; RETRO UNIX 8086 v1 modification ->
  5885                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  5886                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  5887                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  5888                              <1> 	;	compatibles was using 1MB segmented memory 
  5889                              <1> 	;	in 8086/8088 times.
  5890                              <1> 	;
  5891                              <1> 	; INPUTS ->
  5892                              <1> 	;    r1 - process number of process to be read in
  5893                              <1> 	;    p.break - negative of word count of process 
  5894                              <1> 	;    p.dska - disk address of the process		
  5895                              <1> 	;    u.emt - determines handling of emt's 	
  5896                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5897                              <1> 	; OUTPUTS ->
  5898                              <1> 	;    8 = (u.ilgins)
  5899                              <1> 	;    24 = (u.emt)
  5900                              <1> 	;    swp - bit 10 is set to indicate read 
  5901                              <1> 	;		(bit 15=0 when reading is done)	
  5902                              <1> 	;    swp+2 - disk block address
  5903                              <1> 	;    swp+4 - negative word count 	
  5904                              <1> 	;      ((swp+6 - address of user structure)) 
  5905                              <1> 	;
  5906                              <1> 	; RETRO UNIX 8086 v1 input/output:
  5907                              <1> 	;
  5908                              <1> 	; INPUTS ->
  5909                              <1> 	;    AL	- new process number (to be swapped in)	 
  5910                              <1> 	; OUTPUTS ->
  5911                              <1> 	;    none
  5912                              <1> 	;
  5913                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
  5914                              <1> 	;
  5915                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
  5916 0000BC61 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  5917 0000BC63 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5918 0000BC68 BF[78E30000]        <1> 	mov	edi, user ; active user (u) structure	
  5919 0000BC6D F3A5                <1> 	rep	movsd
  5920 0000BC6F 58                  <1> 	pop	eax	; 'rswap' return address
  5921                              <1> 	; 
  5922                              <1> 	;; 21/05/2016
  5923 0000BC70 8A0D[38E00000]      <1> 	mov	cl, [priority]
  5924 0000BC76 880D[C3E30000]      <1> 	mov	[u.pri], cl  ; running priority level 
  5925                              <1> 			     ; (specifies run queue which is 
  5926                              <1> 			     ; process comes from)
  5927                              <1> 	;cli
  5928 0000BC7C 8B3D[7CE30000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  5929                              <1> 			     ;     points to user registers)
  5930 0000BC82 8B0D[78E30000]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  5931                              <1> 			     ; (for IRET)
  5932                              <1> 			     ; [u.sp] -> EIP (user)
  5933                              <1> 			     ; [u.sp+4]-> CS (user)
  5934                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  5935                              <1> 			     ; [u.sp+12] -> ESP (user)
  5936                              <1> 			     ; [u.sp+16] -> SS (user)		
  5937 0000BC88 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  5938 0000BC8A 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5939                              <1> 			     ; (for IRET) 	
  5940 0000BC8D C1E902              <1> 	shr	ecx, 2	       		
  5941 0000BC90 F3A5                <1> 	rep	movsd
  5942 0000BC92 8B25[7CE30000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
  5943                              <1> 	;sti
  5944 0000BC98 50                  <1> 	push	eax	; 'rswap' return address
  5945 0000BC99 C3                  <1> 	retn
  5946                              <1> 
  5947                              <1> putlu: 
  5948                              <1> 	; 20/05/2016
  5949                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5950                              <1> 	; 10/05/2015 - 12/09/2015 (Retro UNIX 386 v1)
  5951                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  5952                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
  5953                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
  5954                              <1> 	; the last process on the queue to process in r1 by putting
  5955                              <1> 	; the process number in r1 into the last process's link.
  5956                              <1> 	;
  5957                              <1> 	; INPUTS ->
  5958                              <1> 	;    r1 - user process number
  5959                              <1> 	;    r2 - points to lowest priority queue 
  5960                              <1> 	;    p.dska - disk address of the process		
  5961                              <1> 	;    u.emt - determines handling of emt's 	
  5962                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  5963                              <1> 	; OUTPUTS ->
  5964                              <1> 	;    r3 - process number of last process on the queue upon
  5965                              <1> 	;	  entering putlu
  5966                              <1> 	;    p.link-1 + r3 - process number in r1
  5967                              <1> 	;    r2 - points to lowest priority queue
  5968                              <1> 	;
  5969                              <1> 	; ((Modified registers: EDX, EBX)) 
  5970                              <1> 	;
  5971                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
  5972                              <1> 
  5973                              <1> 	; EBX = r2
  5974                              <1> 	; EAX = r1 (AL=r1b)
  5975                              <1> 
  5976                              <1> 	; 20/05/2016
  5977                              <1> 	; AL = process number (1 to 16) // Retro UNIX 8086, 386 v1 // 
  5978                              <1> 	;     (max. 16 processes available for current kernel version) 
  5979                              <1> 	; EBX = run queue address ; 20/05/2016 (TRDOS 386)
  5980                              <1> 		; which is one of following addresses:
  5981                              <1> 		;  1) 'runq_event' high priority run queue	 	
  5982                              <1> 		;  2) 'runq_normal' normal/regular priority run queue
  5983                              <1> 		;  3) 'runq_background' low priority run queue
  5984                              <1> 
  5985                              <1> 	;mov	ebx, runq
  5986 0000BC9A 0FB613              <1> 	movzx  	edx, byte [ebx]
  5987 0000BC9D 43                  <1> 	inc	ebx
  5988 0000BC9E 20D2                <1> 	and	dl, dl
  5989                              <1> 		; tstb (r2)+ / is queue empty?
  5990 0000BCA0 740A                <1>        	jz	short putlu_1
  5991                              <1> 		; beq 1f / yes, branch
  5992 0000BCA2 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
  5993                              <1> 		; movb (r2),r3 / no, save the "last user" process number
  5994                              <1> 			     ; / in r3
  5995 0000BCA4 8882[E1E00000]      <1>        	mov	[edx+p.link-1], al
  5996                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
  5997                              <1> 			     ; / "last users" link
  5998 0000BCAA EB03                <1> 	jmp	short putlu_2
  5999                              <1> 		; br 2f /
  6000                              <1> putlu_1: ; 1:
  6001 0000BCAC 8843FF              <1> 	mov	[ebx-1], al
  6002                              <1>        		; movb r1,-1(r2) / user is only user; 
  6003                              <1> 			    ; / put process no. at beginning and at end
  6004                              <1> putlu_2: ; 2: 
  6005 0000BCAF 8803                <1> 	mov	[ebx], al
  6006                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
  6007                              <1> 			     ; / on the queue
  6008 0000BCB1 88C2                <1> 	mov	dl, al
  6009 0000BCB3 88B2[E1E00000]      <1>         mov     [edx+p.link-1], dh ; 0
  6010                              <1> 		; dec r2 / restore r2
  6011 0000BCB9 C3                  <1>         retn
  6012                              <1> 		; rts r0
  6013                              <1> sysver:
  6014                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6015 0000BCBA C705[80E30000]0002- <1> 	mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  6015 0000BCC2 0000                <1>
  6016 0000BCC4 E95AE4FFFF          <1> 	jmp	sysret
  6017                              <1> 
  6018                              <1> sysreserved1:
  6019                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  6020                              <1> 	; // name and contect will be changed later //
  6021 0000BCC9 C705[80E30000]E007- <1> 	mov	dword [u.r0], 2016
  6021 0000BCD1 0000                <1>
  6022 0000BCD3 E94BE4FFFF          <1> 	jmp	sysret
  6023                              <1> 
  6024                              <1> syspri: ; change running priority (of the process)
  6025                              <1> 	; 21/05/2016
  6026                              <1> 	; 20/05/2026 - TRDOS 386 (TRDOS v2.0)
  6027                              <1> 	; INPUT ->
  6028                              <1> 	;	BL = priority level
  6029                              <1> 	;	   0 = low running priority (running on background)
  6030                              <1> 	;	   1 = normal/regular priority (running as regular)
  6031                              <1> 	;	   2 = high/event priority (running for event)
  6032                              <1> 	;	   >2 = invalid, it will accepted as 2 (event)
  6033                              <1> 	;	   0FFh = get/return current running priority only	
  6034                              <1> 	; OUTPUT -> 	
  6035                              <1> 	;	* if current [u.pri] < 2
  6036                              <1> 	;	  if BL input < 0FFh ->
  6037                              <1> 	;	     [u.pri] is updated as in BL input (0,1,2)
  6038                              <1> 	;	  if BL input = 0FFh -> AL = [u.pri] (current)
  6039                              <1> 	;	      
  6040                              <1> 	;	* if current [u.pri] = 2
  6041                              <1> 	;	  if BL input < 0FFh -> cf = 1 & AL = 2
  6042                              <1> 	;	  if BL input = 0FFh -> cf = 0 & AL = 2  
  6043                              <1> 	;	
  6044                              <1> 	;	NOTE: 	
  6045                              <1> 	;	If [u.pri] = 2, it can not be changed to 1 or 0;
  6046                              <1> 	;	because, run queue of the running process is unspecified
  6047                              <1> 	;	at this	stage. Process might be started by a timer event
  6048                              <1> 	;	or priority might be changed to high by previous
  6049                              <1> 	;	'syspri' system	call. In both cases, the process is in
  6050                              <1> 	;	'runq_normal' or 'runq_background' queue.
  6051                              <1> 	;	As result of this fact, when the [u.quant] time quantum
  6052                              <1> 	;	of the process is elapsed or 'sysrele' system call is
  6053                              <1> 	;	instructed by the process, 'tswap' ('tswitch') procedure
  6054                              <1> 	;	will be called (to 'swap' or 'switch' out the procedure)
  6055                              <1> 	;	and it will not call 'putlu' to add the (stopping)
  6056                              <1> 	;	process to relevant run queue when [u.pri] = 2.
  6057                              <1> 	;	(Otherwise, it would be possible to add process to
  6058                              <1> 	;	a run queue while it is already in a run queue, wrongly.)
  6059                              <1>   	;
  6060                              <1> 	;	If [u.pri]< 2, 'tswap/tswitch' procedure will call 
  6061                              <1> 	;	'putlu' to add process to relevant run queue
  6062                              <1> 	;	according to [u.pri] value. ('runq_normal' for 1, 
  6063                              <1> 	;	'runq_background' for 0).
  6064                              <1> 	;
  6065                              <1> 	;	If BL input >= 2 and < 0FFh while [u.pri] < 2,
  6066                              <1> 	;	process will be added to 'runq_normal' queue and
  6067                              <1> 	;	[u.pri] will be set to 2. (in 'syspri' system call)
  6068                              <1> 	;
  6069                              <1> 
  6070 0000BCD8 29C0                <1> 	sub	eax, eax ; 0
  6071 0000BCDA A3[D5E30000]        <1> 	mov	[u.error], eax
  6072                              <1> 
  6073 0000BCDF A0[C3E30000]        <1> 	mov	al, [u.pri]
  6074 0000BCE4 A3[80E30000]        <1> 	mov	[u.r0], eax
  6075                              <1> 
  6076 0000BCE9 FEC3                <1> 	inc	bl
  6077 0000BCEB 0F8432E4FFFF        <1> 	jz	sysret ; 0FFh -> 0, get priority level
  6078                              <1> 	
  6079 0000BCF1 3C02                <1> 	cmp	al, 2
  6080 0000BCF3 0F830AE4FFFF        <1> 	jnb	error ; CF = 1 & AL = 2 (& last error = 0)
  6081                              <1> 
  6082 0000BCF9 FECB                <1> 	dec	bl
  6083 0000BCFB 80FB02              <1> 	cmp	bl, 2
  6084 0000BCFE 7602                <1> 	jna	short syspri_1
  6085 0000BD00 B302                <1> 	mov	bl, 2
  6086                              <1> syspri_1:
  6087 0000BD02 881D[C3E30000]      <1> 	mov	[u.pri], bl
  6088 0000BD08 80FB02              <1> 	cmp	bl, 2
  6089 0000BD0B 0F8212E4FFFF        <1>         jb      sysret
  6090                              <1> 
  6091                              <1> 	; here...
  6092                              <1> 	; Priority of current process has been changed to high
  6093                              <1> 	; ('run for event') but current process will be added to
  6094                              <1> 	; 'run as normal' queue. ('run for event' high priority
  6095                              <1> 	; queue is under control of timer -& RTC- interrupt only!) 
  6096                              <1> 	;
  6097                              <1> 	; (Otherwise, process can fall into black hole!
  6098                              <1> 	; e.g. if it is not in waiting list and it has not got 
  6099                              <1> 	; a timer event and it is not in a run queue!
  6100                              <1> 	; Because, when [u.pri] is 2, 'tswap/tswitch' will not 
  6101                              <1> 	; add the stopping process to a run queue.)
  6102                              <1> 
  6103 0000BD11 A0[CFE30000]        <1> 	mov	al, [u.uno]
  6104 0000BD16 BB[6EE30000]        <1> 	mov	ebx, runq_normal ; normal priority !
  6105                              <1> 				 ; [u.pri] is set to high
  6106                              <1> 				 ; but 'runq_event' queue is set
  6107                              <1> 				 ; only by the kernel's timer
  6108                              <1> 				 ; event function (timer interrupt). 
  6109 0000BD1B E87AFFFFFF          <1> 	call	putlu
  6110 0000BD20 E9FEE3FFFF          <1> 	jmp	sysret
  6111                              <1> 
  6112                              <1> cpass: ; / get next character from user area of core and put it in AL (r1)
  6113                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  6114                              <1> 	; 19/05/2015 - 18/10/2015 (Retro UNIX 386 v1)
  6115                              <1> 	; 14/08/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  6116                              <1> 	; INPUTS -> 
  6117                              <1> 	;     [u.base] = virtual address in user area
  6118                              <1> 	;     [u.count] = byte count (max.)
  6119                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
  6120                              <1> 	; OUTPUTS -> 
  6121                              <1> 	;     AL = the character which is pointed by [u.base]
  6122                              <1> 	;     zf = 1 -> transfer count has been completed	
  6123                              <1>         ;
  6124                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
  6125                              <1> 	;
  6126 0000BD25 833D[A4E30000]00    <1> 	cmp 	dword [u.count], 0  ; have all the characters been transferred
  6127                              <1> 			    	    ; i.e., u.count, # of chars. left
  6128 0000BD2C 763F                <1> 	jna	short cpass_3	    ; to be transferred = 0?) yes, branch
  6129 0000BD2E FF0D[A4E30000]      <1> 	dec	dword [u.count]	    ; no, decrement u.count
  6130                              <1>         ; 19/05/2015 
  6131                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
  6132                              <1> 	;		      to physical address
  6133 0000BD34 66833D[E5E30000]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  6134                              <1> 			     ; 1-4095 --> use previous physical base address
  6135                              <1> 			     ; in [u.pbase]
  6136 0000BD3C 770E                <1> 	ja	short cpass_1
  6137 0000BD3E 833D[DDE30000]00    <1> 	cmp     dword [u.ppgdir], 0  ; is the caller os kernel
  6138 0000BD45 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ?  (MainProg)
  6139 0000BD47 E858FDFFFF          <1> 	call	trans_addr_r
  6140                              <1> cpass_1:
  6141 0000BD4C 66FF0D[E5E30000]    <1> 	dec	word [u.pcount]
  6142                              <1> cpass_2: 
  6143 0000BD53 8B15[E1E30000]      <1> 	mov	edx, [u.pbase]
  6144 0000BD59 8A02                <1> 	mov	al, [edx]	; take the character pointed to 
  6145                              <1> 				; by u.base and put it in r1
  6146 0000BD5B FF05[A8E30000]      <1> 	inc	dword [u.nread] ; increment no. of bytes transferred
  6147 0000BD61 FF05[A0E30000]      <1> 	inc	dword [u.base]  ; increment the buffer address to point to the
  6148                              <1> 			        ; next byte
  6149 0000BD67 FF05[E1E30000]      <1> 	inc	dword [u.pbase]
  6150                              <1> cpass_3:
  6151 0000BD6D C3                  <1> 	retn
  6152                              <1> cpass_k:
  6153                              <1> 	; 02/07/2015
  6154                              <1> 	; The caller is os kernel 
  6155                              <1> 	; (get sysexec arguments from kernel's memory space)
  6156 0000BD6E 8B1D[A0E30000]      <1> 	mov	ebx, [u.base]
  6157 0000BD74 66C705[E5E30000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  6157 0000BD7C 10                  <1>
  6158 0000BD7D 891D[E1E30000]      <1> 	mov	[u.pbase], ebx
  6159 0000BD83 EBCE                <1> 	jmp	short cpass_2
  6160                              <1> 
  6161                              <1> transfer_to_user_buffer: ; fast transfer
  6162                              <1> 	; 27/05/2016
  6163                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6164                              <1> 	;
  6165                              <1> 	; INPUT ->
  6166                              <1> 	;	ESI = source address in system space
  6167                              <1> 	;	EDI = user's buffer address
  6168                              <1> 	;	ECX = transfer (byte) count
  6169                              <1> 	;	[u.pgdir] = user's page directory
  6170                              <1> 	; OUTPUT ->
  6171                              <1> 	;	ecx = actual transfer count
  6172                              <1> 	;	cf = 1 -> error
  6173                              <1> 	;	[u.count] = remain byte count
  6174                              <1> 	;
  6175                              <1> 	; Modified registers: eax, ecx
  6176                              <1> 	;
  6177                              <1> 
  6178 0000BD85 21C9                <1> 	and	ecx, ecx
  6179 0000BD87 743B                <1> 	jz	short ttub_4
  6180                              <1> 
  6181 0000BD89 890D[A4E30000]      <1> 	mov	[u.count], ecx
  6182                              <1> 	
  6183 0000BD8F 57                  <1> 	push	edi
  6184 0000BD90 56                  <1> 	push	esi
  6185 0000BD91 53                  <1> 	push	ebx
  6186 0000BD92 52                  <1> 	push	edx
  6187 0000BD93 51                  <1> 	push	ecx
  6188                              <1> 
  6189 0000BD94 89FB                <1> 	mov	ebx, edi
  6190 0000BD96 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  6191                              <1> ttub_1:
  6192                              <1> 	; ebx = virtual (linear) address
  6193                              <1> 	; [u.pgdir] = user's page directory
  6194 0000BD9C E80D7BFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6195 0000BDA1 7222                <1> 	jc	short ttub_5
  6196                              <1> 	; eax = physical address 
  6197                              <1> 	; ecx = remain byte count in page (1-4096)
  6198 0000BDA3 89C7                <1> 	mov	edi, eax
  6199 0000BDA5 A1[A4E30000]        <1> 	mov	eax, [u.count]
  6200 0000BDAA 39C1                <1> 	cmp	ecx, eax
  6201 0000BDAC 7602                <1> 	jna	short ttub_2
  6202 0000BDAE 89C1                <1> 	mov	ecx, eax
  6203                              <1> ttub_2:	
  6204 0000BDB0 29C8                <1> 	sub	eax, ecx
  6205 0000BDB2 01CB                <1> 	add	ebx, ecx
  6206 0000BDB4 F3A4                <1> 	rep	movsb
  6207 0000BDB6 A3[A4E30000]        <1> 	mov	[u.count], eax
  6208 0000BDBB 09C0                <1> 	or	eax, eax
  6209 0000BDBD 75DD                <1> 	jnz	short ttub_1
  6210                              <1> ttub_retn:
  6211                              <1> tfub_retn:
  6212 0000BDBF 59                  <1> 	pop	ecx ; transfer count = actual transfer count
  6213                              <1> ttub_3:
  6214 0000BDC0 5A                  <1> 	pop	edx
  6215 0000BDC1 5B                  <1> 	pop	ebx
  6216 0000BDC2 5E                  <1> 	pop	esi
  6217 0000BDC3 5F                  <1> 	pop	edi
  6218                              <1> ttub_4:
  6219 0000BDC4 C3                  <1> 	retn
  6220                              <1> ttub_5:
  6221 0000BDC5 59                  <1> 	pop	ecx
  6222 0000BDC6 2B0D[A4E30000]      <1> 	sub	ecx, [u.count] ; actual transfer count
  6223 0000BDCC F9                  <1> 	stc
  6224 0000BDCD EBF1                <1> 	jmp	short ttub_3
  6225                              <1> 
  6226                              <1> transfer_from_user_buffer: ; fast transfer
  6227                              <1> 	; 27/05/2016
  6228                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6229                              <1> 	;
  6230                              <1> 	; INPUT ->
  6231                              <1> 	;	ESI = user's buffer address
  6232                              <1> 	;	EDI = destination address in system space
  6233                              <1> 	;	ECX = transfer (byte) count
  6234                              <1> 	;	[u.pgdir] = user's page directory
  6235                              <1> 	; OUTPUT ->
  6236                              <1> 	;	ecx = actual transfer count
  6237                              <1> 	;	cf = 1 -> error
  6238                              <1> 	;	[u.count] = remain byte count
  6239                              <1> 	;
  6240                              <1> 	; Modified registers: eax, ecx
  6241                              <1> 	;
  6242                              <1> 
  6243 0000BDCF 21C9                <1> 	and	ecx, ecx
  6244                              <1> 	;jz	short tfub_4
  6245 0000BDD1 74F1                <1> 	jz	short ttub_4
  6246                              <1> 
  6247 0000BDD3 890D[A4E30000]      <1> 	mov	[u.count], ecx
  6248                              <1> 	
  6249 0000BDD9 57                  <1> 	push	edi
  6250 0000BDDA 56                  <1> 	push	esi
  6251 0000BDDB 53                  <1> 	push	ebx
  6252 0000BDDC 52                  <1> 	push	edx
  6253 0000BDDD 51                  <1> 	push	ecx
  6254                              <1> 
  6255 0000BDDE 89F3                <1> 	mov	ebx, esi
  6256 0000BDE0 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  6257                              <1> tfub_1:
  6258                              <1> 	; ebx = virtual (linear) address
  6259                              <1> 	; [u.pgdir] = user's page directory
  6260 0000BDE6 E8C37AFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6261                              <1> 	;jc	short tfub_5
  6262 0000BDEB 72D8                <1> 	jc	short ttub_5
  6263                              <1> 	; eax = physical address 
  6264                              <1> 	; ecx = remain byte count in page (1-4096)
  6265 0000BDED 89C6                <1> 	mov	esi, eax
  6266 0000BDEF A1[A4E30000]        <1> 	mov	eax, [u.count]
  6267 0000BDF4 39C1                <1> 	cmp	ecx, eax
  6268 0000BDF6 7602                <1> 	jna	short tfub_2
  6269 0000BDF8 89C1                <1> 	mov	ecx, eax
  6270                              <1> tfub_2:	
  6271 0000BDFA 29C8                <1> 	sub	eax, ecx
  6272 0000BDFC 01CB                <1> 	add	ebx, ecx
  6273 0000BDFE F3A4                <1> 	rep	movsb
  6274 0000BE00 A3[A4E30000]        <1> 	mov	[u.count], eax
  6275 0000BE05 09C0                <1> 	or	eax, eax
  6276 0000BE07 75DD                <1> 	jnz	short tfub_1
  6277                              <1> 
  6278 0000BE09 EBB4                <1> 	jmp	short tfub_retn
  6279                              <1> 
  6280                              <1> ;tfub_retn:
  6281                              <1> ;	pop	ecx ; transfer count = actual transfer count
  6282                              <1> ;tfub_3:
  6283                              <1> ;	pop	edx
  6284                              <1> ;	pop	ebx
  6285                              <1> ;	pop	esi
  6286                              <1> ;	pop	edi
  6287                              <1> ;tfub_4:
  6288                              <1> ;	retn
  6289                              <1> ;tfub_5:
  6290                              <1> ;	pop	ecx
  6291                              <1> ;	sub	ecx, [u.count] ; actual transfer count
  6292                              <1> ;	stc
  6293                              <1> ;	jmp	short tfub_3
  6294                              <1> 	
  6295                              <1> ; temporary - 24/01/2016
  6296                              <1> 
  6297                              <1> iget:
  6298 0000BE0B C3                  <1> 	retn
  6299                              <1> poke:
  6300 0000BE0C C3                  <1> 	retn
  6301                              <1> isintr:
  6302 0000BE0D C3                  <1> 	retn
  6303                              <1> writei:
  6304 0000BE0E C3                  <1> 	retn
  6305                              <1> iopen:
  6306 0000BE0F C3                  <1> 	retn
  6307                              <1> iclose:
  6308 0000BE10 C3                  <1> 	retn
  6309                              <1> itrunc:
  6310 0000BE11 C3                  <1> 	retn
  6311                              <1> setimod:
  6312 0000BE12 C3                  <1> 	retn
  6313                              <1> ottyp:
  6314 0000BE13 C3                  <1> 	retn
  6315                              <1> cttyp:
  6316 0000BE14 C3                  <1> 	retn
  6317                              <1> sndc:
  6318 0000BE15 C3                  <1> 	retn
  6319                              <1> access:
  6320 0000BE16 C3                  <1> 	retn
  6321                              <1> passc:
  6322 0000BE17 C3                  <1> 	retn
  6323                              <1> epoch:
  6324 0000BE18 C3                  <1> 	retn
  6325                              <1> set_date_time:
  6326 0000BE19 C3                  <1> 	retn
  6327                              <1> imap:
  6328 0000BE1A C3                  <1> 	retn
  6329                              <1> diskio:
  6330 0000BE1B C3                  <1> 	retn
  6331                              <1> idle:
  6332 0000BE1C C3                  <1> 	retn
  6333                              <1> sleep:
  6334 0000BE1D C3                  <1> 	retn
  1909                                  %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 0000BE1E 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    20 0000BE22 777B                <1>         ja      short lba_write
    21                              <1> 
    22                              <1> chs_write:
    23                              <1> 	; 25/02/2016
    24                              <1> 	; 23/02/2016
    25 0000BE24 C605[71DC0000]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    26 0000BE2B 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 0000BE2D 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    47 0000BE31 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 0000BE33 C605[71DC0000]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 0000BE3A C605[72DC0000]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 0000BE41 50                  <1> 	push	eax			; Linear sector #
    80 0000BE42 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    81                              <1>                 
    82 0000BE43 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    83                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    84 0000BE47 29D2                <1> 	sub	edx, edx
    85 0000BE49 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 0000BE4B 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    90 0000BE4E 6641                <1> 	inc	cx			; To make it 1 based
    91 0000BE50 6651                <1> 	push	cx
    92 0000BE52 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    93 0000BE56 6629D2              <1> 	sub	dx, dx
    94 0000BE59 F7F1                <1> 	div	ecx			; Convert track to head & cyl
    95                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    96 0000BE5B 88D6                <1> 	mov	dh, dl
    97 0000BE5D 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    98 0000BE5F 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
    99                              <1> 
   100 0000BE62 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   101 0000BE64 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   102 0000BE67 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 0000BE69 B001                <1> 	mov	al, 1 ; 25/02/2016
   113 0000BE6B 8A25[71DC0000]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   114                              <1> 	;
   115 0000BE71 E8AF69FFFF          <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 0000BE76 8825[73DC0000]      <1> 	mov	[disk_rw_err], ah
   122                              <1> 	
   123 0000BE7C 59                  <1> 	pop	ecx
   124 0000BE7D 58                  <1> 	pop	eax
   125 0000BE7E 7314                <1> 	jnc	short chs_read_ok
   126                              <1> 
   127 0000BE80 803D[73DC0000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   128 0000BE87 7408                <1> 	je	short chs_read_error_retn
   129                              <1>              
   130 0000BE89 FE0D[72DC0000]      <1> 	dec	byte [retry_count]
   131 0000BE8F 75B0                <1> 	jnz	short chs_read_retry
   132                              <1> 
   133                              <1> chs_read_error_retn:
   134 0000BE91 F9                  <1> 	stc
   135                              <1> 	;retn
   136 0000BE92 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 0000BE94 40                  <1> 	inc	eax ; next sector
   154 0000BE95 81C300020000        <1> 	add	ebx, 512
   155 0000BE9B E29D                <1> 	loop	chs_read_next_sector
   156 0000BE9D EB5E                <1> 	jmp	short update_drv_error_byte
   157                              <1> 
   158                              <1> lba_write:
   159                              <1> 	; 23/02/2016
   160 0000BE9F C605[71DC0000]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   161 0000BEA6 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 0000BEA8 C605[71DC0000]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   185                              <1> 
   186                              <1> lba_rw:
   187                              <1> 	; 17/02/2016
   188 0000BEAF 57                  <1> 	push	edi
   189                              <1> 
   190 0000BEB0 890D[74DC0000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   191                              <1> 
   192 0000BEB6 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 0000BEB9 81F900010000        <1> 	cmp	ecx, 256
   197 0000BEBF 7605                <1> 	jna	short lba_read_rsc
   198 0000BEC1 B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   199                              <1> lba_read_rsc:
   200 0000BEC6 290D[74DC0000]      <1> 	sub	[sector_count], ecx ; remain sectors
   201                              <1> 
   202 0000BECC 89CF                <1> 	mov	edi, ecx 
   203 0000BECE 89C1                <1> 	mov	ecx, eax ; sector number/address
   204                              <1> 
   205 0000BED0 C605[72DC0000]04    <1> 	mov	byte [retry_count], 4
   206                              <1> lba_read_retry:
   207 0000BED7 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 0000BED9 8A25[71DC0000]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   217 0000BEDF E84169FFFF          <1> 	call	int13h
   218                              <1> 	; al = ? (changed)
   219                              <1> 	; ah = error code
   220 0000BEE4 8825[73DC0000]      <1> 	mov	[disk_rw_err], ah
   221 0000BEEA 7334                <1> 	jnc	short lba_read_ok
   222 0000BEEC 80FC80              <1> 	cmp	ah, 80h ; time out?
   223 0000BEEF 740A                <1>         je      short lba_read_stc_retn
   224 0000BEF1 FE0D[72DC0000]      <1> 	dec	byte [retry_count]
   225 0000BEF7 7FDE                <1> 	jg	short lba_read_retry
   226 0000BEF9 743A                <1> 	jz	short lba_read_reset
   227                              <1> 	; sf =  1
   228                              <1> 
   229                              <1> lba_read_stc_retn:
   230 0000BEFB F9                  <1> 	stc
   231                              <1> lba_read_retn:
   232 0000BEFC 5F                  <1> 	pop	edi
   233                              <1> 
   234                              <1> update_drv_error_byte:
   235 0000BEFD 9C                  <1> 	pushf
   236 0000BEFE 53                  <1> 	push	ebx
   237 0000BEFF 6651                <1> 	push	cx
   238                              <1> 	;or	ecx, ecx
   239                              <1> 	;jz	short udrv_errb0
   240 0000BF01 8A0D[73DC0000]      <1> 	mov	cl, [disk_rw_err]
   241                              <1> udrv_errb0:
   242 0000BF07 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   243 0000BF0B 80FB02              <1> 	cmp	bl, 2
   244 0000BF0E 7203                <1>         jb      short udrv_errb1
   245 0000BF10 80EB7E              <1> 	sub	bl, 7Eh
   246                              <1> 	;cmp	bl, 5
   247                              <1> 	;ja	short udrv_errb2	
   248                              <1> udrv_errb1:
   249 0000BF13 81C3[13CE0000]      <1>         add     ebx, drv.error ; 13/02/2016
   250 0000BF19 880B                <1> 	mov	[ebx], cl ; error code
   251                              <1> udrv_errb2:
   252 0000BF1B 6659                <1> 	pop	cx
   253 0000BF1D 5B                  <1> 	pop	ebx
   254 0000BF1E 9D                  <1> 	popf
   255 0000BF1F C3                  <1> 	retn
   256                              <1> 
   257                              <1> lba_read_ok:
   258 0000BF20 89C8                <1> 	mov	eax, ecx ; sector number
   259 0000BF22 01F8                <1> 	add	eax, edi ; sector number (next)
   260 0000BF24 C1E709              <1> 	shl	edi, 9 ; sector count * 512
   261 0000BF27 01FB                <1> 	add	ebx, edi ; next buffer offset
   262                              <1> 
   263 0000BF29 8B0D[74DC0000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   264 0000BF2F 09C9                <1> 	or	ecx, ecx
   265 0000BF31 7586                <1> 	jnz	short lba_read_next
   266 0000BF33 EBC7                <1> 	jmp	short lba_read_retn
   267                              <1> 
   268                              <1> lba_read_reset:
   269 0000BF35 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   270 0000BF37 E8E968FFFF          <1>         call	int13h
   271                              <1> 	; al = ? (changed)
   272                              <1> 	; ah = error code
   273 0000BF3C 7399                <1> 	jnc	short lba_read_retry
   274 0000BF3E EBBC                <1> 	jmp	short lba_read_retn
  1910                                  %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: 20/06/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> 	; 10/06/2016
    16                              <1> 	; 22/05/2016
    17                              <1> 	; 20/05/2016
    18                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
    19                              <1> 	; TRDOS 386 feature only !
    20                              <1> 	;
    21                              <1> 	; INPUT ->
    22                              <1> 	;	AL = process number (next process)
    23                              <1> 	;
    24                              <1> 	;	this process must be added to run sequence
    25                              <1> 	;
    26                              <1> 	;	[u.pri] = priority of present process
    27                              <1> 	;
    28                              <1> 	;	DL = priority (queue)
    29                              <1> 	;	     0 = background (low) ; run on background 
    30                              <1> 	;	     1 = regular (normal) ; run as regular
    31                              <1> 	;	     2 = event (high)     ; run for event
    32                              <1> 	;
    33                              <1> 	;	1) If the requested process is already running:
    34                              <1> 	;	   a) If present priority is high ([u.pri]=2) 
    35                              <1> 	;	      and requested priority is also high, 
    36                              <1> 	;	      there is nothing to do! Because it has been
    37                              <1> 	;	      done already (before this attempt).		 	
    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 0000BF40 89C3                <1> 	mov	ebx, eax
   109 0000BF42 31C0                <1> 	xor	eax, eax
   110 0000BF44 BF[62E00000]        <1> 	mov	edi, p.pid
   111                              <1> srunseq_1:
   112 0000BF49 3A05[CFE30000]      <1>         cmp     al, [u.uno]     ; same process ?
   113 0000BF4F 7514                <1> 	jne	short srunseq_4 ; no
   114                              <1> 
   115 0000BF51 8A25[C3E30000]      <1> 	mov	ah, [u.pri] 	; present/current priority
   116 0000BF57 80FC02              <1> 	cmp	ah, 2       	; 'run for event' priority level
   117 0000BF5A 7229                <1> 	jb	short srunseq_8 ; no
   118                              <1> 
   119                              <1> srunseq_2:
   120                              <1> 	; there is nothing to do!
   121 0000BF5C C3                  <1> 	retn
   122                              <1> 
   123                              <1> srunseq_3:
   124 0000BF5D 3C10                <1>         cmp     al, nproc       ; number of processes = 16 
   125 0000BF5F 7322                <1> 	jnb	short srunseq_7 ; 'p.pid' values do not match !!!???
   126                              <1> 
   127 0000BF61 47                  <1> 	inc	edi
   128 0000BF62 47                  <1> 	inc	edi
   129 0000BF63 EBE4                <1> 	jmp	short srunseq_1
   130                              <1> 
   131                              <1> srunseq_4:
   132                              <1> 	; dl = priority
   133 0000BF65 80FA02              <1> 	cmp	dl, 2 		; event queue
   134 0000BF68 72F2                <1> 	jb	short srunseq_2 ; requested process is not present
   135                              <1> 				; process and priority of requested
   136                              <1> 				; process is not high (event), 
   137                              <1> 				; there is nothing to do!
   138                              <1> 	
   139                              <1> 	; requested process is not present process
   140                              <1> 	; & priority of requested process is high
   141 0000BF6A 3A15[C3E30000]      <1> 	cmp	dl, [u.pri] 	; priority of present process
   142 0000BF70 7606                <1> 	jna	short srunseq_5 ; is high, also
   143                              <1> 	;
   144                              <1> 	; present process will be swapped/switched out
   145 0000BF72 FE05[39E00000]      <1> 	inc	byte [p_change] ; 1
   146                              <1> 
   147                              <1> srunseq_5:
   148                              <1> 	; add process to 'runq_event' queue for new event
   149 0000BF78 BB[6CE30000]        <1> 	mov	ebx, runq_event ; high priority run queue
   150                              <1> 
   151                              <1> srunseq_6:
   152                              <1> 	; al = process number
   153                              <1> 	; ebx = run queue
   154 0000BF7D E818FDFFFF          <1> 	call	putlu
   155 0000BF82 C3                  <1> 	retn
   156                              <1> 
   157                              <1> srunseq_7:
   158 0000BF83 F5                  <1> 	cmc
   159 0000BF84 C3                  <1> 	retn
   160                              <1> 
   161                              <1> srunseq_8:
   162                              <1> 	; present priority of the process is not high
   163                              <1> 	
   164 0000BF85 8815[C3E30000]      <1> 	mov	[u.pri], dl ; new priority 
   165                              <1> 			    ; (will be used by 'tswap')
   166                              <1> 
   167 0000BF8B 80FA02              <1> 	cmp	dl, 2 		; high priority ?
   168 0000BF8E 72F3                <1> 	jb	short srunseq_7 ; no, there is nothing to do
   169                              <1> 				; in addition
   170                              <1> 
   171                              <1> 	; process must be added to relevant run queue, here!
   172                              <1> 	; (new priority is high/event priority and process
   173                              <1> 	; will not be added to a run queue by 'tswap')
   174                              <1> 
   175 0000BF90 BB[6EE30000]        <1> 	mov	ebx, runq_normal ; 'run as regular' queue
   176                              <1> 
   177 0000BF95 20E4                <1> 	and	ah, ah  ;  previous value of [u.pri]
   178 0000BF97 75E4                <1> 	jnz	short srunseq_6
   179                              <1> 
   180 0000BF99 43                  <1> 	inc	ebx
   181 0000BF9A 43                  <1> 	inc	ebx
   182                              <1> 	; ebx = runq_background ; 'run on backgroud' queue 
   183                              <1> 
   184 0000BF9B EBE0                <1> 	jmp	short srunseq_6
   185                              <1> 
   186                              <1> clock:
   187                              <1> 	; 23/05/2016
   188                              <1> 	; 22/05/2016
   189                              <1> 	; 20/05/2016
   190                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   191                              <1> 	; 14/05/2015 - 14/10/2015 (Retro UNIX 386 v1)
   192                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
   193                              <1> 
   194 0000BF9D 803D[C2E30000]00    <1> 	cmp	byte [u.quant], 0
   195 0000BFA4 772C                <1> 	ja	short clk_1
   196                              <1> 	;
   197 0000BFA6 803D[CFE30000]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ? (for Retro UNIX 8086 & 386 v1)
   198                              <1> 				; MainProg (Kernel's Command Interpreter)
   199                              <1> 				; for TRDOS 386.
   200 0000BFAD 7623                <1> 	jna	short clk_1 ; yes, do not swap out
   201                              <1> 	;
   202 0000BFAF 803D[75E30000]FF    <1> 	cmp     byte [sysflg], 0FFh ; user or system space ?
   203 0000BFB6 7520                <1> 	jne	short clk_2 	    ; system space (sysflg <> 0FFh)
   204                              <1> 	;
   205 0000BFB8 66833D[C4E30000]00  <1> 	cmp	word [u.intr], 0
   206 0000BFC0 7616                <1> 	jna	short clk_2
   207                              <1> 	;
   208                              <1> 	; 23/05/2016
   209 0000BFC2 803D[3AE00000]00    <1> 	cmp	byte [multi_tasking], 0
   210 0000BFC9 760D                <1> 	jna	short clk_2
   211                              <1> 	;
   212 0000BFCB FE05[39E00000]      <1> 	inc	byte [p_change] ; it is time to change running process	
   213 0000BFD1 C3                  <1> 	retn
   214                              <1> clk_1:
   215 0000BFD2 FE0D[C2E30000]      <1> 	dec	byte [u.quant]
   216                              <1> clk_2:
   217 0000BFD8 C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
   218                              <1> 
   219                              <1> 
   220                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   221                              <1> int34h:  ; #IOCTL# (I/O port access support for ring 3)
   222                              <1> ; 23/05/2016
   223                              <1> 	; 20/06/2016
   224                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   225                              <1> 	;
   226                              <1> 	; INPUT ->
   227                              <1> 	;	AH = 0 -> read port  (physical IO port)
   228                              <1> 	;	AH = 1 -> write port (physical IO port)
   229                              <1> 	;	AL = data byte
   230                              <1> 	;	DX = Port number (<= 0FFFFh)    	
   231                              <1> 	; OUTPUT ->
   232                              <1> 	;	AL = data byte
   233                              <1> 	;
   234                              <1> 	; Modified registers: none (except AL)
   235                              <1> 	;
   236 0000BFD9 FB                  <1> 	sti	; enable interrupts
   237 0000BFDA 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   238 0000BFDF 80FC01              <1> 	cmp	ah, 1
   239 0000BFE2 7706                <1> 	ja	short int34h_3
   240 0000BFE4 7202                <1> 	jb	short int34h_2
   241                              <1> 	; AH = 1 -> write port
   242 0000BFE6 EE                  <1> 	out	dx, al
   243 0000BFE7 CF                  <1> 	iretd
   244                              <1> int34h_2:
   245                              <1> 	; AH = 0 -> read port
   246 0000BFE8 EC                  <1> 	in	al, dx	
   247 0000BFE9 CF                  <1> 	iretd
   248                              <1> int34h_3:
   249                              <1> 	; AH > 1 -> invalid function for now ; 20/06/2016
   250 0000BFEA 30C0                <1> 	xor	al, al ; 0
   251 0000BFEC 804C240801          <1> 	or	byte [esp+8], 1	; set carry bit of eflags register
   252 0000BFF1 CF                  <1> 	iretd
   253                              <1> 
   254                              <1> INT4Ah:
   255                              <1> 	; 24/01/2016
   256                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
   257 0000BFF2 C3                  <1> 	retn
   258                              <1> 
   259                              <1> ; u0.s
   260                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
   261                              <1> ; Last Modification: 20/11/2015
   262                              <1> 
   263                              <1> com2_int:
   264                              <1> 	; 07/11/2015 
   265                              <1> 	; 24/10/2015
   266                              <1> 	; 23/10/2015
   267                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   268                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   269                              <1> 	; < serial port 2 interrupt handler >
   270                              <1> 	;
   271 0000BFF3 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   272                              <1> 	;push	eax
   273 0000BFF6 66B80900            <1> 	mov	ax, 9
   274 0000BFFA EB07                <1> 	jmp	short comm_int
   275                              <1> com1_int:
   276                              <1> 	; 07/11/2015
   277                              <1> 	; 24/10/2015
   278 0000BFFC 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   279                              <1> 	; 23/10/2015
   280                              <1> 	;push	eax
   281 0000BFFF 66B80800            <1> 	mov	ax, 8
   282                              <1> comm_int:
   283                              <1> 	; 20/11/2015
   284                              <1> 	; 18/11/2015
   285                              <1> 	; 17/11/2015
   286                              <1> 	; 16/11/2015
   287                              <1> 	; 09/11/2015
   288                              <1> 	; 08/11/2015
   289                              <1> 	; 07/11/2015
   290                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
   291                              <1> 	; 01/11/2015
   292                              <1> 	; 26/10/2015
   293                              <1> 	; 23/10/2015
   294 0000C003 53                  <1> 	push	ebx
   295 0000C004 56                  <1> 	push	esi
   296 0000C005 57                  <1> 	push	edi
   297 0000C006 1E                  <1> 	push 	ds
   298 0000C007 06                  <1> 	push 	es
   299                              <1> 	; 18/11/2015
   300 0000C008 0F20DB              <1> 	mov	ebx, cr3
   301 0000C00B 53                  <1> 	push	ebx ; ****
   302                              <1> 	;
   303 0000C00C 51                  <1> 	push	ecx ; ***
   304 0000C00D 52                  <1> 	push	edx ; **
   305                              <1> 	;
   306 0000C00E BB10000000          <1> 	mov	ebx, KDATA
   307 0000C013 8EDB                <1> 	mov	ds, bx
   308 0000C015 8EC3                <1> 	mov	es, bx
   309                              <1> 	;
   310 0000C017 8B0D[B8D20000]      <1> 	mov	ecx, [k_page_dir]
   311 0000C01D 0F22D9              <1> 	mov	cr3, ecx
   312                              <1> 	; 20/11/2015
   313                              <1> 	; Interrupt identification register
   314 0000C020 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
   315                              <1> 	;
   316 0000C024 3C08                <1> 	cmp 	al, 8 
   317 0000C026 7702                <1> 	ja 	short com_i0
   318                              <1> 	;
   319                              <1> 	; 20/11/2015
   320                              <1> 	; 17/11/2015
   321                              <1> 	; 16/11/2015
   322                              <1> 	; 15/11/2015
   323                              <1> 	; 24/10/2015
   324                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   325                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   326                              <1> 	; < serial port 1 interrupt handler >
   327                              <1> 	;
   328 0000C028 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
   329                              <1> com_i0:
   330                              <1> 	;push	eax ; *
   331                              <1> 	; 07/11/2015
   332 0000C02A A2[22D30000]        <1> 	mov 	byte [ccomport], al
   333                              <1> 	; 09/11/2015
   334 0000C02F 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
   335                              <1> 	; 17/11/2015
   336                              <1>  	; reset request for response status
   337 0000C032 88A3[18D30000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   338                              <1> 	;
   339                              <1> 	; 20/11/2015
   340 0000C038 EC                  <1> 	in	al, dx		; read interrupt id. register
   341 0000C039 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   342 0000C03B 2404                <1> 	and	al, 4		; received data available?	
   343 0000C03D 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   344                              <1> 	;
   345                              <1> 	; 20/11/2015
   346 0000C03F 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   347 0000C042 EC                  <1> 	in	al, dx     	; read character
   348                              <1> 	;JMP	$+2	   	; I/O DELAY
   349                              <1> 	; 08/11/2015
   350                              <1> 	; 07/11/2015
   351 0000C043 89DE                <1> 	mov	esi, ebx 
   352 0000C045 89DF                <1> 	mov	edi, ebx
   353 0000C047 81C6[1CD30000]      <1> 	add 	esi, rchar - 8 ; points to last received char
   354 0000C04D 81C7[1ED30000]      <1> 	add	edi, schar - 8 ; points to last sent char
   355 0000C053 8806                <1> 	mov	[esi], al ; received char (current char)
   356                              <1> 	; query
   357 0000C055 20C0                <1> 	and	al, al
   358 0000C057 7527                <1> 	jnz	short com_i2
   359                              <1>    	; response
   360                              <1> 	; 17/11/2015
   361                              <1> 	; set request for response status
   362 0000C059 FE83[18D30000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   363                              <1> 	;
   364 0000C05F 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   365 0000C063 EC                  <1> 	in	al, dx	   	; read line status register 
   366 0000C064 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   367 0000C066 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   368 0000C068 7445                <1> 	jz	short com_eoi 	; no
   369 0000C06A B0FF                <1> 	mov 	al, 0FFh   	; response			
   370 0000C06C 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   371 0000C070 EE                  <1> 	out	dx, al	   	; send on serial port
   372                              <1> 	; 17/11/2015
   373 0000C071 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   374 0000C074 7502                <1> 	jne 	short com_i1    ; no
   375 0000C076 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
   376                              <1> com_i1:
   377                              <1> 	; 17/11/2015
   378                              <1> 	; reset request for response status (again)
   379 0000C078 FE8B[18D30000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   380 0000C07E EB2F                <1> 	jmp	short com_eoi
   381                              <1> com_i2:	
   382                              <1> 	; 08/11/2015
   383 0000C080 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   384 0000C082 7417                <1> 	je	short com_i3	; (check for response signal)
   385                              <1> 	; 07/11/2015
   386 0000C084 3C04                <1> 	cmp	al, 04h	; EOT
   387 0000C086 751C                <1> 	jne	short com_i4	
   388                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
   389                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
   390                              <1> 	; 08/11/2015
   391                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
   392 0000C088 861D[E6D20000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   393 0000C08E E81680FFFF          <1> 	call 	ctrlbrk
   394 0000C093 861D[E6D20000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   395                              <1> 	;mov	al, 04h ; EOT
   396                              <1> 	; 08/11/2015
   397 0000C099 EB09                <1> 	jmp	short com_i4	
   398                              <1> com_i3:
   399                              <1> 	; 08/11/2015
   400                              <1> 	; If 0FFh has been received just after a query
   401                              <1> 	; (schar, ZERO), it is a response signal.
   402                              <1> 	; 17/11/2015
   403 0000C09B 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   404 0000C09E 7704                <1> 	ja	short com_i4 ; no
   405                              <1> 	; reset query status (schar)
   406 0000C0A0 8807                <1> 	mov	[edi], al ; 0FFh
   407 0000C0A2 FEC0                <1> 	inc	al ; 0
   408                              <1> com_i4:
   409                              <1> 	; 27/07/2014
   410                              <1> 	; 09/07/2014
   411 0000C0A4 D0E3                <1> 	shl	bl, 1	
   412 0000C0A6 81C3[E8D20000]      <1> 	add	ebx, ttychr
   413                              <1> 	; 23/07/2014 (always overwrite)
   414                              <1> 	;;cmp	word [ebx], 0
   415                              <1> 	;;ja	short com_eoi
   416                              <1> 	;
   417 0000C0AC 668903              <1> 	mov	[ebx], ax   ; Save ascii code
   418                              <1> 			    ; scan code = 0
   419                              <1> com_eoi:
   420                              <1> 	;mov	al, 20h
   421                              <1> 	;out	20h, al	   ; end of interrupt
   422                              <1> 	;
   423                              <1> 	; 07/11/2015
   424                              <1>       	;pop	eax ; *
   425 0000C0AF A0[22D30000]        <1> 	mov	al, byte [ccomport] ; current COM port
   426                              <1> 	 ; al = tty number (8 or 9)
   427 0000C0B4 E85E010000          <1>         call	wakeup
   428                              <1> com_iret:
   429                              <1> 	; 23/10/2015
   430 0000C0B9 5A                  <1> 	pop	edx ; **
   431 0000C0BA 59                  <1> 	pop	ecx ; ***
   432                              <1> 	; 18/11/2015
   433                              <1> 	;pop	eax ; ****
   434                              <1> 	;mov	cr3, eax
   435                              <1> 	;jmp	iiret
   436 0000C0BB E9FD48FFFF          <1> 	jmp	iiretp
   437                              <1> 
   438                              <1> ;iiretp: ; 01/09/2015
   439                              <1> ;	; 28/08/2015
   440                              <1> ;	pop	eax ; (*) page directory
   441                              <1> ;	mov	cr3, eax
   442                              <1> ;iiret:
   443                              <1> ;	; 22/08/2014
   444                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
   445                              <1> ;	out	20h, al	; 8259 PORT
   446                              <1> ;	;
   447                              <1> ;	pop	es
   448                              <1> ;	pop	ds
   449                              <1> ;	pop	edi
   450                              <1> ;	pop	esi
   451                              <1> ;	pop	ebx ; 29/08/2014
   452                              <1> ;	pop 	eax
   453                              <1> ;	iretd
   454                              <1> 
   455                              <1> sp_init:
   456                              <1> 	; 07/11/2015
   457                              <1> 	; 29/10/2015
   458                              <1> 	; 26/10/2015
   459                              <1> 	; 23/10/2015
   460                              <1> 	; 29/06/2015
   461                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
   462                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
   463                              <1> 	; Initialization of Serial Port Communication Parameters
   464                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   465                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   466                              <1> 	;
   467                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   468                              <1> 	;
   469                              <1> 	; INPUT:  (29/06/2015)
   470                              <1> 	;	AL = 0 for COM1
   471                              <1> 	;	     1 for COM2
   472                              <1> 	;	AH = Communication parameters	
   473                              <1> 	;
   474                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   475                              <1> 	;	Bit	4	3	2	1	0
   476                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   477                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   478                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   479                              <1> 	;		11 = even
   480                              <1> 	;  Baud rate setting bits: (29/06/2015)
   481                              <1> 	;		Retro UNIX 386 v1 feature only !
   482                              <1> 	;	Bit	7    6    5  | Baud rate
   483                              <1> 	;		------------------------
   484                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   485                              <1> 	;		0    0    1  | 9600 (12)
   486                              <1> 	;		0    1    0  | 19200 (6) 
   487                              <1> 	;		0    1	  1  | 38400 (3) 
   488                              <1> 	;		1    0	  0  | 14400 (8)
   489                              <1> 	;		1    0	  1  | 28800 (4)
   490                              <1> 	;		1    1    0  | 57600 (2)
   491                              <1> 	;		1    1    1  | 115200 (1) 	
   492                              <1> 	
   493                              <1> 	; References:	
   494                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
   495                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   496                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
   497                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
   498                              <1> 	;
   499                              <1> 	; Set communication parameters for COM1 (= 03h)	
   500                              <1> 	;
   501 0000C0C0 BB[1ED30000]        <1> 	mov	ebx, com1p		; COM1 parameters  
   502 0000C0C5 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   503                              <1> 	 ; 29/10/2015
   504 0000C0C9 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   505 0000C0CD E86F000000          <1> 	call	sp_i3	; call A4	
   506 0000C0D2 A880                <1> 	test	al, 80h
   507 0000C0D4 7410                <1> 	jz	short sp_i0 ; OK..
   508                              <1> 		; Error !
   509                              <1> 	;mov	dx, 3F8h
   510 0000C0D6 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   511 0000C0D9 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   512 0000C0DD E85F000000          <1> 	call	sp_i3	; call A4	
   513 0000C0E2 A880                <1> 	test	al, 80h
   514 0000C0E4 7508                <1> 	jnz	short sp_i1
   515                              <1> sp_i0:
   516                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
   517                              <1>         ; (INT 14h initialization code disables interrupts.)
   518                              <1> 	;
   519 0000C0E6 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   520 0000C0E9 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   521                              <1> sp_i1:
   522 0000C0EE 43                  <1> 	inc	ebx
   523 0000C0EF 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   524                              <1> 	 ; 29/10/2015
   525 0000C0F3 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   526 0000C0F7 E845000000          <1> 	call	sp_i3	; call A4	
   527 0000C0FC A880                <1> 	test	al, 80h
   528 0000C0FE 7410                <1> 	jz	short sp_i2 ; OK..
   529                              <1> 		; Error !
   530                              <1> 	;mov	dx, 2F8h
   531 0000C100 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   532 0000C103 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   533 0000C107 E835000000          <1> 	call	sp_i3	; call A4	
   534 0000C10C A880                <1> 	test	al, 80h
   535 0000C10E 7530                <1> 	jnz	short sp_i7
   536                              <1> sp_i2:
   537 0000C110 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   538                              <1> sp_i6:
   539                              <1> 	;; COM2 - enabling IRQ 3
   540                              <1> 	; 07/11/2015
   541                              <1> 	; 26/10/2015
   542 0000C113 9C                  <1> 	pushf
   543 0000C114 FA                  <1> 	cli
   544                              <1> 	;
   545 0000C115 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   546 0000C119 EC                  <1> 	in	al, dx 	   		; read register
   547 0000C11A EB00                <1> 	JMP	$+2	   		; I/O DELAY
   548 0000C11C 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   549 0000C11E EE                  <1> 	out	dx, al     		; write back to register
   550 0000C11F EB00                <1> 	JMP	$+2	   		; I/O DELAY
   551 0000C121 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   552 0000C125 EC                  <1> 	in	al, dx     		; read register
   553 0000C126 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   554                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   555 0000C128 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   556 0000C12A EE                  <1> 	out	dx, al 	   		; write back to register
   557 0000C12B EB00                <1> 	JMP	$+2        		; I/O DELAY
   558 0000C12D E421                <1> 	in	al, 21h    		; read interrupt mask register
   559 0000C12F EB00                <1> 	JMP	$+2	   		; I/O DELAY
   560 0000C131 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   561 0000C133 E621                <1> 	out	21h, al    		; write back to register
   562                              <1> 	;
   563                              <1> 	; 23/10/2015
   564 0000C135 B8[F3BF0000]        <1> 	mov 	eax, com2_int
   565 0000C13A A3[12C20000]        <1> 	mov	[com2_irq3], eax
   566                              <1> 	; 26/10/2015
   567 0000C13F 9D                  <1> 	popf	
   568                              <1> sp_i7:
   569 0000C140 C3                  <1> 	retn
   570                              <1> 
   571                              <1> sp_i3:
   572                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   573                              <1> 	; 28/10/2015
   574 0000C141 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   575 0000C143 B000                <1> 	mov	al, 0
   576 0000C145 EE                  <1> 	out	dx, al			; disable serial port interrupt
   577 0000C146 EB00                <1> 	JMP	$+2			; I/O DELAY
   578 0000C148 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   579 0000C14B B080                <1> 	mov	al, 80h			
   580 0000C14D EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   581                              <1> 	;-----	SET BAUD RATE DIVISOR
   582                              <1> 	; 26/10/2015
   583 0000C14E 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   584                              <1> 					; of the divisor value
   585 0000C151 88C8                <1> 	mov	al, cl	; 1
   586 0000C153 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   587                              <1> 					; 2 = 57600 baud
   588                              <1> 					; 3 = 38400 baud
   589                              <1> 					; 6 = 19200 baud
   590                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
   591 0000C154 EB00                <1> 	JMP	$+2			; I/O DELAY
   592 0000C156 28C0                <1> 	sub	al, al
   593 0000C158 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   594                              <1> 					; of the divisor value
   595 0000C15A EE                  <1> 	out	dx, al ; 0
   596 0000C15B EB00                <1> 	JMP	$+2			; I/O DELAY
   597                              <1> 	;	
   598 0000C15D 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   599                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
   600 0000C15F 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   601 0000C162 EE                  <1> 	out	dx, al			
   602 0000C163 EB00                <1> 	JMP	$+2			; I/O DELAY
   603                              <1> 	; 29/10/2015
   604 0000C165 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   605 0000C167 30C0                <1> 	xor	al, al			; 0
   606 0000C169 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   607 0000C16A EB00                <1> 	JMP	$+2	
   608                              <1> sp_i4:
   609                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
   610                              <1> 	; 29/06/2015 (line status after modem status)
   611 0000C16C 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   612                              <1> sp_i4s:
   613 0000C16F EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   614 0000C170 EB00                <1> 	JMP	$+2			; I/O DELAY
   615 0000C172 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   616 0000C174 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   617                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   618 0000C176 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   619                              <1> 	; AL = Line status, AH = Modem status
   620 0000C177 C3                  <1> 	retn
   621                              <1> 
   622                              <1> sp_status:
   623                              <1> 	; 29/06/2015
   624                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
   625                              <1> 	; Get serial port status
   626 0000C178 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   627 0000C17C 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   628                              <1> 					; dx = 2FEh for COM2
   629 0000C17E EBEF                <1> 	jmp	short sp_i4s
   630                              <1> 
   631                              <1> sp_setp: ; Set serial port communication parameters
   632                              <1> 	; 07/11/2015
   633                              <1> 	; 29/10/2015
   634                              <1> 	; 29/06/2015
   635                              <1> 	; Retro UNIX 386 v1 feature only !	
   636                              <1> 	;
   637                              <1> 	; INPUT:
   638                              <1> 	;	AL = 0 for COM1
   639                              <1> 	;	     1 for COM2
   640                              <1> 	;	AH = Communication parameters (*)
   641                              <1> 	; OUTPUT:
   642                              <1> 	;	CL = Line status
   643                              <1> 	;	CH = Modem status
   644                              <1> 	;   If cf = 1 -> Error code in [u.error]
   645                              <1> 	;		 'invalid parameter !' 
   646                              <1> 	;		 	 or
   647                              <1> 	;		 'device not ready !' error
   648                              <1> 	;	
   649                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   650                              <1> 	;	Bit	4	3	2	1	0
   651                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   652                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   653                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   654                              <1> 	;		11 = even
   655                              <1> 	;  Baud rate setting bits: (29/06/2015)
   656                              <1> 	;		Retro UNIX 386 v1 feature only !
   657                              <1> 	;	Bit	7    6    5  | Baud rate
   658                              <1> 	;		------------------------
   659                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   660                              <1> 	;		0    0    1  | 9600 (12)
   661                              <1> 	;		0    1    0  | 19200 (6) 
   662                              <1> 	;		0    1	  1  | 38400 (3) 
   663                              <1> 	;		1    0	  0  | 14400 (8)
   664                              <1> 	;		1    0	  1  | 28800 (4)
   665                              <1> 	;		1    1    0  | 57600 (2)
   666                              <1> 	;		1    1    1  | 115200 (1) 
   667                              <1> 	;
   668                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   669                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   670                              <1> 	;
   671                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   672                              <1> 	;
   673 0000C180 66BAF803            <1> 	mov	dx, 3F8h
   674 0000C184 BB[1ED30000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   675 0000C189 3C01                <1> 	cmp	al, 1
   676 0000C18B 776B                <1> 	ja 	short sp_invp_err
   677 0000C18D 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   678 0000C18F FECE                <1> 	dec	dh ; 2F8h
   679 0000C191 43                  <1> 	inc	ebx ; COM2 control byte offset
   680                              <1> sp_setp1:
   681                              <1> 	; 29/10/2015
   682 0000C192 8823                <1> 	mov	[ebx], ah
   683 0000C194 0FB6CC              <1> 	movzx 	ecx, ah
   684 0000C197 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   685 0000C19A 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   686 0000C19D 8A81[07C20000]      <1> 	mov	al, [ecx+b_div_tbl]
   687 0000C1A3 6689C1              <1> 	mov	cx, ax
   688 0000C1A6 E896FFFFFF          <1> 	call	sp_i3
   689 0000C1AB 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   690 0000C1AE A880                <1> 	test	al, 80h
   691 0000C1B0 740F                <1> 	jz	short sp_setp2
   692 0000C1B2 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   693                              <1> stp_dnr_err:
   694 0000C1B5 C705[D5E30000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   694 0000C1BD 0000                <1>
   695                              <1> 	; CL = Line status, CH = Modem status
   696 0000C1BF F9                  <1> 	stc
   697 0000C1C0 C3                  <1> 	retn
   698                              <1> sp_setp2:
   699 0000C1C1 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   700 0000C1C4 0F8649FFFFFF        <1>         jna     sp_i6 
   701                              <1> 		      ; COM1 (3F?h)
   702                              <1> sp_i5: 
   703                              <1> 	; 07/11/2015
   704                              <1> 	; 26/10/2015
   705                              <1> 	; 29/06/2015
   706                              <1> 	;
   707                              <1> 	;; COM1 - enabling IRQ 4
   708 0000C1CA 9C                  <1> 	pushf
   709 0000C1CB FA                  <1> 	cli
   710 0000C1CC 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   711 0000C1D0 EC                  <1> 	in	al, dx 	   		; read register
   712 0000C1D1 EB00                <1> 	JMP	$+2			; I/O DELAY
   713 0000C1D3 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   714 0000C1D5 EE                  <1> 	out	dx, al     		; write back to register
   715 0000C1D6 EB00                <1> 	JMP	$+2			; I/O DELAY
   716 0000C1D8 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   717 0000C1DC EC                  <1> 	in	al, dx     		; read register
   718 0000C1DD EB00                <1> 	JMP	$+2			; I/O DELAY
   719                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   720 0000C1DF 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   721 0000C1E1 EE                  <1> 	out	dx, al 	   		; write back to register
   722 0000C1E2 EB00                <1> 	JMP	$+2        		; I/O DELAY
   723 0000C1E4 E421                <1> 	in	al, 21h    		; read interrupt mask register
   724 0000C1E6 EB00                <1> 	JMP	$+2			; I/O DELAY
   725 0000C1E8 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   726 0000C1EA E621                <1> 	out	21h, al    		; write back to register
   727                              <1> 	;
   728                              <1> 	; 23/10/2015
   729 0000C1EC B8[FCBF0000]        <1> 	mov 	eax, com1_int
   730 0000C1F1 A3[0EC20000]        <1> 	mov	[com1_irq4], eax
   731                              <1> 	; 26/10/2015
   732 0000C1F6 9D                  <1> 	popf
   733 0000C1F7 C3                  <1> 	retn
   734                              <1> 
   735                              <1> sp_invp_err:
   736 0000C1F8 C705[D5E30000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   736 0000C200 0000                <1>
   737 0000C202 31C9                <1> 	xor	ecx, ecx
   738 0000C204 49                  <1> 	dec	ecx ; 0FFFFh
   739 0000C205 F9                  <1> 	stc
   740 0000C206 C3                  <1> 	retn
   741                              <1> 
   742                              <1> ; 29/10/2015
   743                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   744 0000C207 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   745                              <1> 
   746                              <1> 
   747                              <1> ; 23/10/2015
   748                              <1> com1_irq4:
   749 0000C20E [16C20000]          <1> 	dd dummy_retn
   750                              <1> com2_irq3:
   751 0000C212 [16C20000]          <1> 	dd dummy_retn
   752                              <1> 
   753                              <1> dummy_retn:
   754 0000C216 C3                  <1> 	retn
   755                              <1> 
   756                              <1> wakeup:
   757                              <1> 	; 24/01/2016
   758 0000C217 C3                  <1> 	retn
  1911                                  %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: 17/06/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 0000C218 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 0000C219 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 0000C21A 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 0000C21E 04                  <1> 		db 4
    31 0000C21F 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 0000C220 07                  <1> 		db 7
    34 0000C221 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.200616"
    34 0000C22A 61696E2050726F6772- <1>
    34 0000C233 616D2076322E302E32- <1>
    34 0000C23C 3030363136          <1>
    35 0000C241 0D0A                <1> 		db 0Dh, 0Ah
    36 0000C243 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
    36 0000C24C 616E2054616E203230- <1>
    36 0000C255 30352D32303136      <1>
    37 0000C25C 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile: ; 14/04/2016
    40 0000C25F 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 0000C268 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 0000C26C 5452444F53          <1> 		db "TRDOS"
    44 0000C271 00                  <1> 		db 0
    45 0000C272 00<rept>            <1>                 times 5 db 0
    46 0000C277 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 0000C278 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 0000C27C 434400              <1> Cmd_Cd:		db "CD", 0
    52 0000C27F 433A00              <1> Cmd_Drive:	db "C:", 0
    53 0000C282 56455200            <1> Cmd_Ver:	db "VER", 0
    54 0000C286 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 0000C28B 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 0000C292 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 0000C299 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 0000C2A2 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 0000C2A7 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 0000C2AC 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 0000C2B0 53455400            <1> Cmd_Set:	db "SET", 0 
    62 0000C2B4 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 0000C2B8 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 0000C2BD 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 0000C2C1 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 0000C2C8 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 0000C2CF 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 0000C2D5 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 0000C2DB 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 0000C2E0 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 0000C2E5 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 0000C2EA 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 0000C2EE 00                  <1> 		db 0
    74 0000C2EF 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 0000C2F4 5245414446494C4500  <1> Cmd_ReadFile:	db "READFILE", 0
    76 0000C2FD 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    77 0000C302 2A00                <1> Cmd_Remark:	db "*", 0
    78 0000C304 3F00                <1> Cmd_Help:	db "?", 0
    79 0000C306 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    80 0000C30D 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    81 0000C315 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    82 0000C31B 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    83                              <1> 		
    84 0000C320 00                  <1> 		db 0
    85                              <1> 
    86                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    87                              <1> invalid_fname_chars:
    88 0000C321 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    89 0000C329 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    90 0000C330 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 0000C335 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    95 0000C33E 206461746520286464- <1>
    95 0000C347 2D6D6D2D7979293A20  <1>
    96 0000C350 00                  <1>                 db 0
    97                              <1> Msg_Show_Date:
    98 0000C351 43757272656E742064- <1>                 db   'Current date is '
    98 0000C35A 61746520697320      <1>
    99 0000C361 30                  <1> Day:            db   '0'
   100 0000C362 30                  <1> 		db   '0'
   101 0000C363 2F                  <1>                 db   '/'
   102 0000C364 30                  <1> Month:          db   '0'
   103 0000C365 30                  <1> 		db   '0'
   104 0000C366 2F                  <1>                 db   '/'
   105 0000C367 30                  <1> Century:        db   '0'
   106 0000C368 30                  <1>                 db   '0'
   107 0000C369 30                  <1> Year:           db   '0'
   108 0000C36A 30                  <1> 		db   '0'
   109 0000C36B 0D0A00              <1>                 db   0Dh, 0Ah, 0
   110                              <1> 
   111                              <1> Msg_Enter_Time:
   112 0000C36E 456E746572206E6577- <1> 		db 'Enter new time: '
   112 0000C377 2074696D653A20      <1>
   113 0000C37E 00                  <1> 		db 0
   114                              <1> Msg_Show_Time:
   115 0000C37F 43757272656E742074- <1> 		db   'Current time is '
   115 0000C388 696D6520697320      <1>
   116 0000C38F 30                  <1> Hour:           db   '0'
   117 0000C390 30                  <1> 		db   '0'
   118 0000C391 3A                  <1> 		db   ':'
   119 0000C392 30                  <1> Minute:         db   '0'
   120 0000C393 30                  <1> 		db   '0'
   121 0000C394 3A                  <1> 		db   ':'
   122 0000C395 30                  <1> Second:         db   '0'
   123 0000C396 30                  <1> 		db   '0'
   124 0000C397 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 0000C39A 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   130 0000C3A3 730D0A00            <1>
   131                              <1> VolSize_Bytes:
   132 0000C3A7 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   133                              <1> Volume_in_drive:
   134 0000C3B0 0D0A                <1> 		db 0Dh, 0Ah
   135                              <1> Vol_FS_Name:
   136 0000C3B2 54522046533120      <1> 		db "TR FS1 "
   137 0000C3B9 566F6C756D6520696E- <1> 		db "Volume in drive "
   137 0000C3C2 20647269766520      <1>
   138 0000C3C9 30                  <1> Vol_Drv_Name:   db 30h
   139 0000C3CA 3A                  <1> 		db ":"
   140 0000C3CB 20697320            <1> 		db " is "
   141 0000C3CF 0D0A00              <1> 		db 0Dh, 0Ah, 0
   142                              <1> Dir_Drive_Str:
   143 0000C3D2 54522D444F53204472- <1>                 db "TR-DOS Drive "
   143 0000C3DB 69766520            <1>
   144                              <1> Dir_Drive_Name:
   145 0000C3DF 303A                <1>                 db "0:"
   146 0000C3E1 0D0A                <1>                 db  0Dh, 0Ah
   147                              <1> Vol_Str_Header:
   148 0000C3E3 566F6C756D65204E61- <1>                 db "Volume Name: "
   148 0000C3EC 6D653A20            <1>
   149                              <1> Vol_Name:
   150 0000C3F0 00<rept>            <1> 		times 64 db 0
   151 0000C430 00                  <1> 		db 0
   152                              <1> Vol_Serial_Header:
   153 0000C431 0D0A                <1> 		db 0Dh, 0Ah
   154 0000C433 566F6C756D65205365- <1> 		db "Volume Serial No: "
   154 0000C43C 7269616C204E6F3A20  <1>
   155                              <1> Vol_Serial1:
   156 0000C445 30303030            <1> 		db "0000"
   157 0000C449 2D                  <1> 		db "-"
   158                              <1> Vol_Serial2:
   159 0000C44A 30303030            <1> 		db "0000"
   160 0000C44E 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 0000C451 0D0A                <1> 		db 0Dh, 0Ah
   166 0000C453 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   166 0000C45C 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 0000C462 467265652053706163- <1> 		db "Free Space  : ", 0
   174 0000C46B 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 0000C471 4469726563746F7279- <1>                 db "Directory: "
   181 0000C47A 3A20                <1>
   182 0000C47C 2F                  <1> Dir_Str_Root:   db "/"
   183 0000C47D 00<rept>            <1> Dir_Str:        times 64 db 0
   184 0000C4BD 00000000            <1>                 dd 0
   185 0000C4C1 00                  <1>                 db 0
   186                              <1> 
   187                              <1> Msg_Bad_Command:
   188 0000C4C2 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   188 0000C4CB 6E64206F722066696C- <1>
   188 0000C4D4 65206E616D6521      <1>
   189 0000C4DB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   190                              <1> 
   191                              <1> msgl_drv_not_ready: 
   192 0000C4DE 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 0000C4E1 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   197 0000C4EA 207265616479206F72- <1>
   197 0000C4F3 207265616420657272- <1>
   197 0000C4FC 6F7221              <1>
   198 0000C4FF 0D0A00              <1>                 db 0Dh, 0Ah, 0
   199                              <1> 
   200                              <1> Msg_Not_Ready_Write_Err:
   201 0000C502 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   201 0000C50B 207265616479206F72- <1>
   201 0000C514 207772697465206572- <1>
   201 0000C51D 726F7221            <1>
   202 0000C521 0D0A00              <1>                 db 0Dh, 0Ah, 0
   203                              <1> 
   204                              <1> Msg_Dir_Not_Found:
   205 0000C524 4469726563746F7279- <1>                 db "Directory not found!"
   205 0000C52D 206E6F7420666F756E- <1>
   205 0000C536 6421                <1>
   206 0000C538 0D0A00              <1>                 db 0Dh, 0Ah, 0
   207                              <1> 
   208                              <1> Msg_File_Not_Found:
   209 0000C53B 46696C65206E6F7420- <1>                 db "File not found!"
   209 0000C544 666F756E6421        <1>
   210 0000C54A 0D0A00              <1>                 db 0Dh, 0Ah, 0
   211                              <1> 
   212                              <1> Msg_File_Directory_Not_Found:
   213 0000C54D 46696C65206F722064- <1>                 db "File or directory not found!"
   213 0000C556 69726563746F727920- <1>
   213 0000C55F 6E6F7420666F756E64- <1>
   213 0000C568 21                  <1>
   214 0000C569 0D0A00              <1>                 db 0Dh, 0Ah, 0
   215                              <1> 
   216                              <1> Msg_LongName_Not_Found:
   217 0000C56C 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   217 0000C575 206E6F7420666F756E- <1>
   217 0000C57E 6421                <1>
   218 0000C580 0D0A00              <1>                 db 0Dh, 0Ah, 0
   219                              <1> 
   220                              <1> Msg_Insufficient_Memory:
   221 0000C583 496E73756666696369- <1>                 db "Insufficient memory!"
   221 0000C58C 656E74206D656D6F72- <1>
   221 0000C595 7921                <1>
   222 0000C597 0D0A00              <1>                 db 0Dh, 0Ah, 0
   223                              <1> 
   224                              <1> Msg_Error_Code:
   225 0000C59A 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   225 0000C5A3 61696C656421204572- <1>
   225 0000C5AC 726F7220636F646520- <1>
   225 0000C5B5 3A20                <1>
   226 0000C5B7 303068              <1> error_code_hex: db '00h'
   227 0000C5BA 0A0A00              <1>                 db 0Ah, 0Ah, 0
   228                              <1> 
   229 0000C5BD 90                  <1> align 2
   230                              <1> 
   231                              <1> ; 10/02/2016
   232                              <1> ; DIR.ASM - 09/10/2011
   233                              <1> 
   234 0000C5BE 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   234 0000C5C7 20                  <1>
   235                              <1> 
   236                              <1> File_Name:
   237 0000C5C8 20<rept>            <1>                 times 12 db 20h
   238 0000C5D4 20                  <1> 		db 20h
   239                              <1> Dir_Or_FileSize:
   240 0000C5D5 20<rept>            <1>                 times 10 db 20h
   241 0000C5DF 20                  <1> 		db 20h
   242                              <1> File_Attribute:
   243 0000C5E0 20202020            <1> 		dd 20202020h
   244 0000C5E4 20                  <1> 		db 20h
   245                              <1> File_Day:
   246 0000C5E5 3030                <1>                 db '0','0'
   247 0000C5E7 2F                  <1> 		db '/'
   248                              <1> File_Month:
   249 0000C5E8 3030                <1>                 db '0','0'
   250 0000C5EA 2F                  <1> 		db '/'
   251                              <1> File_Year:
   252 0000C5EB 30303030            <1>                 db '0','0','0','0'
   253 0000C5EF 20                  <1> 		db 20h
   254                              <1> File_Hour:
   255 0000C5F0 3030                <1>                 db '0','0'
   256 0000C5F2 3A                  <1> 		db ':'
   257                              <1> File_Minute:
   258 0000C5F3 3030                <1>                 db '0','0'
   259 0000C5F5 00                  <1> 		db 0
   260                              <1> 
   261                              <1> Decimal_File_Count_Header:
   262 0000C5F6 0D0A                <1> 		db 0Dh, 0Ah
   263                              <1> Decimal_File_Count:
   264 0000C5F8 00<rept>            <1> 		times 6 db 0
   265                              <1> 
   266 0000C5FE 2066696C6528732920- <1> str_files:	db " file(s) & "
   266 0000C607 2620                <1>
   267                              <1> Decimal_Dir_Count: 
   268 0000C609 00<rept>            <1> 		times 6 db 0
   269                              <1> str_dirs:       
   270 0000C60F 206469726563746F72- <1> 		db " directory(s) "
   270 0000C618 7928732920          <1>
   271 0000C61D 0D0A00              <1> 		db 0Dh, 0Ah, 0
   272                              <1> 
   273 0000C620 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   273 0000C629 696E2066696C652873- <1>
   273 0000C632 29                  <1>
   274 0000C633 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 0000C636 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   279 0000C63F 696C65206F72206469- <1>
   279 0000C648 726563746F7279206E- <1>
   279 0000C651 616D65206368617261- <1>
   279 0000C65A 637465727321        <1>
   280 0000C660 0D0A00              <1>         	db 0Dh, 0Ah, 0
   281                              <1> ; 21/02/2016
   282 0000C663 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   282 0000C66C 69726563746F727920- <1>
   282 0000C675 6E616D652065786973- <1>
   282 0000C67E 747321              <1>
   283 0000C681 0D0A00              <1>                 db 0Dh, 0Ah, 0
   284                              <1> Msg_DoYouWantMkdir:
   285 0000C684 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   285 0000C68D 6E7420746F206D616B- <1>
   285 0000C696 65206469726563746F- <1>
   285 0000C69F 72792000            <1>
   286 0000C6A3 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   286 0000C6AC 00                  <1>
   287 0000C6AD 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   288 0000C6B1 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   289                              <1> 
   290                              <1> ; 27/02/2016
   291                              <1> Msg_DoYouWantRmDir:
   292 0000C6B7 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   292 0000C6C0 6E7420746F2064656C- <1>
   292 0000C6C9 657465206469726563- <1>
   292 0000C6D2 746F72792000        <1>
   293                              <1> Msg_Dir_Not_Empty:
   294 0000C6D8 4469726563746F7279- <1>                 db "Directory not empty!"
   294 0000C6E1 206E6F7420656D7074- <1>
   294 0000C6EA 7921                <1>
   295 0000C6EC 0D0A00              <1>                 db 0Dh, 0Ah, 0
   296                              <1> 
   297                              <1> Msg_DoYouWantDelete:
   298 0000C6EF 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   298 0000C6F8 6E7420746F2064656C- <1>
   298 0000C701 6574652066696C6520- <1>
   298 0000C70A 00                  <1>
   299                              <1> 
   300 0000C70B 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   300 0000C714 2E0D0A00            <1>
   301                              <1> 
   302                              <1> Msg_Permission_Denied:
   303 0000C718 07                  <1>                 db 7
   304 0000C719 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   304 0000C722 6E2064656E69656421- <1>
   304 0000C72B 0D0A00              <1>
   305                              <1> 
   306                              <1> ; 04/03/2016
   307 0000C72E 4E657720            <1> Msg_New:        db "New "
   308 0000C732 00                  <1>                 db 0
   309                              <1> Str_Attributes:
   310 0000C733 417474726962757465- <1>                 db "Attributes : "
   310 0000C73C 73203A20            <1>
   311 0000C740 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   312 0000C746 00                  <1>                 db 0
   313                              <1> 
   314                              <1> ; 06/03/2016
   315                              <1> ; CMD_INTR.ASM - 16/11/2010 
   316                              <1> Msg_DoYouWantRename:
   317 0000C747 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   317 0000C750 6E7420746F2072656E- <1>
   317 0000C759 616D652000          <1>
   318 0000C75E 66696C652000        <1> Rename_File:    db "file ", 0
   319 0000C764 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   319 0000C76D 2000                <1>
   320 0000C76F 00<rept>            <1> Rename_OldName: times 13 db 0
   321 0000C77C 20617320            <1> Msg_File_rename_as: db " as "
   322 0000C780 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 0000C78D 4E6F742073616D6520- <1>                 db "Not same drive!" 
   327 0000C796 647269766521        <1>
   328 0000C79C 0D0A00              <1>                 db 0Dh, 0Ah, 0 
   329                              <1> 
   330                              <1> Msg_DoYouWantMoveFile:
   331 0000C79F 446F20796F75207761- <1>                 db "Do you want to move file", 0
   331 0000C7A8 6E7420746F206D6F76- <1>
   331 0000C7B1 652066696C6500      <1>
   332                              <1> 
   333                              <1> msg_insufficient_disk_space:
   334 0000C7B8 496E73756666696369- <1>                 db "Insufficient disk space!" 
   334 0000C7C1 656E74206469736B20- <1>
   334 0000C7CA 737061636521        <1>
   335 0000C7D0 0D0A00              <1>                 db 0Dh, 0Ah, 0
   336                              <1> 
   337                              <1> ; 01/08/2010
   338                              <1> msg_source_file: 
   339 0000C7D3 0D0A536F7572636520- <1> 		db 0Dh, 0Ah, "Source file name      :   "
   339 0000C7DC 66696C65206E616D65- <1>
   339 0000C7E5 2020202020203A2020- <1>
   339 0000C7EE 20                  <1>
   340                              <1> msg_source_file_drv: 
   341 0000C7EF 203A00              <1> 		db " :", 0
   342                              <1> msg_destination_file: 
   343 0000C7F2 0D0A44657374696E61- <1> 		db 0Dh, 0Ah, "Destination file name :   "
   343 0000C7FB 74696F6E2066696C65- <1>
   343 0000C804 206E616D65203A2020- <1>
   343 0000C80D 20                  <1>
   344                              <1> msg_destination_file_drv: 
   345 0000C80E 203A00              <1> 		db " :", 0
   346                              <1> msg_copy_nextline: 
   347 0000C811 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 0000C814 446F20796F75207761- <1>                 db "Do you want to overwrite file ",0
   353 0000C81D 6E7420746F206F7665- <1>
   353 0000C826 727772697465206669- <1>
   353 0000C82F 6C652000            <1>
   354                              <1>   
   355                              <1> Msg_DoYouWantCopyFile:
   356 0000C833 446F20796F75207761- <1>                 db "Do you want to copy file",0
   356 0000C83C 6E7420746F20636F70- <1>
   356 0000C845 792066696C6500      <1>
   357                              <1> 
   358                              <1> Msg_read_file_error_before_EOF:
   359 0000C84C 46696C652072656164- <1> 		db "File reading error! (before EOF)"
   359 0000C855 696E67206572726F72- <1>
   359 0000C85E 2120286265666F7265- <1>
   359 0000C867 20454F4629          <1>
   360 0000C86C 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 0000C86F 52656164696E672E2E- <1> 		db "Reading... ", 0
   365 0000C878 2E2000              <1>
   366                              <1> msg_writing:
   367 0000C87B 57726974696E672E2E- <1> 		db "Writing... ", 0
   367 0000C884 2E2000              <1>
   368                              <1> percentagestr:
   369 0000C887 2020202500          <1> 		db "   %", 0  ; "  0%" .. "100%"
   370                              <1> ; 11/04/2016
   371                              <1> Msg_No_Set_Space:
   372 0000C88C 496E73756666696369- <1>                 db "Insufficient environment space!"
   372 0000C895 656E7420656E766972- <1>
   372 0000C89E 6F6E6D656E74207370- <1>
   372 0000C8A7 61636521            <1>
   373 0000C8AB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   374                              <1> ; 18/04/2016
   375                              <1> isc_msg:	
   376 0000C8AE 0D0A                <1> 		db 0Dh, 0Ah
   377 0000C8B0 494E56414C49442053- <1> 		db "INVALID SYSTEM CALL", 0
   377 0000C8B9 595354454D2043414C- <1>
   377 0000C8C2 4C00                <1>
   378                              <1> usi_msg:
   379 0000C8C4 0D0A                <1> 		db 0Dh, 0Ah
   380 0000C8C6 554E444546494E4544- <1> 		db "UNDEFINED SOFTWARE INTERRUPT", 0
   380 0000C8CF 20534F465457415245- <1>
   380 0000C8D8 20494E544552525550- <1>
   380 0000C8E1 5400                <1>
   381                              <1> ifc_msg:
   382 0000C8E3 0D0A                <1> 		db 0Dh, 0Ah
   383 0000C8E5 494E56414C49442046- <1> 		db "INVALID FUNCTION CALL"
   383 0000C8EE 554E4354494F4E2043- <1>
   383 0000C8F7 414C4C              <1>
   384                              <1> inv_msg_for_trdos_v2:
   385 0000C8FA 20                  <1> 		db 20h
   386 0000C8FB 666F72205452444F53- <1> 		db "for TRDOS v2!"
   386 0000C904 20763221            <1>
   387 0000C908 07                  <1> 		db 07h
   388 0000C909 0D0A                <1> 		db 0Dh, 0Ah
   389 0000C90B 0D0A                <1> 		db 0Dh, 0Ah
   390 0000C90D 494E5420            <1> 		db "INT "
   391 0000C911 303068              <1> int_num_str:	db "00h"
   392 0000C914 0D0A                <1> 		db 0Dh, 0Ah
   393 0000C916 454158203A20        <1> 		db "EAX : "
   394 0000C91C 303030303030303068- <1> eax_str:	db "00000000h", 0Dh, 0Ah
   394 0000C925 0D0A                <1>
   395 0000C927 454950203A20        <1> 		db "EIP : "
   396 0000C92D 303030303030303068- <1> eip_str:	db "00000000h", 0Dh, 0Ah, 0
   396 0000C936 0D0A00              <1>
   397                              <1> 		
  1912                                  
  1913                                  ; 15/04/2016
  1914                                  ; TRDOS 386 (TRDOS v2.0)
  1915                                  
  1916                                  ; 29/04/2016
  1917                                  int30h:
  1918                                  trdos_isc_routine:
  1919                                  	; 02/05/2016
  1920                                  	; 01/05/2016
  1921                                  	; 29/04/2016
  1922                                  	; 18/04/2016
  1923                                  	; 15/04/2016 (TRDOS 386 = TRDOS v2.0)
  1924                                  	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
  1925                                  	; 03/02/2011 ('trdos_ifc_routine')
  1926                                  	;
  1927 0000C939 8B1C24                  	mov	ebx, [esp] ; EIP (next)
  1928 0000C93C 83EB02                  	sub	ebx, 2 ; EIP (CD ##h)
  1929                                  
  1930 0000C93F 89C1                    	mov	ecx, eax
  1931 0000C941 8A4301                  	mov	al, [ebx+1] ; CDh ##h
  1932                                  
  1933 0000C944 66BA1000                	mov	dx, KDATA
  1934 0000C948 8EDA                    	mov	ds, dx
  1935 0000C94A 8EC2                    	mov	es, dx
  1936                                  
  1937 0000C94C FC                      	cld
  1938 0000C94D 8B15[B8D20000]          	mov	edx, [k_page_dir]
  1939 0000C953 0F22DA                  	mov	cr3, edx
  1940                                  
  1941 0000C956 E88D4FFFFF              	call	bytetohex
  1942 0000C95B 66A3[11C90000]          	mov	[int_num_str], ax
  1943                                  
  1944 0000C961 89D8                    	mov	eax, ebx ; EIP
  1945 0000C963 E8C04FFFFF              	call	dwordtohex
  1946 0000C968 8915[2DC90000]          	mov	[eip_str], edx
  1947 0000C96E A3[31C90000]            	mov	[eip_str+4], eax
  1948                                  
  1949 0000C973 89C8                    	mov	eax, ecx
  1950 0000C975 E8AE4FFFFF              	call	dwordtohex
  1951 0000C97A 8915[1CC90000]          	mov	[eax_str], edx
  1952 0000C980 A3[20C90000]            	mov	[eax_str+4], eax 	
  1953                                  
  1954 0000C985 43                      	inc	ebx
  1955 0000C986 8A03                    	mov	al, [ebx] ; Interrupt number
  1956                                  
  1957                                  trdos_isc_handler:
  1958 0000C988 80FE30                  	cmp	dh, 30h ; Retro UNIX, SINGLIX System calls
  1959 0000C98B 7507                    	jne	short trdos_usi_handler
  1960 0000C98D BE[AEC80000]            	mov	esi, isc_msg
  1961 0000C992 EB05                    	jmp	short loc_write_inv_system_call_msg
  1962                                  
  1963                                  trdos_usi_handler:
  1964 0000C994 BE[C4C80000]            	mov	esi, usi_msg
  1965                                  
  1966                                  loc_write_inv_system_call_msg:
  1967 0000C999 E89276FFFF              	call	print_msg
  1968                                  	; 29/04/2016
  1969 0000C99E BE[FAC80000]            	mov	esi, inv_msg_for_trdos_v2
  1970 0000C9A3 E88876FFFF              	call	print_msg
  1971                                  
  1972                                  loc_ifc_terminate_process:
  1973                                  	; u.uno = process number
  1974                                  	; 29/04/2016
  1975                                  
  1976                                  	; 02/05/2016
  1977 0000C9A8 FE05[75E30000]          	inc	byte [sysflg] ; 0FFh -> 0
  1978                                  
  1979 0000C9AE B801000000              	mov	eax, 1
  1980 0000C9B3 E954D8FFFF              	jmp	sysexit
  1981                                  
  1982                                  ; 07/03/2015
  1983                                  ; Temporary Code
  1984                                  display_disks:
  1985 0000C9B8 803D[C0CD0000]00        	cmp 	byte [fd0_type], 0
  1986 0000C9BF 7605                    	jna 	short ddsks1
  1987 0000C9C1 E87D000000              	call	pdskm
  1988                                  ddsks1:
  1989 0000C9C6 803D[C1CD0000]00        	cmp	byte [fd1_type], 0
  1990 0000C9CD 760C                    	jna	short ddsks2
  1991 0000C9CF C605[41CF0000]31        	mov	byte [dskx], '1'
  1992 0000C9D6 E868000000              	call	pdskm
  1993                                  ddsks2:
  1994 0000C9DB 803D[C2CD0000]00        	cmp	byte [hd0_type], 0
  1995 0000C9E2 7654                    	jna	short ddsk6
  1996 0000C9E4 66C705[3FCF0000]68-     	mov	word [dsktype], 'hd'
  1996 0000C9EC 64                 
  1997 0000C9ED C605[41CF0000]30        	mov	byte [dskx], '0'
  1998 0000C9F4 E84A000000              	call	pdskm
  1999                                  ddsks3:
  2000 0000C9F9 803D[C3CD0000]00        	cmp	byte [hd1_type], 0
  2001 0000CA00 7636                    	jna	short ddsk6
  2002 0000CA02 C605[41CF0000]31        	mov	byte [dskx], '1'
  2003 0000CA09 E835000000              	call	pdskm
  2004                                  ddsks4:
  2005 0000CA0E 803D[C4CD0000]00        	cmp	byte [hd2_type], 0
  2006 0000CA15 7621                    	jna	short ddsk6
  2007 0000CA17 C605[41CF0000]32        	mov	byte [dskx], '2'
  2008 0000CA1E E820000000              	call	pdskm
  2009                                  ddsks5:
  2010 0000CA23 803D[C5CD0000]00        	cmp	byte [hd3_type], 0
  2011 0000CA2A 760C                    	jna	short ddsk6
  2012 0000CA2C C605[41CF0000]33        	mov	byte [dskx], '3'
  2013 0000CA33 E80B000000              	call	pdskm
  2014                                  ddsk6:
  2015 0000CA38 BE[52CF0000]            	mov	esi, nextline
  2016 0000CA3D E806000000              	call	pdskml
  2017                                  pdskm_ok:
  2018 0000CA42 C3                      	retn
  2019                                  pdskm:
  2020 0000CA43 BE[3DCF0000]            	mov	esi, dsk_ready_msg
  2021                                  pdskml:	
  2022 0000CA48 AC                      	lodsb
  2023 0000CA49 08C0                    	or	al, al
  2024 0000CA4B 74F5                    	jz	short pdskm_ok
  2025 0000CA4D 56                      	push	esi
  2026                                  	; 13/05/2016
  2027 0000CA4E BB07000000                      mov     ebx, 7  ; Black background, 
  2028                                  			; light gray forecolor
  2029                                  			; Video page 0 (bh=0)
  2030 0000CA53 E8AA4CFFFF              	call	_write_tty
  2031 0000CA58 5E                      	pop	esi
  2032 0000CA59 EBED                    	jmp	short pdskml
  2033                                  
  2034 0000CA5B 90<rept>                align 16
  2035                                  
  2036                                  gdt:	; Global Descriptor Table
  2037                                  	; (30/07/2015, conforming cs)
  2038                                  	; (26/03/2015)
  2039                                  	; (24/03/2015, tss)
  2040                                  	; (19/03/2015)
  2041                                  	; (29/12/2013)
  2042                                  	;
  2043 0000CA60 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  2044                                  	; 18/08/2014
  2045                                  			; 8h kernel code segment, base = 00000000h		
  2046 0000CA68 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2047                                  			; 10h kernel data segment, base = 00000000h	
  2048 0000CA70 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2049                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2050 0000CA78 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  2051                                  			; 23h user data segment, base address = 400000h ; CORE
  2052 0000CA80 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2053                                  			; Task State Segment
  2054 0000CA88 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2055                                  			       ;  no IO permission in ring 3)
  2056                                  gdt_tss0:
  2057 0000CA8A 0000                    	dw 0  ; TSS base address, bits 0-15 
  2058                                  gdt_tss1:
  2059 0000CA8C 00                      	db 0  ; TSS base address, bits 16-23 
  2060                                  	      		; 49h	
  2061 0000CA8D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2062 0000CA8E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2063                                  gdt_tss2:
  2064 0000CA8F 00                      	db 0  ; TSS base address, bits 24-31 
  2065                                  
  2066                                  gdt_end:
  2067                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2068                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2069                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2070                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2071                                  
  2072                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2073                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2074                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2075                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2076                                  		; W= Writeable, A= Accessed
  2077                                  	
  2078                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2079                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2080                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2081                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2082                                  
  2083                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2084                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2085                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2086                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2087                                  	
  2088                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2089                                  
  2090                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2091                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2092                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2093                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2094                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2095                                  		; AVL= Available to programmers	
  2096                                  
  2097                                  gdtd:
  2098 0000CA90 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2099 0000CA92 [60CA0000]                      dd gdt			; Address of the GDT
  2100                                  
  2101                                  	; 20/08/2014
  2102                                  idtd:
  2103 0000CA96 7F02                            dw idt_end - idt - 1    ; Limit (size)
  2104 0000CA98 [D0CF0000]                      dd idt			; Address of the IDT
  2105                                  
  2106                                  Align 4
  2107                                  	; 15/04/2016
  2108                                  	; TRDOS 386 (TRDOS v2.0)
  2109                                  
  2110                                  	; 21/08/2014
  2111                                  ilist:
  2112                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  2113                                  	;
  2114                                  	; Exception list
  2115                                  	; 25/08/2014	
  2116 0000CA9C [35080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2117 0000CAA0 [3C080000]              	dd	exc1	
  2118 0000CAA4 [43080000]              	dd 	exc2	
  2119 0000CAA8 [4A080000]              	dd	exc3	
  2120 0000CAAC [4E080000]              	dd	exc4	
  2121 0000CAB0 [52080000]              	dd	exc5	
  2122 0000CAB4 [56080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2123 0000CAB8 [5A080000]              	dd	exc7	
  2124 0000CABC [5E080000]              	dd	exc8	
  2125 0000CAC0 [62080000]              	dd	exc9	
  2126 0000CAC4 [66080000]              	dd 	exc10	
  2127 0000CAC8 [6A080000]              	dd	exc11
  2128 0000CACC [6E080000]              	dd	exc12
  2129 0000CAD0 [72080000]              	dd	exc13	; 0Dh, General Protection Fault
  2130 0000CAD4 [76080000]              	dd 	exc14	; 0Eh, Page Fault
  2131 0000CAD8 [7A080000]              	dd	exc15
  2132 0000CADC [7E080000]              	dd	exc16
  2133 0000CAE0 [82080000]              	dd	exc17
  2134 0000CAE4 [86080000]              	dd 	exc18
  2135 0000CAE8 [8A080000]              	dd	exc19
  2136 0000CAEC [8E080000]              	dd 	exc20
  2137 0000CAF0 [92080000]              	dd	exc21
  2138 0000CAF4 [96080000]              	dd	exc22
  2139 0000CAF8 [9A080000]              	dd	exc23
  2140 0000CAFC [9E080000]              	dd 	exc24
  2141 0000CB00 [A2080000]              	dd	exc25
  2142 0000CB04 [A6080000]              	dd	exc26
  2143 0000CB08 [AA080000]              	dd	exc27
  2144 0000CB0C [AE080000]              	dd 	exc28
  2145 0000CB10 [B2080000]              	dd	exc29
  2146 0000CB14 [B6080000]              	dd 	exc30
  2147 0000CB18 [BA080000]              	dd	exc31
  2148                                  	; Interrupt list
  2149 0000CB1C [2A060000]              	dd	timer_int	; INT 20h
  2150                                  		;dd	irq0	
  2151 0000CB20 [960C0000]              	dd	kb_int		; 24/01/2016
  2152                                  		;dd	irq1
  2153 0000CB24 [8B070000]              	dd	irq2
  2154                                  		; COM2 int
  2155 0000CB28 [8F070000]              	dd	irq3
  2156                                  		; COM1 int
  2157 0000CB2C [9A070000]              	dd	irq4
  2158 0000CB30 [A5070000]              	dd	irq5
  2159                                  ;DISKETTE_INT: ;06/02/2015
  2160 0000CB34 [CF270000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  2161                                  		;dd	irq6
  2162                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2163                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2164 0000CB38 [960A0000]              	dd	default_irq7	; 25/02/2015
  2165                                  		;dd	irq7
  2166                                  ; Real Time Clock Interrupt
  2167 0000CB3C [07070000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2168                                  		;dd	irq8	; INT 28h
  2169 0000CB40 [B5070000]              	dd	irq9
  2170 0000CB44 [B9070000]              	dd	irq10
  2171 0000CB48 [BD070000]              	dd	irq11
  2172 0000CB4C [C1070000]              	dd	irq12
  2173 0000CB50 [C5070000]              	dd	irq13
  2174                                  ;HDISK_INT1:  ;06/02/2015 	
  2175 0000CB54 [49310000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2176                                  		;dd	irq14
  2177                                  ;HDISK_INT2:  ;06/02/2015
  2178 0000CB58 [70310000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  2179                                  		;dd	irq15	; INT 2Fh
  2180                                  		; 14/08/2015
  2181                                  	;dd	sysent		; INT 30h (system calls)
  2182                                  
  2183                                  	; 15/04/2016
  2184                                  	; TRDOS 386(TRDOS v2.0) Software Interrupts
  2185                                  
  2186 0000CB5C [39C90000]              	dd	int30h		; Reserved for
  2187                                  				; !!! Retro UNIX (RUNIX) !!!
  2188                                  				; !!! SINGLIX !!! System Calls
  2189 0000CB60 [89130000]              	dd	int31h		; Video BIOS (IBM PC/AT, Int 10h)
  2190 0000CB64 [BE0A0000]              	dd	int32h		; Keyboard Functions (IBM PC/AT, Int 16h)
  2191 0000CB68 [86280000]              	dd	int33h		; DISK I/O (IBM PC/AT, Int 13h)
  2192 0000CB6C [D9BF0000]              	dd	int34h		; #IOCTL# (I/O port access support for ring 3)
  2193 0000CB70 [7A3C0000]              	dd	int35h		; Time/Date Functions (IBM PC/AT, Int 1Ah)
  2194 0000CB74 [8B090000]              	dd	ignore_int	; INT 36h : Timer Functions	
  2195 0000CB78 [8B090000]              	dd	ignore_int	; INT 37h	
  2196 0000CB7C [8B090000]              	dd	ignore_int	; INT 38h
  2197 0000CB80 [8B090000]              	dd	ignore_int	; INT 39h
  2198 0000CB84 [8B090000]              	dd	ignore_int	; INT 3Ah	
  2199 0000CB88 [8B090000]              	dd	ignore_int	; INT 3Bh
  2200 0000CB8C [8B090000]              	dd	ignore_int	; INT 3Ch
  2201 0000CB90 [8B090000]              	dd	ignore_int	; INT 3Dh	
  2202 0000CB94 [8B090000]              	dd	ignore_int	; INT 3Eh
  2203 0000CB98 [8B090000]              	dd	ignore_int	; INT 3Fh
  2204 0000CB9C [FB9F0000]              	dd	sysent		; INT 40h : !!! TRDOS 386 System Calls !!!
  2205                                  	;dd	ignore_int
  2206 0000CBA0 00000000                	dd	0
  2207                                  ;;;
  2208                                  ;;; 11/03/2015
  2209                                  %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 0000CBA4 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000CBA9 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 0000CBAE 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 0000CBB4 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000CBBA 202122232425        <1> 	db	32,33,34,35,36,37
    41 0000CBC0 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000CBC6 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000CBC8 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000CBC9 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 0000CBCE 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 0000CBD0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 0000CBD1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000CBD6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000CBD8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 0000CBDE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 0000CBE4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000CBEA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 0000CBF0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000CBF6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 0000CBFC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 0000CC02 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000CC08 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 0000CC0E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 0000CC12 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000CC18 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 0000CC1E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 0000CC24 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 0000CC2A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 0000CC30 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 0000CC39 39302D3D0809        <1>
    76 0000CC3F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 0000CC48 705B5D0DFF61736466- <1>
    76 0000CC51 67686A6B6C3B27      <1>
    77 0000CC58 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 0000CC61 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 0000CC6A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 0000CC6F 4041424344          <1> 	db	64,65,66,67,68
    81 0000CC74 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 0000CC76 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 0000CC7C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 0000CC83 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000CC88 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 0000CC91 28295F2B0800        <1>
    90 0000CC97 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 0000CCA0 507B7D0DFF41534446- <1>
    90 0000CCA9 47484A4B4C3A22      <1>
    91 0000CCB0 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000CCB9 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 0000CCC2 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000CCC7 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 0000CCCC FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 0000CCCE 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000CCD7 3233302E            <1>
    99                              <1> 	;
   100 0000CCDB 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 0000CCE0 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 0000CCE1 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 0000CCE2 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 0000CCE3 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 0000CCE4 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 0000CCE5 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000CCE6 [F6CC0000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000CCEA [16CD0000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 0000CCEE [F6CC0000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 0000CCF2 [F6CC0000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000CCF6 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
   128                              <1> 
   129                              <1> ; /// End Of KEYBOARD DATA ///
  2210                                  %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: 17/06/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 0000CD16 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
    37 0000CD17 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 0000CD18 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
    63                              <1> 	;db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
    64 0000CD1F 1C020F0D0E          <1> 	db	1Ch,2,15,13,14  ; 17/06/2016 - TRDOS 386 (TRDOS v2.0)
    65 0000CD24 00000000            <1> 	db	0,0,0,0
    66                              <1> 
    67                              <1> ; 16/01/2016
    68                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
    69 0000CD28 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    70                              <1> ; 30/01/2016
    71                              <1> vmode:
    72 0000CD30 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    73                              <1> 
    74                              <1> CURSOR_MODE: ; cursor start (ch) = 13, cursor end (cl) = 15
    75 0000CD38 0E0D                <1> 	db	14, 13 ; 17/06/2016 - TRDOS 386 (TRDOS v2.0)
    76                              <1> 
    77                              <1> ; /// End Of VIDEO DATA ///
  2211                                  %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 0000CD3A [9DCD0000]          <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 0000CD3E 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 0000CD3F [5CCD0000]          <1> 		dd	MD_TBL1
   115 0000CD43 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000CD44 [69CD0000]          <1>                 dd      MD_TBL2
   118 0000CD48 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 0000CD49 [76CD0000]          <1> 		dd      MD_TBL3
   121 0000CD4D 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 0000CD4E [83CD0000]          <1> 		dd      MD_TBL4
   124 0000CD52 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000CD53 [90CD0000]          <1> 		dd      MD_TBL5
   127 0000CD57 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 0000CD58 [9DCD0000]          <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 0000CD5C DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 0000CD5D 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 0000CD5E 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 0000CD5F 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000CD60 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000CD61 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000CD62 FF                  <1> 	DB	0FFH		; DTL
   147 0000CD63 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000CD64 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000CD65 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 0000CD66 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 0000CD67 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 0000CD68 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 0000CD69 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 0000CD6A 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 0000CD6B 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 0000CD6C 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 0000CD6D 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 0000CD6E 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 0000CD6F FF                  <1> 	DB	0FFH		; DTL
   164 0000CD70 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000CD71 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000CD72 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000CD73 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000CD74 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000CD75 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 0000CD76 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 0000CD77 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 0000CD78 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 0000CD79 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 0000CD7A 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 0000CD7B 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 0000CD7C FF                  <1> 	DB	0FFH		; DTL
   181 0000CD7D 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 0000CD7E F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 0000CD7F 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000CD80 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000CD81 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000CD82 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 0000CD83 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000CD84 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000CD85 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 0000CD86 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 0000CD87 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 0000CD88 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 0000CD89 FF                  <1> 	DB	0FFH		; DTL
   198 0000CD8A 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 0000CD8B F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 0000CD8C 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 0000CD8D 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 0000CD8E 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 0000CD8F 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 0000CD90 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000CD91 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000CD92 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000CD93 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000CD94 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000CD95 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 0000CD96 FF                  <1> 	DB	0FFH		; DTL
   215 0000CD97 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 0000CD98 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 0000CD99 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 0000CD9A 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 0000CD9B 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 0000CD9C 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 0000CD9D AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 0000CD9E 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 0000CD9F 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 0000CDA0 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 0000CDA1 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 0000CDA2 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 0000CDA3 FF                  <1> 	DB	0FFH		; DTL
   232 0000CDA4 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 0000CDA5 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 0000CDA6 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 0000CDA7 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 0000CDA8 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 0000CDA9 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 0000CDAA E0                  <1> 	db	NO_ERR
   280 0000CDAB 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 0000CDAF 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 0000CDB3 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 0000CDB4 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 0000CDB5 90                  <1> align 2
   293                              <1> 
   294 0000CDB6 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 0000CDB8 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 0000CDBA 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2212                                  ;;;
  2213                                  
  2214 0000CDBB 90                      Align 2
  2215                                  
  2216                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2217 0000CDBC 00                      boot_drv:    db 0 ; boot drive number (physical)
  2218                                  ; 24/11/2014
  2219 0000CDBD 00                      drv:	     db 0 
  2220 0000CDBE 00                      last_drv:    db 0 ; last hdd
  2221 0000CDBF 00                      hdc:         db 0  ; number of hard disk drives
  2222                                  		     ; (present/detected)
  2223                                  ;
  2224                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2225                                  ; Physical drive type & flags
  2226 0000CDC0 00                      fd0_type:    db 0  ; floppy drive type
  2227 0000CDC1 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2228                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2229                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2230                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2231                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2232 0000CDC2 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  2233 0000CDC3 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  2234 0000CDC4 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  2235 0000CDC5 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
  2236                                  		     ; bit 0 - Fixed disk access subset supported
  2237                                  		     ; bit 1 - Drive locking and ejecting
  2238                                  		     ; bit 2 - Enhanced disk drive support
  2239                                  		     ; bit 3 = Reserved (64 bit EDD support)
  2240                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  2241                                  		     ; will interpret it as 'LBA ready'!)		
  2242                                  
  2243                                  ; 11/03/2015 - 10/07/2015
  2244 0000CDC6 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  2244 0000CDCF 0000000000         
  2245 0000CDD4 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  2245 0000CDDD 0000000000         
  2246 0000CDE2 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  2246 0000CDEB 0000000000         
  2247 0000CDF0 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2247 0000CDF9 000000000000000000-
  2247 0000CE02 000000000000000000-
  2247 0000CE0B 00                 
  2248 0000CE0C 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2249 0000CE13 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
  2250                                  ;
  2251                                  
  2252                                  ; 27/08/2014
  2253                                  scr_row:
  2254 0000CE1A E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2255                                  scr_col:
  2256 0000CE1E 00000000                	dd 0
  2257                                  
  2258                                  ; 20/08/2014
  2259                                    ; /* This is the default interrupt "handler" :-) */ 
  2260                                    ; Linux v0.12 (head.s)
  2261                                  int_msg:
  2262 0000CE22 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2262 0000CE2B 6E7465727275707420-
  2262 0000CE34 212000             
  2263                                  
  2264 0000CE37 90                      Align 2
  2265                                  	; 21/08/2014
  2266                                  exc_msg:
  2267 0000CE38 435055206578636570-     	db "CPU exception ! "
  2267 0000CE41 74696F6E202120     
  2268                                  excnstr: 		; 25/08/2014
  2269 0000CE48 3F3F68202045495020-     	db "??h", "  EIP : "
  2269 0000CE51 3A20               
  2270                                  EIPstr: ; 29/08/2014
  2271 0000CE53 00<rept>                	times 12 db 0
  2272                                  
  2273                                  	; 23/02/2015
  2274                                  	; 25/08/2014
  2275                                  ;scounter:
  2276                                  ;	db 5
  2277                                  ;	db 19
  2278                                  
  2279                                  ; 05/11/2014
  2280                                  msg_out_of_memory:
  2281 0000CE5F 070D0A                  	db 	07h, 0Dh, 0Ah
  2282 0000CE62 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2282 0000CE6B 656E74206D656D6F72-
  2282 0000CE74 79202120284D696E69-
  2282 0000CE7D 6D756D2032204D4220-
  2282 0000CE86 6D656D6F7279206973-
  2282 0000CE8F 206E65656465642E29 
  2283 0000CE98 0D0A00                   	db	0Dh, 0Ah, 0
  2284                                  	;
  2285                                  setup_error_msg:
  2286 0000CE9B 0D0A                    	db 0Dh, 0Ah
  2287 0000CE9D 4469736B2053657475-     	db 'Disk Setup Error!' 
  2287 0000CEA6 70204572726F7221   
  2288 0000CEAE 0D0A00                  	db 0Dh, 0Ah,0
  2289                                  
  2290                                  ; 06/11/2014
  2291                                  ; Memory Information message
  2292                                  ; 14/08/2015
  2293                                  msg_memory_info:
  2294 0000CEB1 07                      	db	07h
  2295 0000CEB2 0D0A                    	db	0Dh, 0Ah
  2296                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2297 0000CEB4 546F74616C206D656D-     	db	"Total memory : "
  2297 0000CEBD 6F7279203A20       
  2298                                  mem_total_b_str: ; 10 digits
  2299 0000CEC3 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2299 0000CECC 302062797465730D0A 
  2300 0000CED5 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2300 0000CEDE 202020202020202020 
  2301                                  mem_total_p_str: ; 7 digits
  2302 0000CEE7 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2302 0000CEF0 616765730D0A       
  2303 0000CEF6 0D0A                    	db 	0Dh, 0Ah
  2304 0000CEF8 46726565206D656D6F-     	db	"Free memory  : "
  2304 0000CF01 727920203A20       
  2305                                  free_mem_b_str:  ; 10 digits
  2306 0000CF07 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2306 0000CF10 3F2062797465730D0A 
  2307 0000CF19 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2307 0000CF22 202020202020202020 
  2308                                  free_mem_p_str:  ; 7 digits
  2309 0000CF2B 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2309 0000CF34 616765730D0A       
  2310 0000CF3A 0D0A00                  	db	0Dh, 0Ah, 0
  2311                                  
  2312                                  dsk_ready_msg:
  2313 0000CF3D 0D0A                    	db 	0Dh, 0Ah
  2314                                  dsktype:
  2315 0000CF3F 6664                    	db	'fd'
  2316                                  dskx:
  2317 0000CF41 30                      	db	'0'
  2318 0000CF42 20                      	db	20h
  2319 0000CF43 697320524541445920-     	db 	'is READY ...'
  2319 0000CF4C 2E2E2E             
  2320 0000CF4F 00                      	db 	0
  2321                                  
  2322                                  next2line: ; 08/02/2016
  2323 0000CF50 0D0A                    	db	0Dh, 0Ah
  2324                                  nextline:
  2325 0000CF52 0D0A00                  	db 	0Dh, 0Ah, 0
  2326                                  
  2327                                  ; KERNEL - SYSINIT Messages
  2328                                  ; 24/08/2015
  2329                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  2330                                  ; 14/07/2013
  2331                                  ;kernel_init_err_msg:
  2332                                  ;	db 0Dh, 0Ah
  2333                                  ;	db 07h
  2334                                  ;	db 'Kernel initialization ERROR !'
  2335                                  ;	db 0Dh, 0Ah, 0 
  2336                                  
  2337                                  ;welcome_msg: 
  2338                                  ;	db 0Dh, 0Ah
  2339                                  ;	db 07h
  2340                                  ;	db 'Welcome to TRDOS 386 Operating System !'
  2341                                  ;	db 0Dh, 0Ah
  2342                                  ;	db 'by Erdogan Tan - 20/06/2016 (v2.0.0)'
  2343                                  ;	db 0Dh, 0Ah, 0
  2344                                  
  2345                                  panic_msg:
  2346 0000CF55 0D0A07                  	db 0Dh, 0Ah, 07h
  2347 0000CF58 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2347 0000CF61 726E656C2050616E69-
  2347 0000CF6A 632021             
  2348 0000CF6D 0D0A00                  	db 0Dh, 0Ah, 0
  2349                                  
  2350                                  align 2
  2351                                  
  2352                                  ; EPOCH Variables
  2353                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  2354                                  ; 09/04/2013 epoch variables
  2355                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  2356                                  ;
  2357 0000CF70 B207                    year: 	dw 1970
  2358 0000CF72 0100                    month: 	dw 1
  2359 0000CF74 0100                    day: 	dw 1
  2360 0000CF76 0000                    hour: 	dw 0
  2361 0000CF78 0000                    minute: dw 0
  2362 0000CF7A 0000                    second: dw 0
  2363                                  
  2364                                  DMonth:
  2365 0000CF7C 0000                    	dw 0
  2366 0000CF7E 1F00                    	dw 31
  2367 0000CF80 3B00                    	dw 59
  2368 0000CF82 5A00                    	dw 90
  2369 0000CF84 7800                    	dw 120
  2370 0000CF86 9700                    	dw 151
  2371 0000CF88 B500                    	dw 181
  2372 0000CF8A D400                    	dw 212
  2373 0000CF8C F300                    	dw 243
  2374 0000CF8E 1101                    	dw 273
  2375 0000CF90 3001                    	dw 304
  2376 0000CF92 4E01                    	dw 334
  2377                                  
  2378                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2379 0000CF94 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2380                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2381 0000CF96 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2382                                  		   ; between 16 MB and 4 GB.
  2383                                  
  2384                                  starting_msg:
  2385 0000CF98 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [20/06/2016] ...", 0
  2385 0000CFA1 6174696F6E616C2044-
  2385 0000CFAA 4F532076322E30205B-
  2385 0000CFB3 32302F30362F323031-
  2385 0000CFBC 365D202E2E2E00     
  2386                                  NextLine:
  2387 0000CFC3 0D0A00                  	db 0Dh, 0Ah, 0
  2388                                  
  2389                                  ;msgl_drv_not_ready: 
  2390                                  ;	db 07h, 0Dh, 0Ah
  2391                                  ;       db 'Drive not ready or read error !'
  2392                                  ;       db 0Dh, 0Ah, 0
  2393                                  
  2394 0000CFC6 90<rept>                align 16
  2395                                  
  2396                                  bss_start:
  2397                                  
  2398                                  ABSOLUTE bss_start
  2399                                  
  2400                                  	; 15/04/2016
  2401                                  	; TRDOS 386 (TRDOS v2.0)
  2402                                  	; 	80 interrupts 	
  2403                                  	; 11/03/2015
  2404                                  	; Interrupt Descriptor Table (20/08/2014)
  2405                                  idt:
  2406                                  	;resb	64*8 ; INT 0 to INT 3Fh
  2407                                  	; 15/04/2016
  2408 0000CFD0 <res 00000280>          	resb	80*8 ; INT 0 to INT 4Fh
  2409                                  
  2410                                  idt_end:
  2411                                  
  2412                                  ;alignb 4
  2413                                  
  2414                                  task_state_segment:
  2415                                  	; 24/03/2015
  2416 0000D250 <res 00000002>          tss.link:   resw 1
  2417 0000D252 <res 00000002>          	    resw 1
  2418                                  ; tss offset 4	
  2419 0000D254 <res 00000004>          tss.esp0:   resd 1
  2420 0000D258 <res 00000002>          tss.ss0:    resw 1
  2421 0000D25A <res 00000002>          	    resw 1	
  2422 0000D25C <res 00000004>          tss.esp1:   resd 1
  2423 0000D260 <res 00000002>          tss.ss1:    resw 1
  2424 0000D262 <res 00000002>          	    resw 1 	
  2425 0000D264 <res 00000004>          tss.esp2:   resd 1
  2426 0000D268 <res 00000002>          tss.ss2:    resw 1
  2427 0000D26A <res 00000002>          	    resw 1
  2428                                  ; tss offset 28
  2429 0000D26C <res 00000004>          tss.CR3:    resd 1
  2430 0000D270 <res 00000004>          tss.eip:    resd 1
  2431 0000D274 <res 00000004>          tss.eflags: resd 1
  2432                                  ; tss offset 40
  2433 0000D278 <res 00000004>          tss.eax:    resd 1		 		
  2434 0000D27C <res 00000004>          tss.ecx:    resd 1
  2435 0000D280 <res 00000004>          tss.edx:    resd 1
  2436 0000D284 <res 00000004>          tss.ebx:    resd 1
  2437 0000D288 <res 00000004>          tss.esp:    resd 1
  2438 0000D28C <res 00000004>          tss.ebp:    resd 1
  2439 0000D290 <res 00000004>          tss.esi:    resd 1
  2440 0000D294 <res 00000004>          tss.edi:    resd 1
  2441                                  ; tss offset 72
  2442 0000D298 <res 00000002>          tss.ES:     resw 1
  2443 0000D29A <res 00000002>          	    resw 1	
  2444 0000D29C <res 00000002>          tss.CS:	    resw 1
  2445 0000D29E <res 00000002>          	    resw 1
  2446 0000D2A0 <res 00000002>          tss.SS:	    resw 1
  2447 0000D2A2 <res 00000002>          	    resw 1
  2448 0000D2A4 <res 00000002>          tss.DS:	    resw 1
  2449 0000D2A6 <res 00000002>          	    resw 1
  2450 0000D2A8 <res 00000002>          tss.FS:	    resw 1
  2451 0000D2AA <res 00000002>          	    resw 1
  2452 0000D2AC <res 00000002>          tss.GS:	    resw 1
  2453 0000D2AE <res 00000002>          	    resw 1		
  2454 0000D2B0 <res 00000002>          tss.LDTR:   resw 1
  2455 0000D2B2 <res 00000002>          	    resw 1
  2456                                  ; tss offset 100		
  2457 0000D2B4 <res 00000002>          	    resw 1		
  2458 0000D2B6 <res 00000002>          tss.IOPB:   resw 1
  2459                                  ; tss offset 104 
  2460                                  tss_end:
  2461                                  
  2462 0000D2B8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2463                                  		    ; (Physical address = Virtual address)	 	
  2464 0000D2BC <res 00000004>          memory_size: resd 1 ; memory size in pages
  2465 0000D2C0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  2466 0000D2C4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  2467                                  		    ; first free page search
  2468 0000D2C8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
  2469                                  		    ; next free page search will be
  2470                                  		    ; stopped after it. (end of M.A.T.)
  2471 0000D2CC <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
  2472                                  		    ; first free page search
  2473                                  		    ; will be started on it. (for user)
  2474 0000D2D0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
  2475                                  
  2476                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2477                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  2478 0000D2D4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  2479                                  			  ; NOTE: active page only	
  2480 0000D2D6 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  2481                                  ACTIVE_PAGE: 
  2482 0000D2E6 <res 00000001>          ptty: 	     resb 1 ; current tty
  2483                                  ; 01/07/2015 - 29/01/2016
  2484 0000D2E7 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  2485                                  ; 26/10/2015
  2486                                  ; 07/09/2014
  2487 0000D2E8 <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  2488                                  
  2489                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2490 0000D2FC <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
  2491                                  
  2492                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  2493                                  ; (open mode locks for pseudo TTYs)
  2494                                  ; [ major tty locks (return error in any conflicts) ]
  2495 0000D300 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
  2496                                  
  2497                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2498                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  2499 0000D314 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  2500                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2501                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  2502                                  ;; 0 means serial port is not available 
  2503                                  ;;comprm: ; 25/06/2014
  2504 0000D31E <res 00000001>          com1p:       resb 1  ;;0E3h
  2505 0000D31F <res 00000001>          com2p:       resb 1  ;;0E3h
  2506                                  
  2507                                  ; 17/11/2015
  2508                                  ; request for response (from the terminal)	
  2509 0000D320 <res 00000002>          req_resp:    resw 1 			
  2510                                  ; 07/11/2015
  2511 0000D322 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  2512                                  		    ; (0= COM1, 1= COM2)
  2513                                  ; 09/11/2015
  2514 0000D323 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2515                                  ; 07/11/2015
  2516 0000D324 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2517 0000D326 <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2518                                  
  2519                                  ; 22/08/2014 (RTC)
  2520                                  ; (Packed BCD)
  2521 0000D328 <res 00000001>          time_seconds: resb 1
  2522 0000D329 <res 00000001>          time_minutes: resb 1
  2523 0000D32A <res 00000001>          time_hours:   resb 1
  2524 0000D32B <res 00000001>          date_wday:    resb 1
  2525 0000D32C <res 00000001>          date_day:     resb 1
  2526 0000D32D <res 00000001>          date_month:   resb 1			
  2527 0000D32E <res 00000001>          date_year:    resb 1
  2528 0000D32F <res 00000001>          date_century: resb 1
  2529                                  
  2530                                  ; 24/01/2016
  2531 0000D330 <res 00000004>          RTC_LH:	       resd 1
  2532 0000D334 <res 00000001>          RTC_WAIT_FLAG: resb 1
  2533 0000D335 <res 00000001>          USER_FLAG:     resb 1
  2534                                  ; 19/05/2016
  2535                                  ;RTC_second:
  2536 0000D336 <res 00000001>          RTC_2Hz:       resb 1 ;  from 2Hz interrupt to 1Hz timer event function	
  2537                                  
  2538                                  %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 0000D337 <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 0000D338 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0000D33A <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0000D33C <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 0000D33D <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0000D33E <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0000D33F <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 0000D340 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 0000D341 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 0000D348 <res 00000001>      <1> LASTRATE:	resb 	1
    49 0000D349 <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0000D34A <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0000D34B <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0000D34C <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0000D34D <res 00000004>      <1> DSK_STATE:	resb 	4
    54 0000D351 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 0000D353 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 0000D354 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 0000D355 <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 0000D356 <res 00000002>      <1> alignb 4
    68                              <1> 
    69                              <1> ;HF_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    70                              <1> ;HF1_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    71                              <1> HF_TBL_VEC: ; 22/12/2014	
    72 0000D358 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0000D35C <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 0000D360 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 0000D364 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 0000D368 <res 00000001>      <1> LBAMode:     	resb	1
    79                              <1> 
    80                              <1> ; *****************************************************************************
  2539                                  
  2540                                  ;;; Real Mode Data (10/07/2015 - BSS)
  2541                                  
  2542                                  ;alignb 2
  2543                                  
  2544                                  ; 10/01/2016
  2545                                  %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: 07/06/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 0000D369 <res 00000003>      <1> alignb 4
    20                              <1> 
    21                              <1> ; MAINPROG.ASM
    22 0000D36C <res 00000004>      <1> MainProgCfg_FileSize:   resd 1 ; 14/04/2016
    23 0000D370 <res 00000004>      <1> MainProgCfg_LineOffset: resd 1 ; 14/04/2016
    24                              <1> 
    25 0000D374 <res 00000004>      <1> Current_VolSerial: resd 1
    26                              <1> 
    27 0000D378 <res 00000004>      <1> Current_Dir_FCluster: resd 1
    28                              <1> 
    29 0000D37C <res 00000001>      <1> Current_Dir_Level: resb 1
    30 0000D37D <res 00000001>      <1> Current_FATType: resb 1
    31 0000D37E <res 00000001>      <1> Current_Drv: resb 1
    32 0000D37F <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    33 0000D380 <res 00000001>      <1>                    resb 1 ; ':'
    34 0000D381 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    35 0000D382 <res 0000005A>      <1> Current_Directory: resb 90
    36 0000D3DC <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    37 0000D3DD <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    38                              <1> 
    39 0000D3DE <res 00000001>      <1> CursorColumn: 	resb 1
    40 0000D3DF <res 00000001>      <1> CmdArgStart:    resb 1
    41                              <1> 
    42                              <1> ; 03/02/2016
    43 0000D3E0 <res 0000004E>      <1> Remark:		resb 78
    44                              <1> 
    45 0000D42E <res 00000050>      <1> CommandBuffer: 	resb 80
    46                              <1> 
    47 0000D47E <res 00000100>      <1> TextBuffer:	resb 256
    48                              <1> 
    49                              <1> MasterBootBuff:
    50 0000D57E <res 000001BE>      <1> MasterBootCode: resb 1BEh
    51 0000D73C <res 00000040>      <1> PartitionTable: resb 64
    52 0000D77C <res 00000002>      <1> MBIDCode: resw 1
    53                              <1> 
    54                              <1> PTable_Buffer:
    55 0000D77E <res 00000040>      <1> PTable_hd0: resb 64
    56 0000D7BE <res 00000040>      <1> PTable_hd1: resb 64
    57 0000D7FE <res 00000040>      <1> PTable_hd2: resb 64
    58 0000D83E <res 00000040>      <1> PTable_hd3: resb 64
    59 0000D87E <res 00000040>      <1> PTable_ep0: resb 64
    60 0000D8BE <res 00000040>      <1> PTable_ep1: resb 64
    61 0000D8FE <res 00000040>      <1> PTable_ep2: resb 64
    62 0000D93E <res 00000040>      <1> PTable_ep3: resb 64
    63                              <1> 
    64 0000D97E <res 00000001>      <1> scount:	resb 1 ; 16/05/2016 (diskio.s, 'int33h:')	
    65 0000D97F <res 00000001>      <1> HD_LBA_yes: resb 1
    66 0000D980 <res 00000001>      <1> PP_Counter: resb 1
    67 0000D981 <res 00000001>      <1> EP_Counter: resb 1
    68                              <1> 
    69 0000D982 <res 00000004>      <1> EP_StartSector: resd 1
    70 0000D986 <res 00000004>      <1>                 resd 1
    71 0000D98A <res 00000004>      <1>                 resd 1
    72 0000D98E <res 00000004>      <1>                 resd 1
    73                              <1> 
    74 0000D992 <res 00000200>      <1> DOSBootSectorBuff: resb 512
    75                              <1> 
    76                              <1> FAT_BuffDescriptor:
    77 0000DB92 <res 00000004>      <1> FAT_CurrentCluster: resd 1
    78 0000DB96 <res 00000001>      <1> FAT_BuffValidData: resb 1
    79 0000DB97 <res 00000001>      <1> FAT_BuffDrvName: resb 1
    80 0000DB98 <res 00000002>      <1> FAT_BuffOffset: resw 1
    81 0000DB9A <res 00000004>      <1> FAT_BuffSector: resd 1
    82                              <1> 
    83 0000DB9E <res 00000004>      <1> FAT_ClusterCounter: resd 1
    84 0000DBA2 <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 0000DBA6 <res 00000001>      <1> DirBuff_DRV: resb 1
    92 0000DBA7 <res 00000001>      <1> DirBuff_FATType: resb 1
    93 0000DBA8 <res 00000001>      <1> DirBuff_ValidData: resb 1
    94 0000DBA9 <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
    95 0000DBAB <res 00000002>      <1> DirBuff_LastEntry: resw 1
    96 0000DBAD <res 00000004>      <1> DirBuff_Cluster: resd 1 
    97 0000DBB1 <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 0000DBB3 <res 00000004>      <1> FreeClusterCount: resd 1
   109                              <1> 
   110 0000DBB7 <res 00000004>      <1> VolSize_Unit1:   resd 1
   111 0000DBBB <res 00000004>      <1> VolSize_Unit2:   resd 1
   112                              <1> 
   113 0000DBBF <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   114 0000DBC3 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   115 0000DBCD <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   116 0000DBCE <res 00000001>      <1> resb 1
   117 0000DBCF <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   118 0000DBD3 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   119 0000DBDD <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   120                              <1> 
   121                              <1> ; 10/02/2016
   122 0000DBDE <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   123                              <1> 
   124                              <1> ; 24/01/2016
   125 0000DBDF <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   126                              <1> ; 06/02/2016
   127 0000DC5F <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   128 0000DC63 <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   129 0000DC64 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   130                              <1> ;
   131 0000DC65 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   132 0000DC67 <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   133 0000DC6B <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   134                              <1> ;
   135 0000DC6D <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   136                              <1> 
   137 0000DC6E <res 00000002>      <1> alignb 4
   138                              <1> 
   139                              <1> ; 29/01/2016
   140 0000DC70 <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 0000DC71 <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 0000DC72 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   148 0000DC73 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   149 0000DC74 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   150                              <1> 
   151                              <1> ; 06/02/2016 (long name)
   152 0000DC78 <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   153 0000DC7A <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   154 0000DC7C <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   155                              <1> ;	
   156 0000DC7D <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   157 0000DC7E <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   158 0000DC7F <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   159 0000DC80 <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   160                              <1> 
   161                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   162 0000DD04 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   163 0000DD05 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   164                              <1> 
   165                              <1> ; 07/02/2016
   166 0000DD06 <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   167                              <1> 
   168                              <1> ; 10/02/2016
   169 0000DD13 <res 0000000D>      <1> Dir_Entry_Name:	resb 13 ; DIR.ASM
   170                              <1> 
   171                              <1> alignb 2
   172                              <1> 
   173 0000DD20 <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 0000DD22 <res 00000001>      <1> FindFile_Drv:		  resb 1
   179 0000DD23 <res 00000041>      <1> FindFile_Directory:	  resb 65
   180 0000DD64 <res 0000000D>      <1> FindFile_Name:		  resb 13
   181                              <1> FindFile_LongNameEntryLength:
   182 0000DD71 <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 0000DD72 <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   186 0000DD74 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   187 0000DD94 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   188 0000DD98 <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   189 0000DD9C <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   190 0000DD9E <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   191 0000DDA0 <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   192                              <1> 
   193 0000DDA2 <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   194 0000DDA6 <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   195                              <1> 
   196                              <1> ; 10/02/2016
   197 0000DDAA <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   198 0000DDAC <res 00000002>      <1> Dir_Count:      resw 1
   199 0000DDAE <res 00000004>      <1> Total_FSize:    resd 1
   200 0000DDB2 <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   201 0000DDB6 <res 0000000A>      <1>                 resb 10
   202 0000DDC0 <res 00000001>      <1> TFS_Dec_End:    resb 1
   203                              <1> 
   204 0000DDC1 <res 00000001>      <1> PrintDir_RowCounter: resb 1
   205                              <1> 
   206 0000DDC2 <res 00000002>      <1> alignb 4
   207                              <1> ; 15/02/2015 ('show' command variables)
   208 0000DDC4 <res 00000004>      <1> Show_FDT:	resd 1
   209 0000DDC8 <res 00000004>      <1> Show_LDDDT:	resd 1
   210 0000DDCC <res 00000004>      <1> Show_Cluster:	resd 1
   211 0000DDD0 <res 00000004>      <1> Show_FileSize:	resd 1
   212 0000DDD4 <res 00000004>      <1> Show_FilePointer: resd 1
   213 0000DDD8 <res 00000002>      <1> Show_ClusterPointer: resw 1
   214 0000DDDA <res 00000002>      <1> Show_ClusterSize: resw 1
   215 0000DDDC <res 00000001>      <1> Show_RowCount:	resb 1
   216                              <1> 
   217 0000DDDD <res 00000003>      <1> alignb 4
   218                              <1> ; 21/02/2016
   219 0000DDE0 <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 0000DDE4 <res 00000004>      <1> DelFile_FCluster:	resd 1
   223 0000DDE8 <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   224 0000DDEA <res 00000001>      <1> DelFile_LNEL:		resb 1
   225 0000DDEB <res 00000001>      <1> resb 1
   226                              <1> 
   227                              <1> ; DIR.ASM
   228 0000DDEC <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   229 0000DDF0 <res 00000004>      <1> mkdir_FFCluster:	resd 1
   230 0000DDF4 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   231 0000DDF8 <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   232 0000DDFC <res 00000002>      <1> mkdir_attrib:		resw 1 
   233 0000DDFE <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   234 0000DDFF <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   235 0000DE00 <res 0000000D>      <1> mkdir_Name:		resb 13
   236 0000DE0D <res 00000002>      <1> resw 1 ; 01/03/2016
   237                              <1> ; 27/02/2016
   238 0000DE0F <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   239 0000DE10 <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   240 0000DE14 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   241 0000DE18 <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   242 0000DE1C <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   243                              <1> ; 22/02/2016
   244 0000DE20 <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   245 0000DE21 <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   246                              <1> 	
   247 0000DE25 <res 00000003>      <1> alignb 4
   248                              <1> ; DRV_FAT.ASM ; 21/08/2011
   249 0000DE28 <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   250 0000DE2C <res 00000004>      <1> gffc_first_free_cluster: resd 1
   251 0000DE30 <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 0000DE34 <res 00000004>      <1> ClusterValue:	resd 1
   257                              <1> ; 04/03/2016
   258 0000DE38 <res 00000001>      <1> Attributes:	resb 1 
   259                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   260 0000DE39 <res 00000001>      <1> resb 1
   261 0000DE3A <res 00000001>      <1> CFS_OPType: resb 1
   262 0000DE3B <res 00000001>      <1> CFS_Drv:    resb 1
   263 0000DE3C <res 00000004>      <1> CFS_CC:	    resd 1
   264 0000DE40 <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   265 0000DE44 <res 00000004>      <1> CFS_FAT32FC: resd 1
   266                              <1> 
   267                              <1> ; 27/02/2016
   268                              <1> ;alignb 4
   269 0000DE48 <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   270                              <1> 
   271                              <1> ; DIR.ASM
   272 0000DE4C <res 00000002>      <1> DLN_EntryNumber: resw 1
   273 0000DE4E <res 00000001>      <1> DLN_40h:	 resb 1
   274                              <1> ; 28/02/2016
   275 0000DE4F <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   276                              <1> 
   277                              <1> alignb 4
   278                              <1> ; DIR.ASM (09/10/2011)
   279 0000DE50 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   280 0000DE52 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   281 0000DE54 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   282 0000DE58 <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 0000DE5C <res 00000004>      <1> SourceFilePath:	     resd 1
   288 0000DE60 <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 0000DE64 <res 00000001>      <1> SourceFile_Drv:			resb 1
   295 0000DE65 <res 00000041>      <1> SourceFile_Directory:		resb 65
   296 0000DEA6 <res 0000000D>      <1> SourceFile_Name:		resb 13
   297                              <1> SourceFile_LongNameEntryLength: 
   298 0000DEB3 <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 0000DEB4 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   302 0000DEB6 <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   303 0000DED6 <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   304 0000DEDA <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   305 0000DEDE <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   306 0000DEE0 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   307                              <1> ; 16/03/2016
   308 0000DEE2 <res 00000001>      <1> SourceFile_SecPerClust:		resb 1
   309 0000DEE3 <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 0000DEE4 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   314 0000DEE5 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   315 0000DF26 <res 0000000D>      <1> DestinationFile_Name:		resb 13
   316                              <1> DestinationFile_LongNameEntryLength:
   317 0000DF33 <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 0000DF34 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   321 0000DF36 <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   322 0000DF56 <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   323 0000DF5A <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   324 0000DF5E <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   325 0000DF60 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   326                              <1> ; 16/03/2016
   327 0000DF62 <res 00000001>      <1> DestinationFile_SecPerClust:	resb 1
   328 0000DF63 <res 00000001>      <1> DestinationFile_Reserved:	resb 1
   329                              <1> ; Above is 128 bytes
   330                              <1> 
   331                              <1> ; 24/04/2016
   332 0000DF64 <res 00000002>      <1> resw 1
   333                              <1> 
   334                              <1> ; 10/03/2016
   335                              <1> ; FILE.ASM
   336 0000DF66 <res 00000001>      <1> move_cmd_phase:	   resb 1
   337 0000DF67 <res 00000001>      <1> msftdf_sf_df_drv:  resb 1
   338 0000DF68 <res 00000004>      <1> msftdf_drv_offset: resd 1
   339                              <1> 
   340                              <1> ; 11/03/2016
   341                              <1> ; DRV_FAT.ASM (21/08/2011)
   342 0000DF6C <res 00000004>      <1> FAT_anc_LCluster:  resd 1
   343 0000DF70 <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 0000DF74 <res 00000004>      <1> mem_ipg_count:	resd 1 ; page count (for contiguous allocation)
   351 0000DF78 <res 00000004>      <1> mem_pg_count:	resd 1 ; page count (for count down)
   352 0000DF7C <res 00000004>      <1> mem_aperture:	resd 1 ; contiguous free pages (current)
   353 0000DF80 <res 00000004>      <1> mem_max_aperture: resd 1 ; maximum value of contiguous free pages
   354 0000DF84 <res 00000004>      <1> mem_pg_pos:	resd 1 ; mem. position (page #) of current aperture
   355 0000DF88 <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 0000DF8C <res 00000001>      <1> copy_cmd_phase:       resb 1
   360 0000DF8D <res 00000001>      <1> csftdf_rw_err:	      resb 1
   361 0000DF8E <res 00000001>      <1> DestinationFileFound: resb 1
   362 0000DF8F <res 00000001>      <1> csftdf_cdrv: 	      resb 1
   363 0000DF90 <res 00000004>      <1> csftdf_filesize:      resd 1
   364                              <1> ; TRDOS386 (TRDOS v2.0)
   365 0000DF94 <res 00000004>      <1> csftdf_sf_mem_addr:   resd 1
   366 0000DF98 <res 00000004>      <1> csftdf_sf_mem_bsize:  resd 1
   367                              <1> ;
   368                              <1> 
   369 0000DF9C <res 00000004>      <1> csftdf_sf_cluster:    resd 1 ; 16/03/2016
   370 0000DFA0 <res 00000004>      <1> csftdf_df_cluster:    resd 1
   371                              <1> ; 16/03/2016
   372 0000DFA4 <res 00000004>      <1> csftdf_r_size:        resd 1
   373 0000DFA8 <res 00000004>      <1> csftdf_w_size:        resd 1
   374 0000DFAC <res 00000004>      <1> csftdf_sf_rbytes:     resd 1
   375 0000DFB0 <res 00000004>      <1> csftdf_df_wbytes:     resd 1
   376 0000DFB4 <res 00000001>      <1> csftdf_percentage:    resb 1
   377                              <1> ; 17/03/2016
   378 0000DFB5 <res 00000001>      <1> csftdf_videopage:     resb 1
   379 0000DFB6 <res 00000002>      <1> csftdf_cursorpos:     resw 1
   380 0000DFB8 <res 00000004>      <1> csftdf_sf_drv_dt:     resd 1
   381 0000DFBC <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 0000DFC0 <res 00000004>      <1> createfile_Name_Offset:  resd 1
   387 0000DFC4 <res 00000004>      <1> createfile_FreeSectors:  resd 1 
   388 0000DFC8 <res 00000004>      <1> createfile_size:         resd 1
   389 0000DFCC <res 00000004>      <1> createfile_FFCluster:    resd 1 ; 11/03/2016
   390 0000DFD0 <res 00000004>      <1> createfile_LastDirCluster: resd 1
   391 0000DFD4 <res 00000004>      <1> createfile_Cluster:      resd 1
   392 0000DFD8 <res 00000004>      <1> createfile_PCluster:     resd 1
   393 0000DFDC <res 00000001>      <1> createfile_attrib:	 resb 1
   394 0000DFDD <res 00000001>      <1> createfile_SecPerClust:  resb 1
   395 0000DFDE <res 00000002>      <1> createfile_DirIndex:     resw 1
   396 0000DFE0 <res 00000004>      <1> createfile_CCount:	 resd 1
   397 0000DFE4 <res 00000002>      <1> createfile_BytesPerSec:	 resw 1 ; 23/03/2016
   398 0000DFE6 <res 00000001>      <1> createfile_wfc:	         resb 1
   399 0000DFE7 <res 00000001>      <1> createfile_UpdatePDir:	 resb 1 ; 31/03/2016
   400                              <1> 
   401                              <1> ;alignb 4
   402                              <1> 
   403                              <1> ; 11/04/2016
   404 0000DFE8 <res 00000002>      <1> env_var_length:	   resw 1
   405                              <1> 
   406 0000DFEA <res 00000002>      <1> alignb 4
   407                              <1> 
   408                              <1> ; 25/04/2016
   409 0000DFEC <res 00000001>      <1> readi.valid:	resb 1 ; valid data (>0 = valid for readi)
   410 0000DFED <res 00000001>      <1> readi.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   411 0000DFEE <res 00000001>      <1> readi.spc:	resb 1 ; sectors per cluster for 'readi' drive
   412 0000DFEF <res 00000001>      <1> readi.s_index:  resb 1 ; sector index in current cluster (buffer)
   413 0000DFF0 <res 00000004>      <1> readi.sector:	resd 1 ; current disk sector
   414 0000DFF4 <res 00000002>      <1> readi.bpc:	resw 1 ; bytes per cluster - 1
   415 0000DFF6 <res 00000002>      <1> readi.offset:	resw 1 ; byte offset in cluster buffer
   416 0000DFF8 <res 00000004>      <1> readi.cluster:  resd 1 ; current cluster number
   417 0000DFFC <res 00000004>      <1> readi.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   418 0000E000 <res 00000004>      <1> readi.fclust:	resd 1 ; first cluster of the current cluster
   419 0000E004 <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 0000E008 <res 00000001>      <1> writei.valid:	resb 1 ; valid data (>0 = valid for writei)
   423 0000E009 <res 00000001>      <1> writei.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   424 0000E00A <res 00000001>      <1> writei.spc:	resb 1 ; sectors per cluster for 'writei' drive
   425 0000E00B <res 00000001>      <1> writei.s_index: resb 1 ; sector index in current cluster (buffer)
   426 0000E00C <res 00000004>      <1> writei.sector:	resd 1 ; current disk sector
   427 0000E010 <res 00000002>      <1> writei.bpc:	resw 1 ; bytes per cluster - 1
   428 0000E012 <res 00000002>      <1> writei.offset:	resw 1 ; byte offset in cluster buffer
   429 0000E014 <res 00000004>      <1> writei.cluster: resd 1 ; current cluster number
   430 0000E018 <res 00000004>      <1> writei.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   431 0000E01C <res 00000004>      <1> writei.fclust:  resd 1 ; first cluster of the current cluster
   432 0000E020 <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 0000E024 <res 00000004>      <1> Run_CDirFC:	resd 1
   437 0000E028 <res 00000001>      <1> Run_Auto_Path:	resb 1
   438 0000E029 <res 00000001>      <1> Run_Manual_Path: resb 1 ; 0 -> auto path sequence needed
   439 0000E02A <res 00000001>      <1> EXE_ID:		resb 1	
   440 0000E02B <res 00000001>      <1> EXE_dot:	resb 1
   441                              <1> 
   442                              <1> ; 06/05/2016
   443 0000E02C <res 00000004>      <1> mainprog_return_addr: resd 1
   444 0000E030 <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 0000E034 <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 0000E038 <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 0000E039 <res 00000001>      <1> p_change:	resb 1  ; process change status (for timer events)
   455                              <1> ; 23/05/2016 - TRDOS 386 ('clock')
   456 0000E03A <res 00000001>      <1> multi_tasking:	resb 1   ; Multi Tasking status (0 = disabled, >0 = enabled)
   457                              <1> ; 29/05/2016
   458 0000E03B <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> ; 01/06/2016
   462 0000E03C <res 00000004>      <1> user_buffer:	resd 1  ; 'diskio.s' (INT 33h, Function 08h, floppy disk type)
   463                              <1> 			; (EBX will return with user buffer addr or disk type)
   464                              <1> ; 07/06/2016
   465 0000E040 <res 00000001>      <1> timer_events:	resb 1  ; number of (active) timer events, <= 16		
   466                              <1> 			
  2546                                  ; 24/01/2016
  2547                                  %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 0000E041 <res 00000001>      <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 0000E042 <res 00000002>      <1> 	i.flgs:	 resw 1
    37 0000E044 <res 00000001>      <1> 	i.nlks:	 resb 1
    38 0000E045 <res 00000001>      <1> 	i.uid:	 resb 1
    39                              <1>         ;i.size:  resw 1 ; size
    40 0000E046 <res 00000002>      <1> 	resw 1 ; 29/04/2016
    41 0000E048 <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    42 0000E058 <res 00000004>      <1> 	i.ctim:	 resd 1
    43 0000E05C <res 00000004>      <1> 	i.mtim:	 resd 1
    44 0000E060 <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 0000E062 <res 00000020>      <1>         p.pid:   resw nproc
    57 0000E082 <res 00000020>      <1>         p.ppid:  resw nproc
    58 0000E0A2 <res 00000020>      <1>         p.break: resw nproc
    59 0000E0C2 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    60 0000E0D2 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    61 0000E0E2 <res 00000010>      <1> 	p.link:	 resb nproc
    62 0000E0F2 <res 00000010>      <1> 	p.stat:	 resb nproc
    63                              <1> 
    64                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
    65 0000E102 <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 0000E142 <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 0000E152 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
   104 0000E346 <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
   105 0000E35E <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   106 0000E360 <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 0000E362 <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 0000E363 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   122                              <1> ; 15/04/2015
   123 0000E364 <res 00000001>      <1> active:	 resb 1 
   124 0000E365 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   125 0000E366 <res 00000002>      <1> mnti:	 resw 1
   126 0000E368 <res 00000002>      <1> mpid:	 resw 1
   127 0000E36A <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 0000E36C <res 00000002>      <1> runq_event:	 resw 1 ; high priority, 'run for event'            ; 2
   132 0000E36E <res 00000002>      <1> runq_normal:	 resw 1 ; normal/regular priority, 'run as reqular' ; 1
   133 0000E370 <res 00000002>      <1> runq_background: resw 1 ; low priority, 'run on background'         ; 0
   134                              <1> ;
   135 0000E372 <res 00000001>      <1> imod:	 resb 1
   136 0000E373 <res 00000001>      <1> smod:	 resb 1
   137 0000E374 <res 00000001>      <1> mmod:	 resb 1
   138 0000E375 <res 00000001>      <1> sysflg:	 resb 1
   139                              <1> 
   140 0000E376 <res 00000002>      <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 0000E378 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   160 0000E37C <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   161 0000E380 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   162 0000E384 <res 00000002>      <1> 	u.cdir:	  resw 1
   163 0000E386 <res 0000000A>      <1> 	u.fp:	  resb 10
   164 0000E390 <res 00000004>      <1> 	u.fofp:	  resd 1
   165 0000E394 <res 00000004>      <1> 	u.dirp:	  resd 1
   166 0000E398 <res 00000004>      <1> 	u.namep:  resd 1
   167 0000E39C <res 00000004>      <1> 	u.off:	  resd 1
   168 0000E3A0 <res 00000004>      <1> 	u.base:	  resd 1
   169 0000E3A4 <res 00000004>      <1> 	u.count:  resd 1
   170 0000E3A8 <res 00000004>      <1> 	u.nread:  resd 1
   171 0000E3AC <res 00000004>      <1> 	u.break:  resd 1 ; break
   172 0000E3B0 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   173 0000E3B2 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   174                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   175 0000E3C2 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   176 0000E3C3 <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
   177 0000E3C4 <res 00000002>      <1> 	u.intr:	  resw 1
   178 0000E3C6 <res 00000002>      <1> 	u.quit:	  resw 1
   179                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   180 0000E3C8 <res 00000002>      <1> 	u.ilgins: resw 1
   181 0000E3CA <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   182 0000E3CC <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   183 0000E3CD <res 00000001>      <1> 	u.ruid:	  resb 1
   184 0000E3CE <res 00000001>      <1> 	u.bsys:	  resb 1
   185 0000E3CF <res 00000001>      <1> 	u.uno:	  resb 1
   186 0000E3D0 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   187                              <1> 	; tty number (rtty, rcvt, wtty)
   188 0000E3D4 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   189                              <1> 	; last error number
   190 0000E3D5 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   191                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   192 0000E3D9 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   193 0000E3DD <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   194 0000E3E1 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   195 0000E3E5 <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 0000E3E7 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   202 0000E3E8 <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 0000E3E9 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   212                              <1> 
   213 0000E3ED <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 0000E3F0 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
   219 0000E3F4 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
   220 0000E3F8 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   221 0000E3FC <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   222 0000E3FE <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   223 0000E400 <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 0000E404 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   228                              <1> 
   229                              <1> ;alignb 4
   230                              <1> 
   231                              <1> ; 24/04/2016
   232 0000E405 <res 00000004>      <1> ii:		resd 1 ; first cluster of the program file
   233 0000E409 <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 0000E40D <res 00000008>      <1> 	resb	8 
   239                              <1> readi_buffer:
   240 0000E415 <res 00000200>      <1> 	resb 	512
   241 0000E615 <res 00000008>      <1> 	resb	8
   242                              <1> writei_buffer:
   243 0000E61D <res 00000200>      <1> 	resb	512	
   244 0000E81D <res 00000410>      <1> 	resb (nbuf-2) * 520
   245                              <1> 
   246 0000EC2D <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 0000EC35 <res 00000002>      <1> 	resw 1
   256 0000EC37 <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
   257 0000ED9F <res 00000002>      <1> 	resw 1
   258 0000EDA1 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
   259 0000EDC1 <res 00000004>      <1> 	s.time:	 resd 1
   260 0000EDC5 <res 00000004>      <1> 	s.syst:	 resd 1
   261 0000EDC9 <res 00000004>      <1>         s.wait_: resd 1 ; wait
   262 0000EDCD <res 00000004>      <1> 	s.idlet: resd 1
   263 0000EDD1 <res 00000004>      <1> 	s.chrgt: resd 1
   264 0000EDD5 <res 00000002>      <1> 	s.drerr: resw 1
   265                              <1> 
   266                              <1> S_SIZE	equ $ - systm
   267                              <1> 
   268 0000EDD7 <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
   269                              <1> 
   270 0000EE35 <res 00000008>      <1> sb1:	resd 2
   271                              <1> ; (mounted disk) super block buffer
   272                              <1> mount:	
   273 0000EE3D <res 00000200>      <1> 	resb 512  ; 03/06/2015
  2548                                  
  2549 0000F03D <res 00000003>          alignb 4
  2550                                  
  2551                                  ; 23/05/2016 (TRDOS 386)
  2552                                  ; 14/10/2015 (Retro UNIX 386 v1, 'unix386.s')
  2553 0000F040 <res 00000004>          cr3reg:	 resd 1  ; cr3 register content at the beginning of the timer
  2554                                  		 ; (or RTC) interrupt handler.
  2555                                  ; 10/06/2016
  2556                                  ; 19/05/2016
  2557                                  ; 18/05/2016 - TRDOS 386 feature only !
  2558 0000F044 <res 00000100>          timer_set: resd 16*4   ; 256 bytes memory space for 16 timer events
  2559                                  	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  2560                                  	;       Owner:	        resb 1 ; 0 = free
  2561                                  	;		  	       ;>0 = process number (p.pid)
  2562                                  	;	Reserved:	resb 1 ; = 0		
  2563                                  	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  2564                                  	;		   	       ; 1 = Real Time Clock interrupt 
  2565                                  	;	Response:       resb 1 ; 0 to 255, signal return value
  2566                                  	;	Count Limit:	resd 1 ; count of ticks (total/set)
  2567                                  	;	Current Count: 	resd 1 ; count of ticks (current)
  2568                                  	;	Response Addr:  resd 1 ; response byte (pointer) address
  2569                                  
  2570                                  ;; Memory (swap) Data (11/03/2015)
  2571                                  ; 09/03/2015
  2572 0000F144 <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  2573 0000F146 <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2574 0000F14A <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2575 0000F14E <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2576 0000F152 <res 00000004>          swpd_next:  resd 1 ; next free page block
  2577 0000F156 <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  2578                                  
  2579 0000F15A <res 00000002>          alignb 4
  2580                                  
  2581                                  ; 10/07/2015
  2582                                  ; 28/08/2014
  2583 0000F15C <res 00000004>          error_code:	resd 1
  2584                                  ; 29/08/2014
  2585 0000F160 <res 00000004>          FaultOffset: 	resd 1
  2586                                  ; 21/09/2015
  2587 0000F164 <res 00000004>          PF_Count:	resd 1	; total page fault count
  2588                                  		       	; (for debugging - page fault analyze)
  2589                                  		 	; 'page_fault_handler' (memory.inc)
  2590                                  			; 'sysgeterr' (u9.s)
  2591                                  ;; 21/08/2015
  2592                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
  2593                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
  2594                                  
  2595                                  bss_end:
  2596                                  
  2597                                  ; 27/12/2013
  2598                                  _end:  ; end of kernel code
